Browse Source

interaction tweaks

flowchartTest
Alex de Mulder 9 years ago
parent
commit
084c19400e
9 changed files with 2861 additions and 2861 deletions
  1. +2737
    -2735
      dist/vis.js
  2. +1
    -1
      examples/network/01_basic_usage.html
  3. +8
    -0
      lib/network/Edge.js
  4. +4
    -11
      lib/network/Network.js
  5. +13
    -15
      lib/network/modules/Canvas.js
  6. +19
    -15
      lib/network/modules/CanvasRenderer.js
  7. +72
    -71
      lib/network/modules/InteractionHandler.js
  8. +2
    -8
      lib/network/modules/SelectionHandler.js
  9. +5
    -5
      lib/network/modules/View.js

+ 2737
- 2735
dist/vis.js
File diff suppressed because it is too large
View File


+ 1
- 1
examples/network/01_basic_usage.html View File

@ -43,7 +43,7 @@
nodes: nodes, nodes: nodes,
edges: edges edges: edges
}; };
var options = {};
var options = {}//{physics:{stabilization:false}};
var network = new vis.Network(container, data, options); var network = new vis.Network(container, data, options);
</script> </script>

+ 8
- 0
lib/network/Edge.js View File

@ -173,6 +173,14 @@ Edge.prototype.getTitle = function() {
return typeof this.title === "function" ? this.title() : this.title; return typeof this.title === "function" ? this.title() : this.title;
}; };
/**
* check if this node is selecte
* @return {boolean} selected True if node is selected, else false
*/
Edge.prototype.isSelected = function() {
return this.selected;
};
/** /**
* Retrieve the value of the edge. Can be undefined * Retrieve the value of the edge. Can be undefined

+ 4
- 11
lib/network/Network.js View File

@ -24,7 +24,7 @@ import { ClusterEngine } from './modules/Clustering'
import { CanvasRenderer } from './modules/CanvasRenderer' import { CanvasRenderer } from './modules/CanvasRenderer'
import { Canvas } from './modules/Canvas' import { Canvas } from './modules/Canvas'
import { View } from './modules/View' import { View } from './modules/View'
import { TouchEventHandler } from './modules/InteractionHandler'
import { InteractionHandler } from './modules/InteractionHandler'
import { SelectionHandler } from "./modules/SelectionHandler" import { SelectionHandler } from "./modules/SelectionHandler"
/** /**
@ -228,7 +228,7 @@ function Network (container, data, options) {
// modules // modules
this.canvas = new Canvas(this.body); this.canvas = new Canvas(this.body);
this.selectionHandler = new SelectionHandler(this.body, this.canvas); this.selectionHandler = new SelectionHandler(this.body, this.canvas);
this.touchHandler = new TouchEventHandler(this.body, this.canvas, this.selectionHandler);
this.interactionHandler = new InteractionHandler(this.body, this.canvas, this.selectionHandler);
this.view = new View(this.body, this.canvas); this.view = new View(this.body, this.canvas);
this.renderer = new CanvasRenderer(this.body, this.canvas); this.renderer = new CanvasRenderer(this.body, this.canvas);
this.clustering = new ClusterEngine(this.body); this.clustering = new ClusterEngine(this.body);
@ -268,13 +268,6 @@ function Network (container, data, options) {
// apply options // apply options
this.setOptions(options); this.setOptions(options);
// other vars
this.cachedFunctions = {};
this.startedStabilization = false;
this.stabilized = false;
this.stabilizationIterations = null;
this.draggingNodes = false;
// position and scale variables and objects // position and scale variables and objects
this.pointerPosition = {"x": 0,"y": 0}; // coordinates of the bottom right of the canvas. they will be set during _redraw this.pointerPosition = {"x": 0,"y": 0}; // coordinates of the bottom right of the canvas. they will be set during _redraw
@ -465,7 +458,7 @@ Network.prototype.setOptions = function (options) {
this.physics.setOptions(options.physics); this.physics.setOptions(options.physics);
this.canvas.setOptions(options.canvas); this.canvas.setOptions(options.canvas);
this.renderer.setOptions(options.rendering); this.renderer.setOptions(options.rendering);
this.touchHandler.setOptions(options.interaction);
this.interactionHandler.setOptions(options.interaction);
this.selectionHandler.setOptions(options.selection); this.selectionHandler.setOptions(options.selection);
@ -573,7 +566,7 @@ Network.prototype.setOptions = function (options) {
//this._configureSmoothCurves(); //this._configureSmoothCurves();
// bind hammer // bind hammer
this.canvas._bindHammer();
//this.canvas._bindHammer();
// bind keys. If disabled, this will not do anything; // bind keys. If disabled, this will not do anything;
//this._createKeyBinds(); //this._createKeyBinds();

+ 13
- 15
lib/network/modules/Canvas.js View File

@ -66,7 +66,6 @@ class Canvas {
ctx.oBackingStorePixelRatio || ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio || 1); ctx.backingStorePixelRatio || 1);
//this.pixelRatio = Math.max(1,this.pixelRatio); // this is to account for browser zooming out. The pixel ratio is ment to switch between 1 and 2 for HD screens.
this.frame.canvas.getContext("2d").setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0); this.frame.canvas.getContext("2d").setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0);
} }
@ -85,30 +84,29 @@ class Canvas {
* @private * @private
*/ */
_bindHammer() { _bindHammer() {
var me = this;
if (this.hammer !== undefined) { if (this.hammer !== undefined) {
this.hammer.destroy(); this.hammer.destroy();
} }
this.drag = {}; this.drag = {};
this.pinch = {}; this.pinch = {};
this.hammer = new Hammer(this.frame.canvas); this.hammer = new Hammer(this.frame.canvas);
this.hammer.on('tap', me.body.eventListeners.onTap );
this.hammer.on('doubletap', me.body.eventListeners.onDoubleTap );
this.hammer.on('press', me.body.eventListeners.onHold );
hammerUtil.onTouch(this.hammer, me.body.eventListeners.onTouch );
this.hammer.on('panstart', me.body.eventListeners.onDragStart );
this.hammer.on('panmove', me.body.eventListeners.onDrag );
this.hammer.on('panend', me.body.eventListeners.onDragEnd );
this.hammer.on('pinch', me.body.eventListeners.onPinch.bind(me) );
this.hammer.on('tap', this.body.eventListeners.onTap );
this.hammer.on('doubletap', this.body.eventListeners.onDoubleTap );
this.hammer.on('press', this.body.eventListeners.onHold );
hammerUtil.onTouch(this.hammer, this.body.eventListeners.onTouch );
this.hammer.on('panstart', this.body.eventListeners.onDragStart );
this.hammer.on('panmove', this.body.eventListeners.onDrag );
this.hammer.on('panend', this.body.eventListeners.onDragEnd );
this.hammer.on('pinch', function() {console.log("pinching!");});//this.body.eventListeners.onPinch );
// TODO: neatly cleanup these handlers when re-creating the Canvas, IF these are done with hammer, event.stopPropagation will not work? // TODO: neatly cleanup these handlers when re-creating the Canvas, IF these are done with hammer, event.stopPropagation will not work?
this.frame.canvas.addEventListener('mousewheel', me.body.eventListeners.onMouseWheel.bind(me));
this.frame.canvas.addEventListener('DOMMouseScroll', me.body.eventListeners.onMouseWheel.bind(me));
this.frame.canvas.addEventListener('mousewheel', this.body.eventListeners.onMouseWheel);
this.frame.canvas.addEventListener('DOMMouseScroll', this.body.eventListeners.onMouseWheel);
this.frame.canvas.addEventListener('mousemove', me.body.eventListeners.onMouseMove.bind(me));
this.frame.canvas.addEventListener('mousemove', this.body.eventListeners.onMouseMove);
this.hammerFrame = new Hammer(this.frame); this.hammerFrame = new Hammer(this.frame);
hammerUtil.onRelease(this.hammerFrame, me.body.eventListeners.onRelease.bind(me) );
hammerUtil.onRelease(this.hammerFrame, this.body.eventListeners.onRelease);
} }
@ -153,7 +151,7 @@ class Canvas {
} }
if (emitEvent === true) { if (emitEvent === true) {
this.body.emitter.emit('resize', {width:this.frame.canvas.width * this.pixelRatio,height:this.frame.canvas.height * this.pixelRatio, oldWidth: oldWidth * this.pixelRatio, oldHeight: oldHeight * this.pixelRatio});
this.body.emitter.emit('resize', {width:this.frame.canvas.width / this.pixelRatio, height:this.frame.canvas.height / this.pixelRatio, oldWidth: oldWidth / this.pixelRatio, oldHeight: oldHeight / this.pixelRatio});
} }
}; };

