Skip to content

Commit

Permalink
update extension to match model from widget-cookiecutter
Browse files Browse the repository at this point in the history
  • Loading branch information
zakandrewking committed Jun 5, 2019
1 parent e228205 commit 23c7092
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 129 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,13 @@ For the Jupyter notebooks, run:

```
cd py
jupyter nbextension install --py --symlink --sys-prefix escher
jupyter nbextension enable --py --sys-prefix escher
jupyter nbextension install --py --symlink escher
jupyter nbextension enable --py escher
```

If you are using virtualenv or conda, you can add the `--sys-prefix` flag to
those commands to keep your environment isolated and reproducible.

When you make changes, you will need to `yarn copy` and refresh notebook browser
tab.

Expand Down
6 changes: 3 additions & 3 deletions docs/notebooks/Escher Python Tutorial.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 4,
"metadata": {
"scrolled": true
"scrolled": false
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "ef4ada30b3a0425e8b835047a01d6be5",
"model_id": "f5058c0931f74956a11facfe218ee803",
"version_major": 2,
"version_minor": 0
},
Expand Down
4 changes: 2 additions & 2 deletions jupyter/lab-extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ const escher = require('../dist/escher.min')
const base = require('@jupyter-widgets/base')

module.exports = {
id: 'jupyter.extensions.escher',
id: 'escher',
requires: [base.IJupyterWidgetRegistry],
activate: (app, widgets) => widgets.registerWidget({
name: 'escher',
version: escher.version,
exports: escher.initializeJupyterWidget()
exports: escher
}),
autoStart: true
}
10 changes: 0 additions & 10 deletions jupyter/notebook-extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,11 @@
// dynamically.
window.__webpack_public_path__ = document.querySelector('body').getAttribute('data-base-url') + 'nbextensions/escher'

// Pull jupyter object out when importing escher
window.define(
'escher-intercept',
['escher'],
escher => escher.initializeJupyterWidget()
)

