|
@@ -253,6 +253,11 @@ var defaultNetworkGraphOptions = {
|
|
|
hoverConnectedEdges: false,
|
|
hoverConnectedEdges: false,
|
|
|
selectConnectedEdges: true,
|
|
selectConnectedEdges: true,
|
|
|
},
|
|
},
|
|
|
|
|
+ physics: {
|
|
|
|
|
+ barnesHut: {
|
|
|
|
|
+ avoidOverlap: 0.2
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
};
|
|
};
|
|
|
var TMP_COUNTER = 1;
|
|
var TMP_COUNTER = 1;
|
|
|
|
|
|
|
@@ -284,14 +289,36 @@ var p5UI__NetworkGraph = createReactClass({
|
|
|
componentDidMount: function () {
|
|
componentDidMount: function () {
|
|
|
var data = { nodes: this._nodes, edges: this._edges };
|
|
var data = { nodes: this._nodes, edges: this._edges };
|
|
|
this._network = new vis.Network(this._visOutputRef, data, defaultNetworkGraphOptions);
|
|
this._network = new vis.Network(this._visOutputRef, data, defaultNetworkGraphOptions);
|
|
|
- // bindNetwork();
|
|
|
|
|
- this.setState({ initialized: true });
|
|
|
|
|
|
|
+ if (this.props.onZoom) this._network.on('zoom', this.props.onZoom)
|
|
|
|
|
+ this.setState({ initialized: true });
|
|
|
this._unsubscribe = this.props.store.subscribe(this._storeUpdated)
|
|
this._unsubscribe = this.props.store.subscribe(this._storeUpdated)
|
|
|
},
|
|
},
|
|
|
_storeUpdated: function () {
|
|
_storeUpdated: function () {
|
|
|
this.setState( this.getStateFromStore() )
|
|
this.setState( this.getStateFromStore() )
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
|
|
+ fitToContainer: function () {
|
|
|
|
|
+ if (this._network) {
|
|
|
|
|
+ this._network.fit()
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ incScale: function () {
|
|
|
|
|
+ if (this._network) {
|
|
|
|
|
+ var scale = this._network.getScale();
|
|
|
|
|
+ this._network.moveTo({
|
|
|
|
|
+ scale: scale + 0.2
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ decScale: function () {
|
|
|
|
|
+ if (this._network) {
|
|
|
|
|
+ var scale = this._network.getScale();
|
|
|
|
|
+ this._network.moveTo({
|
|
|
|
|
+ scale: (scale > 0.3) ? scale - 0.2 : scale
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
testOnClick1: function () {
|
|
testOnClick1: function () {
|
|
|
TMP_COUNTER++;
|
|
TMP_COUNTER++;
|
|
|
this._nodes.add({ id: TMP_COUNTER, label: "Node " + TMP_COUNTER, value: TMP_COUNTER, level: 0 });
|
|
this._nodes.add({ id: TMP_COUNTER, label: "Node " + TMP_COUNTER, value: TMP_COUNTER, level: 0 });
|
|
@@ -414,14 +441,21 @@ var p5UI__NetworkGraph = createReactClass({
|
|
|
},
|
|
},
|
|
|
render: function () {
|
|
render: function () {
|
|
|
DBG1 && console.log('DBG:render');
|
|
DBG1 && console.log('DBG:render');
|
|
|
- return h('div', {}, [
|
|
|
|
|
|
|
+ return h('div', { style: { 'position': "relative" } }, [
|
|
|
h('div', {
|
|
h('div', {
|
|
|
ref: this.setOutputRef,
|
|
ref: this.setOutputRef,
|
|
|
style: {
|
|
style: {
|
|
|
'min-height': 600,
|
|
'min-height': 600,
|
|
|
'height': 600,
|
|
'height': 600,
|
|
|
|
|
+ 'border-radius': "6px",
|
|
|
|
|
+ 'border': "1px solid #ddd",
|
|
|
},
|
|
},
|
|
|
}),
|
|
}),
|
|
|
|
|
+ h('div', { className: "btn-group-vertical", style: { position: "absolute", right: 10, top: 10 } }, [
|
|
|
|
|
+ h('button', { onClick: this.incScale, className: "btn btn-xs btn-default" }, [ h('i', { className: "glyphicon glyphicon-plus" }) ]),
|
|
|
|
|
+ h('button', { onClick: this.fitToContainer, className: "btn btn-xs btn-default" }, [ "100%" ]),
|
|
|
|
|
+ h('button', { onClick: this.decScale, className: "btn btn-xs btn-default" }, [ h('i', { className: "glyphicon glyphicon-minus" }) ]),
|
|
|
|
|
+ ]),
|
|
|
h('div', {}, [
|
|
h('div', {}, [
|
|
|
h('button', { onClick: this.testOnClick1 }, [ "TEST 1 ", h('small', [], "(+ node)") ]),
|
|
h('button', { onClick: this.testOnClick1 }, [ "TEST 1 ", h('small', [], "(+ node)") ]),
|
|
|
h('button', { onClick: this.testOnClick2 }, [ "TEST 2 ", h('small', [], "(+ edge)") ]),
|
|
h('button', { onClick: this.testOnClick2 }, [ "TEST 2 ", h('small', [], "(+ edge)") ]),
|
|
@@ -452,10 +486,23 @@ var p5UI__RaportOutputPanel = createReactClass({
|
|
|
DBG1 && console.log('DBG:typeahead selected:', { selected })
|
|
DBG1 && console.log('DBG:typeahead selected:', { selected })
|
|
|
this.setState({ selected: selected });
|
|
this.setState({ selected: selected });
|
|
|
},
|
|
},
|
|
|
|
|
+ _onZoom: function (event) {
|
|
|
|
|
+ // {
|
|
|
|
|
+ // direction: '+'/'-',
|
|
|
|
|
+ // scale: Number,
|
|
|
|
|
+ // pointer: {x:pointer_x, y:pointer_y}
|
|
|
|
|
+ // }
|
|
|
|
|
+ DBG1 && console.log('DBG:onZoom', { scale: event.scale, event })
|
|
|
|
|
+ var this__handleZoomUpdate = this.handleZoomUpdate;
|
|
|
|
|
+ },
|
|
|
|
|
+ handleZoomUpdate: function () {
|
|
|
|
|
+ DBG1 && console.warn('DBG:handleZoomUpdate', { event })
|
|
|
|
|
+ },
|
|
|
render: function () {
|
|
render: function () {
|
|
|
var state = this.props.store.getState()
|
|
var state = this.props.store.getState()
|
|
|
DBG1 && console.log('DBG: state', state);
|
|
DBG1 && console.log('DBG: state', state);
|
|
|
var nodes = state.nodes || [];
|
|
var nodes = state.nodes || [];
|
|
|
|
|
+
|
|
|
return h(React.Fragment, {}, [
|
|
return h(React.Fragment, {}, [
|
|
|
h(Typeahead, {
|
|
h(Typeahead, {
|
|
|
labelKey: "label",
|
|
labelKey: "label",
|
|
@@ -471,6 +518,7 @@ var p5UI__RaportOutputPanel = createReactClass({
|
|
|
store: this.props.store,
|
|
store: this.props.store,
|
|
|
storeActions: this.props.storeActions,
|
|
storeActions: this.props.storeActions,
|
|
|
selected: this.state.selected,
|
|
selected: this.state.selected,
|
|
|
|
|
+ onZoom: window._.throttle(this._onZoom, 500),
|
|
|
})
|
|
})
|
|
|
])
|
|
])
|
|
|
}
|
|
}
|