+ 19
- 15
lib/network/modules/CanvasRenderer.js View File

@ -18,20 +18,21 @@ class CanvasRenderer {
this.redrawRequested = false; this.redrawRequested = false;
this.renderTimer = false; this.renderTimer = false;
this.requiresTimeout = true; this.requiresTimeout = true;
this.continueRendering = false;
this.renderingActive = false;
this.renderRequests = 0; this.renderRequests = 0;
this.pixelRatio = undefined;
this.canvasTopLeft = {x: 0, y: 0}; this.canvasTopLeft = {x: 0, y: 0};
this.canvasBottomRight = {x: 0, y: 0}; this.canvasBottomRight = {x: 0, y: 0};
this.dragging = false; this.dragging = false;
this.body.emitter.on("dragStart", () => {this.dragging = true; console.log("here")});
this.body.emitter.on("dragStart", () => {this.dragging = true;});
this.body.emitter.on("dragEnd", () => this.dragging = false); this.body.emitter.on("dragEnd", () => this.dragging = false);
this.body.emitter.on("_redraw", this._redraw.bind(this));
this.body.emitter.on("_redraw", () => {if (this.renderingActive === false) {this._redraw();}});
this.body.emitter.on("_requestRedraw", this._requestRedraw.bind(this)); this.body.emitter.on("_requestRedraw", this._requestRedraw.bind(this));
this.body.emitter.on("_startRendering", () => {this.renderRequests += 1; this.continueRendering = true; this.startRendering();});
this.body.emitter.on("_stopRendering", () => {this.renderRequests -= 1; this.continueRendering = this.renderRequests > 0;});
this.body.emitter.on("_startRendering", () => {this.renderRequests += 1; this.renderingActive = true; this.startRendering();});
this.body.emitter.on("_stopRendering", () => {this.renderRequests -= 1; this.renderingActive = this.renderRequests > 0;});
this.options = {}; this.options = {};
this.defaultOptions = { this.defaultOptions = {
@ -40,7 +41,6 @@ class CanvasRenderer {
} }
util.extend(this.options,this.defaultOptions); util.extend(this.options,this.defaultOptions);
this._determineBrowserMethod(); this._determineBrowserMethod();
} }
@ -52,7 +52,7 @@ class CanvasRenderer {
startRendering() { startRendering() {
if (this.continueRendering === true) {
if (this.renderingActive === true) {
if (!this.renderTimer) { if (!this.renderTimer) {
if (this.requiresTimeout == true) { if (this.requiresTimeout == true) {
this.renderTimer = window.setTimeout(this.renderStep.bind(this), this.simulationInterval); // wait this.renderTimeStep milliseconds and perform the animation step function this.renderTimer = window.setTimeout(this.renderStep.bind(this), this.simulationInterval); // wait this.renderTimeStep milliseconds and perform the animation step function
@ -99,7 +99,7 @@ class CanvasRenderer {
* @private * @private
*/ */
_requestRedraw() { _requestRedraw() {
if (this.redrawRequested !== true) {
if (this.redrawRequested !== true && this.renderingActive === false) {
this.redrawRequested = true; this.redrawRequested = true;
if (this.requiresTimeout === true) { if (this.requiresTimeout === true) {
window.setTimeout(this._redraw.bind(this, false),0); window.setTimeout(this._redraw.bind(this, false),0);
@ -116,6 +116,14 @@ class CanvasRenderer {
this.redrawRequested = false; this.redrawRequested = false;
var ctx = this.canvas.frame.canvas.getContext('2d'); var ctx = this.canvas.frame.canvas.getContext('2d');
if (this.pixelRation === undefined) {
this.pixelRatio = (window.devicePixelRatio || 1) / (ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio || 1);
}
ctx.setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0); ctx.setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0);
// clear the canvas // clear the canvas
@ -133,8 +141,6 @@ class CanvasRenderer {
this.canvasTopLeft = this.canvas.DOMtoCanvas({x:0,y:0}); this.canvasTopLeft = this.canvas.DOMtoCanvas({x:0,y:0});
this.canvasBottomRight = this.canvas.DOMtoCanvas({x:this.canvas.frame.canvas.clientWidth,y:this.canvas.frame.canvas.clientHeight}); this.canvasBottomRight = this.canvas.DOMtoCanvas({x:this.canvas.frame.canvas.clientWidth,y:this.canvas.frame.canvas.clientHeight});
console.log(this.dragging)
if (hidden === false) { if (hidden === false) {
if (this.dragging === false || (this.dragging === true && this.options.hideEdgesOnDrag === false)) { if (this.dragging === false || (this.dragging === true && this.options.hideEdgesOnDrag === false)) {
this._drawEdges(ctx); this._drawEdges(ctx);
@ -145,14 +151,12 @@ class CanvasRenderer {
this._drawNodes(ctx, this.body.nodes, hidden); this._drawNodes(ctx, this.body.nodes, hidden);
} }
if (hidden === false) {
if (this.controlNodesActive == true) {
this._drawControlNodes(ctx);
}
if (this.controlNodesActive === true) {
this._drawControlNodes(ctx);
} }
//this._drawNodes(ctx,this.body.supportNodes,true); //this._drawNodes(ctx,this.body.supportNodes,true);
// this.physics.nodesSolver._debug(ctx,"#F00F0F");
//this.physics.nodesSolver._debug(ctx,"#F00F0F");
// restore original scaling and translation // restore original scaling and translation
ctx.restore(); ctx.restore();

+ 72
- 71
lib/network/modules/InteractionHandler.js View File

@ -153,7 +153,6 @@ class InteractionHandler {
this.drag.selection = []; this.drag.selection = [];
this.drag.translation = util.extend({},this.body.view.translation); // copy the object this.drag.translation = util.extend({},this.body.view.translation); // copy the object
this.drag.nodeId = null; this.drag.nodeId = null;
this.draggingNodes = false;
this.body.emitter.emit("dragStart", {nodeIds: this.selectionHandler.getSelection().nodes}); this.body.emitter.emit("dragStart", {nodeIds: this.selectionHandler.getSelection().nodes});
@ -161,6 +160,7 @@ class InteractionHandler {
this.drag.nodeId = node.id; this.drag.nodeId = node.id;
// select the clicked node if not yet selected // select the clicked node if not yet selected
if (node.isSelected() === false) { if (node.isSelected() === false) {
this.selectionHandler.unselectAll();
this.selectionHandler.selectObject(node); this.selectionHandler.selectObject(node);
} }
@ -274,6 +274,7 @@ class InteractionHandler {
* @private * @private
*/ */
onPinch(event) { onPinch(event) {
console.log("on pinch")
var pointer = this.getPointer(event.center); var pointer = this.getPointer(event.center);
this.drag.pinched = true; this.drag.pinched = true;
@ -387,76 +388,76 @@ class InteractionHandler {
* @private * @private
*/ */
onMouseMove(event) { onMouseMove(event) {
var pointer = {x:event.pageX, y:event.pageY};
var popupVisible = false;
// check if the previously selected node is still selected
if (this.popup !== undefined) {
if (this.popup.hidden === false) {
this._checkHidePopup(pointer);
}
// if the popup was not hidden above
if (this.popup.hidden === false) {
popupVisible = true;
this.popup.setPosition(pointer.x + 3, pointer.y - 5)
this.popup.show();
}
}
// if we bind the keyboard to the div, we have to highlight it to use it. This highlights it on mouse over
if (this.options.keyboard.bindToWindow == false && this.options.keyboard.enabled === true) {
this.canvas.frame.focus();
}
// start a timeout that will check if the mouse is positioned above an element
if (popupVisible === false) {
var me = this;
var checkShow = function() {
me._checkShowPopup(pointer);
};
if (this.popupTimer) {
clearInterval(this.popupTimer); // stop any running calculationTimer
}
if (!this.drag.dragging) {
this.popupTimer = setTimeout(checkShow, this.options.tooltip.delay);
}
}
/**
* Adding hover highlights
*/
if (this.options.hoverEnabled === true) {
// removing all hover highlights
for (var edgeId in this.hoverObj.edges) {
if (this.hoverObj.edges.hasOwnProperty(edgeId)) {
this.hoverObj.edges[edgeId].hover = false;
delete this.hoverObj.edges[edgeId];
}
}
// adding hover highlights
var obj = this.selectionHandler.getNodeAt(pointer);
if (obj == null) {
obj = this.selectionHandler.getEdgeAt(pointer);
}
if (obj != null) {
this._hoverObject(obj);
}
// removing all node hover highlights except for the selected one.
for (var nodeId in this.hoverObj.nodes) {
if (this.hoverObj.nodes.hasOwnProperty(nodeId)) {
if (obj instanceof Node && obj.id != nodeId || obj instanceof Edge || obj == null) {
this._blurObject(this.hoverObj.nodes[nodeId]);
delete this.hoverObj.nodes[nodeId];
}
}
}
this.body.emitter.emit("_requestRedraw");
}
// var pointer = {x:event.pageX, y:event.pageY};
// var popupVisible = false;
//
// // check if the previously selected node is still selected
// if (this.popup !== undefined) {
// if (this.popup.hidden === false) {
// this._checkHidePopup(pointer);
// }
//
// // if the popup was not hidden above
// if (this.popup.hidden === false) {
// popupVisible = true;
// this.popup.setPosition(pointer.x + 3, pointer.y - 5)
// this.popup.show();
// }
// }
//
// // if we bind the keyboard to the div, we have to highlight it to use it. This highlights it on mouse over
// if (this.options.keyboard.bindToWindow == false && this.options.keyboard.enabled === true) {
// this.canvas.frame.focus();
// }
//
// // start a timeout that will check if the mouse is positioned above an element
// if (popupVisible === false) {
// var me = this;
// var checkShow = function() {
// me._checkShowPopup(pointer);
// };
//
// if (this.popupTimer) {
// clearInterval(this.popupTimer); // stop any running calculationTimer
// }
// if (!this.drag.dragging) {
// this.popupTimer = setTimeout(checkShow, this.options.tooltip.delay);
// }
// }
//
// /**
// * Adding hover highlights
// */
// if (this.options.hoverEnabled === true) {
// // removing all hover highlights
// for (var edgeId in this.hoverObj.edges) {
// if (this.hoverObj.edges.hasOwnProperty(edgeId)) {
// this.hoverObj.edges[edgeId].hover = false;
// delete this.hoverObj.edges[edgeId];
// }
// }
//
// // adding hover highlights
// var obj = this.selectionHandler.getNodeAt(pointer);
// if (obj == null) {
// obj = this.selectionHandler.getEdgeAt(pointer);
// }
// if (obj != null) {
// this._hoverObject(obj);
// }
//
// // removing all node hover highlights except for the selected one.
// for (var nodeId in this.hoverObj.nodes) {
// if (this.hoverObj.nodes.hasOwnProperty(nodeId)) {
// if (obj instanceof Node && obj.id != nodeId || obj instanceof Edge || obj == null) {
// this._blurObject(this.hoverObj.nodes[nodeId]);
// delete this.hoverObj.nodes[nodeId];
// }
// }
// }
// this.body.emitter.emit("_requestRedraw");
// }
} }
} }
export {TouchEventHandler};
export {InteractionHandler};

+ 2
- 8
lib/network/modules/SelectionHandler.js View File

@ -36,17 +36,11 @@ class SelectionHandler {
selectOnPoint(pointer) { selectOnPoint(pointer) {
var selected = false; var selected = false;
if (this.options.select === true) { if (this.options.select === true) {
this.unselectAll();
var obj = this.getNodeAt(pointer) || this.getEdgeAt(pointer);; var obj = this.getNodeAt(pointer) || this.getEdgeAt(pointer);;
// deselect
if (obj === undefined) {
this.unselectAll();
}
else {
if (obj !== undefined) {
selected = this.selectObject(obj); selected = this.selectObject(obj);
} }
this.body.emitter.emit("_requestRedraw"); this.body.emitter.emit("_requestRedraw");
} }
return selected; return selected;

+ 5
- 5
lib/network/modules/View.js View File

@ -16,8 +16,8 @@ class View {
this.targetScale = 0; this.targetScale = 0;
this.sourceTranslation = 0; this.sourceTranslation = 0;
this.targetTranslation = 0; this.targetTranslation = 0;
this.lockedOnNodeId = null;
this.lockedOnNodeOffset = null;
this.lockedOnNodeId = undefined;
this.lockedOnNodeOffset = undefined;
this.touchTime = 0; this.touchTime = 0;
this.viewFunction = undefined; this.viewFunction = undefined;
@ -250,7 +250,7 @@ class View {
// if the time is set to 0, don't do an animation // if the time is set to 0, don't do an animation
if (options.animation.duration == 0) { if (options.animation.duration == 0) {
if (this.lockedOnNodeId != null) {
if (this.lockedOnNodeId != undefined) {
this.viewFunction = this._lockedRedraw.bind(this); this.viewFunction = this._lockedRedraw.bind(this);
this.body.emitter.on("_beforeRender", this.viewFunction); this.body.emitter.on("_beforeRender", this.viewFunction);
} }
@ -292,7 +292,7 @@ class View {
} }
releaseNode() { releaseNode() {
if (this.lockedOnNodeId !== undefined) {
if (this.lockedOnNodeId !== undefined && this.viewFunction !== undefined) {
this.body.emitter.off("_beforeRender", this.viewFunction); this.body.emitter.off("_beforeRender", this.viewFunction);
this.lockedOnNodeId = undefined; this.lockedOnNodeId = undefined;
this.lockedOnNodeOffset = undefined; this.lockedOnNodeOffset = undefined;
@ -320,7 +320,7 @@ class View {
if (this.easingTime >= 1.0) { if (this.easingTime >= 1.0) {
this.body.emitter.off("_beforeRender", this.viewFunction); this.body.emitter.off("_beforeRender", this.viewFunction);
this.easingTime = 0; this.easingTime = 0;
if (this.lockedOnNodeId != null) {
if (this.lockedOnNodeId != undefined) {
this.viewFunction = this._lockedRedraw.bind(this); this.viewFunction = this._lockedRedraw.bind(this);
this.body.emitter.on("_beforeRender", this.viewFunction); this.body.emitter.on("_beforeRender", this.viewFunction);
} }

Loading…
Cancel
Save