// Configure requirejs
if (window.require) {
window.require.config({
map: {
'*': {
'escher': 'escher-intercept'
},
'escher-intercept': {
escher: 'nbextensions/escher/escher.min'
}
}
Expand Down
4 changes: 2 additions & 2 deletions py/escher/static/escher.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion py/escher/static/escher.min.js.map

Large diffs are not rendered by default.

10 changes: 0 additions & 10 deletions py/escher/static/extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,11 @@
// dynamically.
window.__webpack_public_path__ = document.querySelector('body').getAttribute('data-base-url') + 'nbextensions/escher'

// Pull jupyter object out when importing escher
window.define(
'escher-intercept',
['escher'],
escher => escher.initializeJupyterWidget()
)

// Configure requirejs
if (window.require) {
window.require.config({
map: {
'*': {
'escher': 'escher-intercept'
},
'escher-intercept': {
escher: 'nbextensions/escher/escher.min'
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export { default as dataStyles } from './dataStyles'
export { default as ZoomContainer } from './ZoomContainer'

// Jupyter extension
export { default as initializeJupyterWidget } from './widget'
export { EscherMapView, EscherMapModel } from './widget'

export const libs = {
_: underscore,
Expand Down
193 changes: 95 additions & 98 deletions src/widget.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { default as Builder } from './Builder'
import { select as d3Select } from 'd3-selection'
import _ from 'underscore'

// @jupyter-widgets/base is optional, so only initialize if it's called
let base
try {
Expand All @@ -29,116 +30,112 @@ const NO_DRAW_OPTIONS = [
/**
* Jupyter widget implementation for the Escher Builder.
*/
export default function initializeJupyterWidget () {
if (!base) {
throw Error('@jupyter-widgets/base not installed. You must install it to ' +
'use the jupyter widget')
}

class EscherMapView extends base.DOMWidgetView {
render () {
const sel = d3Select(this.el).append('div')

// set height before loading map
this.setHeight(sel)

_.defer(() => {
this.builder = new Builder(
this.getMapData(),
this.getModelData(),
this.model.get('embedded_css'),
sel,
{
first_load_callback: builder => {
// reset map json in widget
builder.callback_manager.set('clear_map', () => {
this.model.set('_loaded_map_json', null)
this.model.save_changes()
})

// reset model json in widget
builder.callback_manager.set('clear_model', () => {
this.model.set('_loaded_model_json', null)
this.model.save_changes()
})

// update functions
this.model.on('change:height', () => {
this.setHeight(sel)
})
this.model.on('change:_loaded_map_json', () => {
builder.load_map(this.getMapData())
})
this.model.on('change:_loaded_model_json', () => {
builder.load_model(this.getModelData())
})
export class EscherMapView extends base.DOMWidgetView {
render () {
if (!base) {
throw Error('@jupyter-widgets/base not installed. You must install it to ' +
'use the jupyter widget')
}

// set the rest of the options
Object.keys(builder.settings.streams).map(key => {
if (this.model.keys().includes(key)) {
const sel = d3Select(this.el).append('div')

// set height before loading map
this.setHeight(sel)

_.defer(() => {
this.builder = new Builder(
this.getMapData(),
this.getModelData(),
this.model.get('embedded_css'),
sel,
{
first_load_callback: builder => {
// reset map json in widget
builder.callback_manager.set('clear_map', () => {
this.model.set('_loaded_map_json', null)
this.model.save_changes()
})

// reset model json in widget
builder.callback_manager.set('clear_model', () => {
this.model.set('_loaded_model_json', null)
this.model.save_changes()
})

// update functions
this.model.on('change:height', () => {
this.setHeight(sel)
})
this.model.on('change:_loaded_map_json', () => {
builder.load_map(this.getMapData())
})
this.model.on('change:_loaded_model_json', () => {
builder.load_model(this.getModelData())
})

// set the rest of the options
Object.keys(builder.settings.streams).map(key => {
if (this.model.keys().includes(key)) {
const val = this.model.get(key)
// ignore null because that means to use the default
if (val !== null) builder.settings.set(key, val)

// reactive updates
this.model.on(`change:${key}`, () => {
const val = this.model.get(key)
// ignore null because that means to use the default
if (val !== null) builder.settings.set(key, val)

// reactive updates
this.model.on(`change:${key}`, () => {
const val = this.model.get(key)
// ignore null because that means to use the default
if (val !== null) {
builder.settings.set(key, val)
// default to drawing everything, unless it's a common
// option where that's not necessary
if (!NO_DRAW_OPTIONS.includes(key)) {
builder.map.draw_everything()
}
if (val !== null) {
builder.settings.set(key, val)
// default to drawing everything, unless it's a common
// option where that's not necessary
if (!NO_DRAW_OPTIONS.includes(key)) {
builder.map.draw_everything()
}
})
}
})

// get changes from options (only after they have been accepted)
_.mapObject(builder.settings.acceptedStreams, (stream, key) => {
stream.onValue(val => {
// avoid a loop
if (val !== this.model.get(key)) {
this.model.set(key, val)
this.model.save_changes()
}
})
}
})

// get changes from options (only after they have been accepted)
_.mapObject(builder.settings.acceptedStreams, (stream, key) => {
stream.onValue(val => {
// avoid a loop
if (val !== this.model.get(key)) {
this.model.set(key, val)
this.model.save_changes()
}
})
}
})
}
)
})
}

setHeight (sel) {
sel.style('height', `${this.model.get('height')}px`)
}
}
)
})
}

getMapData () {
const json = this.model.get('_loaded_map_json')
return json ? JSON.parse(json) : null
}
setHeight (sel) {
sel.style('height', `${this.model.get('height')}px`)
}

getModelData () {
const json = this.model.get('_loaded_model_json')
return json ? JSON.parse(json) : null
}
getMapData () {
const json = this.model.get('_loaded_map_json')
return json ? JSON.parse(json) : null
}

class EscherMapModel extends base.DOMWidgetModel {
defaults () {
return _.extend(super.defaults(), {
_model_name: 'EscherMapModel',
_view_name: 'EscherMapView',
_model_module: 'escher',
_view_module: 'escher',
_model_module_version: version,
_view_module_version: version
})
}
getModelData () {
const json = this.model.get('_loaded_model_json')
return json ? JSON.parse(json) : null
}
}

return { EscherMapView, EscherMapModel }
export class EscherMapModel extends base.DOMWidgetModel {
defaults () {
return _.extend(super.defaults(), {
_model_name: 'EscherMapModel',
_view_name: 'EscherMapView',
_model_module: 'escher',
_view_module: 'escher',
_model_module_version: version,
_view_module_version: version
})
}
}

0 comments on commit 23c7092

Please sign in to comment.