Browse Source

fixed ZoomToFit, tweaked force calculation

css_transitions
Alex de Mulder 10 years ago
parent
commit
3e9b13c1db
15 changed files with 298 additions and 171 deletions
  1. BIN
      dist/UI/downarrow.png
  2. BIN
      dist/UI/leftarrow.png
  3. BIN
      dist/UI/minus.png
  4. BIN
      dist/UI/plus.png
  5. BIN
      dist/UI/rightarrow.png
  6. BIN
      dist/UI/uparrow.png
  7. BIN
      dist/UI/zoomExtends.png
  8. +150
    -86
      dist/vis.js
  9. +6
    -6
      dist/vis.min.js
  10. +1
    -1
      examples/graph/20_UI_example.html
  11. +1
    -1
      package.json
  12. +100
    -56
      src/graph/Graph.js
  13. +5
    -5
      src/graph/Node.js
  14. +32
    -13
      src/graph/UIMixin.js
  15. +3
    -3
      src/module/imports.js

BIN
dist/UI/downarrow.png View File

Before After
Width: 30  |  Height: 30  |  Size: 4.4 KiB

BIN
dist/UI/leftarrow.png View File

Before After
Width: 30  |  Height: 30  |  Size: 4.4 KiB

BIN
dist/UI/minus.png View File

Before After
Width: 30  |  Height: 30  |  Size: 4.0 KiB

BIN
dist/UI/plus.png View File

Before After
Width: 30  |  Height: 30  |  Size: 4.2 KiB

BIN
dist/UI/rightarrow.png View File

Before After
Width: 30  |  Height: 30  |  Size: 4.4 KiB

BIN
dist/UI/uparrow.png View File

Before After
Width: 30  |  Height: 30  |  Size: 4.4 KiB

BIN
dist/UI/zoomExtends.png View File

Before After
Width: 30  |  Height: 30  |  Size: 4.4 KiB

+ 150
- 86
dist/vis.js View File

@ -5,7 +5,7 @@
* A dynamic, browser-based visualization library. * A dynamic, browser-based visualization library.
* *
* @version 0.4.0-SNAPSHOT * @version 0.4.0-SNAPSHOT
* @date 2014-01-24
* @date 2014-01-27
* *
* @license * @license
* Copyright (C) 2011-2014 Almende B.V, http://almende.com * Copyright (C) 2011-2014 Almende B.V, http://almende.com
@ -22,7 +22,7 @@
* License for the specific language governing permissions and limitations under * License for the specific language governing permissions and limitations under
* the License. * the License.
*/ */
!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.vis=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.vis=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
/** /**
* vis.js module imports * vis.js module imports
*/ */
@ -30,12 +30,12 @@
// Try to load dependencies from the global window object. // Try to load dependencies from the global window object.
// If not available there, load via require. // If not available there, load via require.
var moment = (typeof window !== 'undefined') && window['moment'] || _dereq_('moment');
var moment = (typeof window !== 'undefined') && window['moment'] || require('moment');
var Hammer; var Hammer;
if (typeof window !== 'undefined') { if (typeof window !== 'undefined') {
// load hammer.js only when running in a browser (where window is available) // load hammer.js only when running in a browser (where window is available)
Hammer = window['Hammer'] || _dereq_('hammerjs');
Hammer = window['Hammer'] || require('hammerjs');
} }
else { else {
Hammer = function () { Hammer = function () {
@ -43,13 +43,13 @@ else {
} }
} }
var mouseTrap;
var mousetrap;
if (typeof window !== 'undefined') { if (typeof window !== 'undefined') {
// load mousetrap.js only when running in a browser (where window is available) // load mousetrap.js only when running in a browser (where window is available)
mouseTrap = window['mouseTrap'] || _dereq_('mouseTrap');
mousetrap = window['mousetrap'] || require('mousetrap');
} }
else { else {
mouseTrap = function () {
mousetrap = function () {
throw Error('mouseTrap is only available in a browser, not in node.js.'); throw Error('mouseTrap is only available in a browser, not in node.js.');
} }
} }
@ -8815,7 +8815,7 @@ function Node(properties, imagelist, grouplist, constants) {
this.vy = 0.0; // velocity y this.vy = 0.0; // velocity y
this.minForce = constants.minForce; this.minForce = constants.minForce;
this.damping = 0.9; this.damping = 0.9;
this.dampingFactor = 60;
this.dampingFactor = 75;
this.graphScaleInv = 1; this.graphScaleInv = 1;
this.canvasTopLeft = {"x": -300, "y": -300}; this.canvasTopLeft = {"x": -300, "y": -300};
@ -9641,10 +9641,10 @@ Node.prototype.getTextSize = function(ctx) {
*/ */
Node.prototype.inArea = function() { Node.prototype.inArea = function() {
if (this.width !== undefined) { if (this.width !== undefined) {
return (this.x + this.width*0.8 >= this.canvasTopLeft.x &&
this.x - this.width*0.8 < this.canvasBottomRight.x &&
this.y + this.height*0.8 >= this.canvasTopLeft.y &&
this.y - this.height*0.8 < this.canvasBottomRight.y);
return (this.x + this.width*this.graphScaleInv >= this.canvasTopLeft.x &&
this.x - this.width*this.graphScaleInv < this.canvasBottomRight.x &&
this.y + this.height*this.graphScaleInv >= this.canvasTopLeft.y &&
this.y - this.height*this.graphScaleInv < this.canvasBottomRight.y);
} }
else { else {
return true; return true;
@ -12674,25 +12674,27 @@ var UIMixin = {
this.UIclientWidth = 0; this.UIclientWidth = 0;
this.UIclientHeight = 0; this.UIclientHeight = 0;
} }
var offset = 15;
var intermediateOffset = 7;
var UINodes = [ var UINodes = [
{id: 'UI_up', shape: 'image', image: DIR + 'uparrow.png', triggerFunction: "_moveUp", {id: 'UI_up', shape: 'image', image: DIR + 'uparrow.png', triggerFunction: "_moveUp",
verticalAlignTop: false, x: 52, y: this.UIclientHeight - 52},
verticalAlignTop: false, x: 45 + offset + intermediateOffset, y: this.UIclientHeight - 47 - offset},
{id: 'UI_down', shape: 'image', image: DIR + 'downarrow.png', triggerFunction: "_moveDown", {id: 'UI_down', shape: 'image', image: DIR + 'downarrow.png', triggerFunction: "_moveDown",
verticalAlignTop: false, x: 52, y: this.UIclientHeight - 20},
verticalAlignTop: false, x: 45 + offset + intermediateOffset, y: this.UIclientHeight - 15 - offset},
{id: 'UI_left', shape: 'image', image: DIR + 'leftarrow.png', triggerFunction: "_moveLeft", {id: 'UI_left', shape: 'image', image: DIR + 'leftarrow.png', triggerFunction: "_moveLeft",
verticalAlignTop: false, x: 20, y: this.UIclientHeight - 20},
verticalAlignTop: false, x: 15 + offset, y: this.UIclientHeight - 15 - offset},
{id: 'UI_right', shape: 'image', image: DIR + 'rightarrow.png',triggerFunction: "_moveRight", {id: 'UI_right', shape: 'image', image: DIR + 'rightarrow.png',triggerFunction: "_moveRight",
verticalAlignTop: false, x: 84, y: this.UIclientHeight - 20},
verticalAlignTop: false, x: 75 + offset + 2 * intermediateOffset, y: this.UIclientHeight - 15 - offset},
{id: 'UI_plus', shape: 'image', image: DIR + 'plus.png', triggerFunction: "_zoomIn", {id: 'UI_plus', shape: 'image', image: DIR + 'plus.png', triggerFunction: "_zoomIn",
verticalAlignTop: false, horizontalAlignLeft: false, verticalAlignTop: false, horizontalAlignLeft: false,
x: this.UIclientWidth - 52, y: this.UIclientHeight - 20},
x: this.UIclientWidth - 45 - offset - intermediateOffset, y: this.UIclientHeight - 15 - offset},
{id: 'UI_min', shape: 'image', image: DIR + 'minus.png', triggerFunction: "_zoomOut", {id: 'UI_min', shape: 'image', image: DIR + 'minus.png', triggerFunction: "_zoomOut",
verticalAlignTop: false, horizontalAlignLeft: false, verticalAlignTop: false, horizontalAlignLeft: false,
x: this.UIclientWidth - 20, y: this.UIclientHeight - 20},
x: this.UIclientWidth - 15 - offset, y: this.UIclientHeight - 15 - offset},
{id: 'UI_zoomExtends', shape: 'image', image: DIR + 'zoomExtends.png', triggerFunction: "zoomToFit", {id: 'UI_zoomExtends', shape: 'image', image: DIR + 'zoomExtends.png', triggerFunction: "zoomToFit",
verticalAlignTop: false, horizontalAlignLeft: false, verticalAlignTop: false, horizontalAlignLeft: false,
x: this.UIclientWidth - 20, y: this.UIclientHeight - 52}
x: this.UIclientWidth - 15 - offset, y: this.UIclientHeight - 45 - offset - intermediateOffset}
]; ];
var nodeObj = null; var nodeObj = null;
@ -12755,6 +12757,17 @@ var UIMixin = {
}, },
_preventDefault : function(event) {
if (event !== undefined) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
}
},
/** /**
* move the screen up * move the screen up
* By using the increments, instead of adding a fixed number to the translation, we keep fluent and * By using the increments, instead of adding a fixed number to the translation, we keep fluent and
@ -12763,10 +12776,11 @@ var UIMixin = {
* *
* @private * @private
*/ */
_moveUp : function() {
_moveUp : function(event) {
this._highlightUIElement("UI_up"); this._highlightUIElement("UI_up");
this.yIncrement = this.constants.UI.yMovementSpeed; this.yIncrement = this.constants.UI.yMovementSpeed;
this.start(); // if there is no node movement, the calculation wont be done this.start(); // if there is no node movement, the calculation wont be done
this._preventDefault(event);
}, },
@ -12774,10 +12788,11 @@ var UIMixin = {
* move the screen down * move the screen down
* @private * @private
*/ */
_moveDown : function() {
_moveDown : function(event) {
this._highlightUIElement("UI_down"); this._highlightUIElement("UI_down");
this.yIncrement = -this.constants.UI.yMovementSpeed; this.yIncrement = -this.constants.UI.yMovementSpeed;
this.start(); // if there is no node movement, the calculation wont be done this.start(); // if there is no node movement, the calculation wont be done
this._preventDefault(event);
}, },
@ -12785,10 +12800,11 @@ var UIMixin = {
* move the screen left * move the screen left
* @private * @private
*/ */
_moveLeft : function() {
_moveLeft : function(event) {
this._highlightUIElement("UI_left"); this._highlightUIElement("UI_left");
this.xIncrement = this.constants.UI.xMovementSpeed; this.xIncrement = this.constants.UI.xMovementSpeed;
this.start(); // if there is no node movement, the calculation wont be done this.start(); // if there is no node movement, the calculation wont be done
this._preventDefault(event);
}, },
@ -12796,10 +12812,11 @@ var UIMixin = {
* move the screen right * move the screen right
* @private * @private
*/ */
_moveRight : function() {
_moveRight : function(event) {
this._highlightUIElement("UI_right"); this._highlightUIElement("UI_right");
this.xIncrement = -this.constants.UI.xMovementSpeed; this.xIncrement = -this.constants.UI.xMovementSpeed;
this.start(); // if there is no node movement, the calculation wont be done this.start(); // if there is no node movement, the calculation wont be done
this._preventDefault(event);
}, },
@ -12807,10 +12824,11 @@ var UIMixin = {
* Zoom in, using the same method as the movement. * Zoom in, using the same method as the movement.
* @private * @private
*/ */
_zoomIn : function() {
_zoomIn : function(event) {
this._highlightUIElement("UI_plus"); this._highlightUIElement("UI_plus");
this.zoomIncrement = this.constants.UI.zoomMovementSpeed; this.zoomIncrement = this.constants.UI.zoomMovementSpeed;
this.start(); // if there is no node movement, the calculation wont be done this.start(); // if there is no node movement, the calculation wont be done
this._preventDefault(event);
}, },
@ -12822,6 +12840,7 @@ var UIMixin = {
this._highlightUIElement("UI_min"); this._highlightUIElement("UI_min");
this.zoomIncrement = -this.constants.UI.zoomMovementSpeed; this.zoomIncrement = -this.constants.UI.zoomMovementSpeed;
this.start(); // if there is no node movement, the calculation wont be done this.start(); // if there is no node movement, the calculation wont be done
this._preventDefault(event);
}, },
@ -12862,6 +12881,7 @@ var UIMixin = {
}; };
/** /**
* @constructor Graph * @constructor Graph
* Create a graph visualization, displaying nodes and edges. * Create a graph visualization, displaying nodes and edges.
@ -12955,7 +12975,8 @@ function Graph (container, data, options) {
initiallyVisible: true, initiallyVisible: true,
xMovementSpeed: 10, xMovementSpeed: 10,
yMovementSpeed: 10, yMovementSpeed: 10,
zoomMovementSpeed: 0.02
zoomMovementSpeed: 0.02,
iconPath: 'img/UI/'
}, },
minVelocity: 1.0, // px/s minVelocity: 1.0, // px/s
maxIterations: 1000 // maximum number of iteration to stabilize maxIterations: 1000 // maximum number of iteration to stabilize
@ -12975,6 +12996,7 @@ function Graph (container, data, options) {
this.yIncrement = 0; this.yIncrement = 0;
this.zoomIncrement = 0; this.zoomIncrement = 0;
console.log
// create a frame and canvas // create a frame and canvas
this._create(); this._create();
@ -13053,7 +13075,7 @@ function Graph (container, data, options) {
this.setData(data,this.constants.clustering.enabled); this.setData(data,this.constants.clustering.enabled);
// zoom so all data will fit on the screen // zoom so all data will fit on the screen
this.zoomToFit();
this.zoomToFit(true);
// if clustering is disabled, the simulation will have started in the setData function // if clustering is disabled, the simulation will have started in the setData function
if (this.constants.clustering.enabled) { if (this.constants.clustering.enabled) {
@ -13066,44 +13088,87 @@ function Graph (container, data, options) {
* Find the center position of the graph * Find the center position of the graph
* @private * @private
*/ */
Graph.prototype._findCenter = function() {
Graph.prototype._getRange = function() {
var minY = 1e9, maxY = -1e9, minX = 1e9, maxX = -1e9, node; var minY = 1e9, maxY = -1e9, minX = 1e9, maxX = -1e9, node;
for (var i = 0; i < this.nodeIndices.length; i++) { for (var i = 0; i < this.nodeIndices.length; i++) {
node = this.nodes[this.nodeIndices[i]]; node = this.nodes[this.nodeIndices[i]];
if (minX > node.x) {minX = node.x;}
if (maxX < node.x) {maxX = node.x;}
if (minY > node.y) {minY = node.y;}
if (maxY < node.y) {maxY = node.y;}
if (minX > (node.x - node.width)) {minX = node.x - node.width;}
if (maxX < (node.x + node.width)) {maxX = node.x + node.width;}
if (minY > (node.y - node.height)) {minY = node.y - node.height;}
if (maxY < (node.y + node.height)) {maxY = node.y + node.height;}
} }
return {x: (0.5 * (maxX + minX)),
y: (0.5 * (maxY + minY))};
return {minX: minX, maxX: maxX, minY: minY, maxY: maxY};
};
/**
* @param {object} range = {minX: minX, maxX: maxX, minY: minY, maxY: maxY};
* @returns {{x: number, y: number}}
* @private
*/
Graph.prototype._findCenter = function(range) {
var center = {x: (0.5 * (range.maxX + range.minX)),
y: (0.5 * (range.maxY + range.minY))};
return center;
}; };
/** /**
* center the graph * center the graph
*
* @param {object} range = {minX: minX, maxX: maxX, minY: minY, maxY: maxY};
*/ */
Graph.prototype._centerGraph = function() {
var center = this._findCenter();
Graph.prototype._centerGraph = function(range) {
var center = this._findCenter(range);
center.x *= this.scale;
center.y *= this.scale;
center.x -= 0.5 * this.frame.canvas.clientWidth; center.x -= 0.5 * this.frame.canvas.clientWidth;
center.y -= 0.5 * this.frame.canvas.clientHeight; center.y -= 0.5 * this.frame.canvas.clientHeight;
this._setTranslation(-center.x,-center.y);
this._setTranslation(-center.x,-center.y); // set at 0,0
}; };
/** /**
* This function zooms out to fit all data on screen based on amount of nodes
* This function zooms out to fit all data on screen based on amount of nodes
*
* @param {Boolean} [initialZoom] | zoom based on fitted formula or range, true = fitted, default = false;
*/ */
Graph.prototype.zoomToFit = function() {
Graph.prototype.zoomToFit = function(initialZoom) {
if (initialZoom === undefined) {
initialZoom = false;
}
var numberOfNodes = this.nodeIndices.length; var numberOfNodes = this.nodeIndices.length;
var zoomLevel = 46.5 / (numberOfNodes + 20.622); // this is obtained from fitting a dataset from 5 points with scale levels that looked good.
var range = this._getRange();
if (initialZoom == true) {
if (this.constants.clustering.enabled == true &&
numberOfNodes < this.constants.clustering.initialMaxNumberOfNodes) {
var zoomLevel = 38.8467 / (numberOfNodes - 14.50184) + 0.0116360476; // this is obtained from fitting a dataset from 5 points with scale levels that looked good.
}
else {
var zoomLevel = 42.54117319 / (numberOfNodes + 39.31966387) + 0.1944405; // this is obtained from fitting a dataset from 5 points with scale levels that looked good.
}
}
else {
var xDistance = (Math.abs(range.minX) + Math.abs(range.maxX)) * 1.1;
var yDistance = (Math.abs(range.minY) + Math.abs(range.maxY)) * 1.1;
var xZoomLevel = this.frame.canvas.clientWidth / xDistance;
var yZoomLevel = this.frame.canvas.clientHeight / yDistance;
zoomLevel = (xZoomLevel <= yZoomLevel) ? xZoomLevel : yZoomLevel;
}
if (zoomLevel > 1.0) { if (zoomLevel > 1.0) {
zoomLevel = 1.0; zoomLevel = 1.0;
} }
this.pinch.mousewheelScale = zoomLevel; this.pinch.mousewheelScale = zoomLevel;
this._setScale(zoomLevel); this._setScale(zoomLevel);
this._centerGraph();
this._centerGraph(range);
}; };
@ -13334,35 +13399,35 @@ Graph.prototype._create = function () {
*/ */
Graph.prototype._createKeyBinds = function() { Graph.prototype._createKeyBinds = function() {
var me = this; var me = this;
this.mouseTrap = mouseTrap;
this.mouseTrap.bind("up", this._moveUp.bind(me) , "keydown");
this.mouseTrap.bind("up", this._yStopMoving.bind(me), "keyup");
this.mouseTrap.bind("down", this._moveDown.bind(me) , "keydown");
this.mouseTrap.bind("down", this._yStopMoving.bind(me), "keyup");
this.mouseTrap.bind("left", this._moveLeft.bind(me) , "keydown");
this.mouseTrap.bind("left", this._xStopMoving.bind(me), "keyup");
this.mouseTrap.bind("right",this._moveRight.bind(me), "keydown");
this.mouseTrap.bind("right",this._xStopMoving.bind(me), "keyup");
this.mouseTrap.bind("=",this._zoomIn.bind(me), "keydown");
this.mouseTrap.bind("=",this._stopZoom.bind(me), "keyup");
this.mouseTrap.bind("-",this._zoomOut.bind(me), "keydown");
this.mouseTrap.bind("-",this._stopZoom.bind(me), "keyup");
this.mouseTrap.bind("[",this._zoomIn.bind(me), "keydown");
this.mouseTrap.bind("[",this._stopZoom.bind(me), "keyup");
this.mouseTrap.bind("]",this._zoomOut.bind(me), "keydown");
this.mouseTrap.bind("]",this._stopZoom.bind(me), "keyup");
this.mouseTrap.bind("pageup",this._zoomIn.bind(me), "keydown");
this.mouseTrap.bind("pageup",this._stopZoom.bind(me), "keyup");
this.mouseTrap.bind("pagedown",this._zoomOut.bind(me), "keydown");
this.mouseTrap.bind("pagedown",this._stopZoom.bind(me), "keyup");
this.mouseTrap.bind("u",this._toggleUI.bind(me) , "keydown");
this.mousetrap = mousetrap;
this.mousetrap.bind("up", this._moveUp.bind(me) , "keydown");
this.mousetrap.bind("up", this._yStopMoving.bind(me), "keyup");
this.mousetrap.bind("down", this._moveDown.bind(me) , "keydown");
this.mousetrap.bind("down", this._yStopMoving.bind(me), "keyup");
this.mousetrap.bind("left", this._moveLeft.bind(me) , "keydown");
this.mousetrap.bind("left", this._xStopMoving.bind(me), "keyup");
this.mousetrap.bind("right",this._moveRight.bind(me), "keydown");
this.mousetrap.bind("right",this._xStopMoving.bind(me), "keyup");
this.mousetrap.bind("=",this._zoomIn.bind(me), "keydown");
this.mousetrap.bind("=",this._stopZoom.bind(me), "keyup");
this.mousetrap.bind("-",this._zoomOut.bind(me), "keydown");
this.mousetrap.bind("-",this._stopZoom.bind(me), "keyup");
this.mousetrap.bind("[",this._zoomIn.bind(me), "keydown");
this.mousetrap.bind("[",this._stopZoom.bind(me), "keyup");
this.mousetrap.bind("]",this._zoomOut.bind(me), "keydown");
this.mousetrap.bind("]",this._stopZoom.bind(me), "keyup");
this.mousetrap.bind("pageup",this._zoomIn.bind(me), "keydown");
this.mousetrap.bind("pageup",this._stopZoom.bind(me), "keyup");
this.mousetrap.bind("pagedown",this._zoomOut.bind(me), "keydown");
this.mousetrap.bind("pagedown",this._stopZoom.bind(me), "keyup");
this.mousetrap.bind("u",this._toggleUI.bind(me) , "keydown");
/* /*
this.mouseTrap.bind("=",this.decreaseClusterLevel.bind(me));
this.mouseTrap.bind("-",this.increaseClusterLevel.bind(me));
this.mouseTrap.bind("s",this.singleStep.bind(me));
this.mouseTrap.bind("h",this.updateClustersDefault.bind(me));
this.mouseTrap.bind("c",this._collapseSector.bind(me));
this.mouseTrap.bind("f",this.toggleFreeze.bind(me));
this.mousetrap.bind("=",this.decreaseClusterLevel.bind(me));
this.mousetrap.bind("-",this.increaseClusterLevel.bind(me));
this.mousetrap.bind("s",this.singleStep.bind(me));
this.mousetrap.bind("h",this.updateClustersDefault.bind(me));
this.mousetrap.bind("c",this._collapseSector.bind(me));
this.mousetrap.bind("f",this.toggleFreeze.bind(me));
*/ */
} }
@ -13484,7 +13549,6 @@ Graph.prototype._onDrag = function (event) {
this.drag.translation.x + diffX, this.drag.translation.x + diffX,
this.drag.translation.y + diffY); this.drag.translation.y + diffY);
this._redraw(); this._redraw();
this.moved = true; this.moved = true;
} }
}; };
@ -13595,8 +13659,6 @@ Graph.prototype._zoom = function(scale, pointer) {
this.updateClustersDefault(); this.updateClustersDefault();
this._redraw(); this._redraw();
// console.log("current zoomscale:",this.scale);
return scale; return scale;
}; };
@ -14201,10 +14263,10 @@ Graph.prototype._redraw = function() {
ctx.translate(this.translation.x, this.translation.y); ctx.translate(this.translation.x, this.translation.y);
ctx.scale(this.scale, this.scale); ctx.scale(this.scale, this.scale);
this.canvasTopLeft = {"x": (0-this.translation.x)/this.scale,
"y": (0-this.translation.y)/this.scale};
this.canvasBottomRight = {"x": (this.frame.canvas.clientWidth -this.translation.x)/this.scale,
"y": (this.frame.canvas.clientHeight-this.translation.y)/this.scale};
this.canvasTopLeft = {"x": this._canvasToX(0),
"y": this._canvasToY(0)};
this.canvasBottomRight = {"x": this._canvasToX(this.frame.canvas.clientWidth),
"y": this._canvasToY(this.frame.canvas.clientHeight)};
this._doInAllSectors("_drawAllSectorNodes",ctx); this._doInAllSectors("_drawAllSectorNodes",ctx);
this._doInAllSectors("_drawEdges",ctx); this._doInAllSectors("_drawEdges",ctx);
@ -14420,9 +14482,8 @@ Graph.prototype._initializeForceCalculation = function() {
* @private * @private
*/ */
Graph.prototype._calculateForces = function() { Graph.prototype._calculateForces = function() {
var screenCenterPos = {"x":0.5*(this.canvasTopLeft.x + this.canvasBottomRight.x),
"y":0.5*(this.canvasTopLeft.y + this.canvasBottomRight.y)}
var screenCenterPos = {"x":(0.5*(this.canvasTopLeft.x + this.canvasBottomRight.x)),
"y":(0.5*(this.canvasTopLeft.y + this.canvasBottomRight.y))}
// create a local edge to the nodes and edges, that is faster // create a local edge to the nodes and edges, that is faster
var dx, dy, angle, distance, fx, fy, var dx, dy, angle, distance, fx, fy,
repulsingForce, springForce, length, edgeLength, repulsingForce, springForce, length, edgeLength,
@ -14434,7 +14495,7 @@ Graph.prototype._calculateForces = function() {
// Gravity is required to keep separated groups from floating off // Gravity is required to keep separated groups from floating off
// the forces are reset to zero in this loop by using _setForce instead // the forces are reset to zero in this loop by using _setForce instead
// of _addForce // of _addForce
var gravity = 0.3 * this.forceFactor;
var gravity = 0.20 * this.forceFactor;
for (i = 0; i < this.nodeIndices.length; i++) { for (i = 0; i < this.nodeIndices.length; i++) {
node = nodes[this.nodeIndices[i]]; node = nodes[this.nodeIndices[i]];
// gravity does not apply when we are in a pocket sector // gravity does not apply when we are in a pocket sector
@ -14638,7 +14699,7 @@ Graph.prototype._isMoving = function(vmin) {
* @private * @private
*/ */
Graph.prototype._discreteStepNodes = function() { Graph.prototype._discreteStepNodes = function() {
var interval = 0.01;
var interval = 0.010;
var nodes = this.nodes; var nodes = this.nodes;
for (var id in nodes) { for (var id in nodes) {
if (nodes.hasOwnProperty(id)) { if (nodes.hasOwnProperty(id)) {
@ -14663,6 +14724,8 @@ Graph.prototype.start = function() {
if (this.moving) { if (this.moving) {
this._doInAllActiveSectors("_initializeForceCalculation"); this._doInAllActiveSectors("_initializeForceCalculation");
this._doInAllActiveSectors("_discreteStepNodes"); this._doInAllActiveSectors("_discreteStepNodes");
this._findCenter(this._getRange())
} }
if (this.moving || this.xIncrement != 0 || this.yIncrement != 0 || this.zoomIncrement != 0) { if (this.moving || this.xIncrement != 0 || this.yIncrement != 0 || this.zoomIncrement != 0) {
@ -14805,6 +14868,7 @@ Graph.prototype._loadUISystem = function() {
if (this.constants.UI.enabled == true) { if (this.constants.UI.enabled == true) {
this._loadUIElements(); this._loadUIElements();
this._createKeyBinds(); this._createKeyBinds();
} }
} }
@ -14917,7 +14981,7 @@ if (typeof window !== 'undefined') {
} }
},{"hammerjs":2,"moment":3,"mouseTrap":4}],2:[function(_dereq_,module,exports){
},{"hammerjs":2,"moment":3,"mousetrap":4}],2:[function(require,module,exports){
/*! Hammer.JS - v1.0.5 - 2013-04-07 /*! Hammer.JS - v1.0.5 - 2013-04-07
* http://eightmedia.github.com/hammer.js * http://eightmedia.github.com/hammer.js
* *
@ -16339,7 +16403,7 @@ else {
} }
} }
})(this); })(this);
},{}],3:[function(_dereq_,module,exports){
},{}],3:[function(require,module,exports){
//! moment.js //! moment.js
//! version : 2.5.1 //! version : 2.5.1
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors //! authors : Tim Wood, Iskren Chernev, Moment.js contributors
@ -16383,7 +16447,7 @@ else {
}, },
// check for nodeJS // check for nodeJS
hasModule = (typeof module !== 'undefined' && module.exports && typeof _dereq_ !== 'undefined'),
hasModule = (typeof module !== 'undefined' && module.exports && typeof require !== 'undefined'),
// ASP.NET json date format regex // ASP.NET json date format regex
aspNetJsonRegex = /^\/?Date\((\-?\d+)/i, aspNetJsonRegex = /^\/?Date\((\-?\d+)/i,
@ -17175,7 +17239,7 @@ else {
get = function (k) { get = function (k) {
if (!languages[k] && hasModule) { if (!languages[k] && hasModule) {
try { try {
_dereq_('./lang/' + k);
require('./lang/' + k);
} catch (e) { } } catch (e) { }
} }
return languages[k]; return languages[k];
@ -18728,7 +18792,7 @@ else {
module.exports = moment; module.exports = moment;
makeGlobal(true); makeGlobal(true);
} else if (typeof define === "function" && define.amd) { } else if (typeof define === "function" && define.amd) {
define("moment", function (_dereq_, exports, module) {
define("moment", function (require, exports, module) {
if (module.config && module.config() && module.config().noGlobal !== true) { if (module.config && module.config() && module.config().noGlobal !== true) {
// If user provided noGlobal, he is aware of global // If user provided noGlobal, he is aware of global
makeGlobal(module.config().noGlobal === undefined); makeGlobal(module.config().noGlobal === undefined);
@ -18741,7 +18805,7 @@ else {
} }
}).call(this); }).call(this);
},{}],4:[function(_dereq_,module,exports){
},{}],4:[function(require,module,exports){
/** /**
* Copyright 2012 Craig Campbell * Copyright 2012 Craig Campbell
* *

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


+ 1
- 1
examples/graph/20_UI_example.html View File

@ -18,7 +18,7 @@
border-color:#d3d3d3; border-color:#d3d3d3;
border-style:solid; border-style:solid;
} }
table.legend_tabl,td {
table.legend_table,td {
border-width:1px; border-width:1px;
border-color:#d3d3d3; border-color:#d3d3d3;
border-style:solid; border-style:solid;

+ 1
- 1
package.json View File

@ -28,7 +28,7 @@
"devDependencies": { "devDependencies": {
"jake": "latest", "jake": "latest",
"jake-utils": "latest", "jake-utils": "latest",
"browserify": "latest",
"browserify": "3.22",
"moment": "latest", "moment": "latest",
"hammerjs": "1.0.5", "hammerjs": "1.0.5",
"mousetrap": "latest", "mousetrap": "latest",

+ 100
- 56
src/graph/Graph.js View File

@ -91,7 +91,8 @@ function Graph (container, data, options) {
initiallyVisible: true, initiallyVisible: true,
xMovementSpeed: 10, xMovementSpeed: 10,
yMovementSpeed: 10, yMovementSpeed: 10,
zoomMovementSpeed: 0.02
zoomMovementSpeed: 0.02,
iconPath: 'img/UI/'
}, },
minVelocity: 1.0, // px/s minVelocity: 1.0, // px/s
maxIterations: 1000 // maximum number of iteration to stabilize maxIterations: 1000 // maximum number of iteration to stabilize
@ -111,6 +112,7 @@ function Graph (container, data, options) {
this.yIncrement = 0; this.yIncrement = 0;
this.zoomIncrement = 0; this.zoomIncrement = 0;
console.log
// create a frame and canvas // create a frame and canvas
this._create(); this._create();
@ -189,7 +191,7 @@ function Graph (container, data, options) {
this.setData(data,this.constants.clustering.enabled); this.setData(data,this.constants.clustering.enabled);
// zoom so all data will fit on the screen // zoom so all data will fit on the screen
this.zoomToFit();
this.zoomToFit(true);
// if clustering is disabled, the simulation will have started in the setData function // if clustering is disabled, the simulation will have started in the setData function
if (this.constants.clustering.enabled) { if (this.constants.clustering.enabled) {
@ -202,44 +204,87 @@ function Graph (container, data, options) {
* Find the center position of the graph * Find the center position of the graph
* @private * @private
*/ */
Graph.prototype._findCenter = function() {
Graph.prototype._getRange = function() {
var minY = 1e9, maxY = -1e9, minX = 1e9, maxX = -1e9, node; var minY = 1e9, maxY = -1e9, minX = 1e9, maxX = -1e9, node;
for (var i = 0; i < this.nodeIndices.length; i++) { for (var i = 0; i < this.nodeIndices.length; i++) {
node = this.nodes[this.nodeIndices[i]]; node = this.nodes[this.nodeIndices[i]];
if (minX > node.x) {minX = node.x;}
if (maxX < node.x) {maxX = node.x;}
if (minY > node.y) {minY = node.y;}
if (maxY < node.y) {maxY = node.y;}
if (minX > (node.x - node.width)) {minX = node.x - node.width;}
if (maxX < (node.x + node.width)) {maxX = node.x + node.width;}
if (minY > (node.y - node.height)) {minY = node.y - node.height;}
if (maxY < (node.y + node.height)) {maxY = node.y + node.height;}
} }
return {x: (0.5 * (maxX + minX)),
y: (0.5 * (maxY + minY))};
return {minX: minX, maxX: maxX, minY: minY, maxY: maxY};
};
/**
* @param {object} range = {minX: minX, maxX: maxX, minY: minY, maxY: maxY};
* @returns {{x: number, y: number}}
* @private
*/
Graph.prototype._findCenter = function(range) {
var center = {x: (0.5 * (range.maxX + range.minX)),
y: (0.5 * (range.maxY + range.minY))};
return center;
}; };
/** /**
* center the graph * center the graph
*
* @param {object} range = {minX: minX, maxX: maxX, minY: minY, maxY: maxY};
*/ */
Graph.prototype._centerGraph = function() {
var center = this._findCenter();
Graph.prototype._centerGraph = function(range) {
var center = this._findCenter(range);
center.x *= this.scale;
center.y *= this.scale;
center.x -= 0.5 * this.frame.canvas.clientWidth; center.x -= 0.5 * this.frame.canvas.clientWidth;
center.y -= 0.5 * this.frame.canvas.clientHeight; center.y -= 0.5 * this.frame.canvas.clientHeight;
this._setTranslation(-center.x,-center.y);
this._setTranslation(-center.x,-center.y); // set at 0,0
}; };
/** /**
* This function zooms out to fit all data on screen based on amount of nodes
* This function zooms out to fit all data on screen based on amount of nodes
*
* @param {Boolean} [initialZoom] | zoom based on fitted formula or range, true = fitted, default = false;
*/ */
Graph.prototype.zoomToFit = function() {
Graph.prototype.zoomToFit = function(initialZoom) {
if (initialZoom === undefined) {
initialZoom = false;
}
var numberOfNodes = this.nodeIndices.length; var numberOfNodes = this.nodeIndices.length;
var zoomLevel = 46.5 / (numberOfNodes + 20.622); // this is obtained from fitting a dataset from 5 points with scale levels that looked good.
var range = this._getRange();
if (initialZoom == true) {
if (this.constants.clustering.enabled == true &&
numberOfNodes < this.constants.clustering.initialMaxNumberOfNodes) {
var zoomLevel = 38.8467 / (numberOfNodes - 14.50184) + 0.0116360476; // this is obtained from fitting a dataset from 5 points with scale levels that looked good.
}
else {
var zoomLevel = 42.54117319 / (numberOfNodes + 39.31966387) + 0.1944405; // this is obtained from fitting a dataset from 5 points with scale levels that looked good.
}
}
else {
var xDistance = (Math.abs(range.minX) + Math.abs(range.maxX)) * 1.1;
var yDistance = (Math.abs(range.minY) + Math.abs(range.maxY)) * 1.1;
var xZoomLevel = this.frame.canvas.clientWidth / xDistance;
var yZoomLevel = this.frame.canvas.clientHeight / yDistance;
zoomLevel = (xZoomLevel <= yZoomLevel) ? xZoomLevel : yZoomLevel;
}
if (zoomLevel > 1.0) { if (zoomLevel > 1.0) {
zoomLevel = 1.0; zoomLevel = 1.0;
} }
this.pinch.mousewheelScale = zoomLevel; this.pinch.mousewheelScale = zoomLevel;
this._setScale(zoomLevel); this._setScale(zoomLevel);
this._centerGraph();
this._centerGraph(range);
}; };
@ -470,35 +515,35 @@ Graph.prototype._create = function () {
*/ */
Graph.prototype._createKeyBinds = function() { Graph.prototype._createKeyBinds = function() {
var me = this; var me = this;
this.mouseTrap = mouseTrap;
this.mouseTrap.bind("up", this._moveUp.bind(me) , "keydown");
this.mouseTrap.bind("up", this._yStopMoving.bind(me), "keyup");
this.mouseTrap.bind("down", this._moveDown.bind(me) , "keydown");
this.mouseTrap.bind("down", this._yStopMoving.bind(me), "keyup");
this.mouseTrap.bind("left", this._moveLeft.bind(me) , "keydown");
this.mouseTrap.bind("left", this._xStopMoving.bind(me), "keyup");
this.mouseTrap.bind("right",this._moveRight.bind(me), "keydown");
this.mouseTrap.bind("right",this._xStopMoving.bind(me), "keyup");
this.mouseTrap.bind("=",this._zoomIn.bind(me), "keydown");
this.mouseTrap.bind("=",this._stopZoom.bind(me), "keyup");
this.mouseTrap.bind("-",this._zoomOut.bind(me), "keydown");
this.mouseTrap.bind("-",this._stopZoom.bind(me), "keyup");
this.mouseTrap.bind("[",this._zoomIn.bind(me), "keydown");
this.mouseTrap.bind("[",this._stopZoom.bind(me), "keyup");
this.mouseTrap.bind("]",this._zoomOut.bind(me), "keydown");
this.mouseTrap.bind("]",this._stopZoom.bind(me), "keyup");
this.mouseTrap.bind("pageup",this._zoomIn.bind(me), "keydown");
this.mouseTrap.bind("pageup",this._stopZoom.bind(me), "keyup");
this.mouseTrap.bind("pagedown",this._zoomOut.bind(me), "keydown");
this.mouseTrap.bind("pagedown",this._stopZoom.bind(me), "keyup");
this.mouseTrap.bind("u",this._toggleUI.bind(me) , "keydown");
this.mousetrap = mousetrap;
this.mousetrap.bind("up", this._moveUp.bind(me) , "keydown");
this.mousetrap.bind("up", this._yStopMoving.bind(me), "keyup");
this.mousetrap.bind("down", this._moveDown.bind(me) , "keydown");
this.mousetrap.bind("down", this._yStopMoving.bind(me), "keyup");
this.mousetrap.bind("left", this._moveLeft.bind(me) , "keydown");
this.mousetrap.bind("left", this._xStopMoving.bind(me), "keyup");
this.mousetrap.bind("right",this._moveRight.bind(me), "keydown");
this.mousetrap.bind("right",this._xStopMoving.bind(me), "keyup");
this.mousetrap.bind("=",this._zoomIn.bind(me), "keydown");
this.mousetrap.bind("=",this._stopZoom.bind(me), "keyup");
this.mousetrap.bind("-",this._zoomOut.bind(me), "keydown");
this.mousetrap.bind("-",this._stopZoom.bind(me), "keyup");
this.mousetrap.bind("[",this._zoomIn.bind(me), "keydown");
this.mousetrap.bind("[",this._stopZoom.bind(me), "keyup");
this.mousetrap.bind("]",this._zoomOut.bind(me), "keydown");
this.mousetrap.bind("]",this._stopZoom.bind(me), "keyup");
this.mousetrap.bind("pageup",this._zoomIn.bind(me), "keydown");
this.mousetrap.bind("pageup",this._stopZoom.bind(me), "keyup");
this.mousetrap.bind("pagedown",this._zoomOut.bind(me), "keydown");
this.mousetrap.bind("pagedown",this._stopZoom.bind(me), "keyup");
this.mousetrap.bind("u",this._toggleUI.bind(me) , "keydown");
/* /*
this.mouseTrap.bind("=",this.decreaseClusterLevel.bind(me));
this.mouseTrap.bind("-",this.increaseClusterLevel.bind(me));
this.mouseTrap.bind("s",this.singleStep.bind(me));
this.mouseTrap.bind("h",this.updateClustersDefault.bind(me));
this.mouseTrap.bind("c",this._collapseSector.bind(me));
this.mouseTrap.bind("f",this.toggleFreeze.bind(me));
this.mousetrap.bind("=",this.decreaseClusterLevel.bind(me));
this.mousetrap.bind("-",this.increaseClusterLevel.bind(me));
this.mousetrap.bind("s",this.singleStep.bind(me));
this.mousetrap.bind("h",this.updateClustersDefault.bind(me));
this.mousetrap.bind("c",this._collapseSector.bind(me));
this.mousetrap.bind("f",this.toggleFreeze.bind(me));
*/ */
} }
@ -620,7 +665,6 @@ Graph.prototype._onDrag = function (event) {
this.drag.translation.x + diffX, this.drag.translation.x + diffX,
this.drag.translation.y + diffY); this.drag.translation.y + diffY);
this._redraw(); this._redraw();
this.moved = true; this.moved = true;
} }
}; };
@ -731,8 +775,6 @@ Graph.prototype._zoom = function(scale, pointer) {
this.updateClustersDefault(); this.updateClustersDefault();
this._redraw(); this._redraw();
// console.log("current zoomscale:",this.scale);
return scale; return scale;
}; };
@ -1337,10 +1379,10 @@ Graph.prototype._redraw = function() {
ctx.translate(this.translation.x, this.translation.y); ctx.translate(this.translation.x, this.translation.y);
ctx.scale(this.scale, this.scale); ctx.scale(this.scale, this.scale);
this.canvasTopLeft = {"x": (0-this.translation.x)/this.scale,
"y": (0-this.translation.y)/this.scale};
this.canvasBottomRight = {"x": (this.frame.canvas.clientWidth -this.translation.x)/this.scale,
"y": (this.frame.canvas.clientHeight-this.translation.y)/this.scale};
this.canvasTopLeft = {"x": this._canvasToX(0),
"y": this._canvasToY(0)};
this.canvasBottomRight = {"x": this._canvasToX(this.frame.canvas.clientWidth),
"y": this._canvasToY(this.frame.canvas.clientHeight)};
this._doInAllSectors("_drawAllSectorNodes",ctx); this._doInAllSectors("_drawAllSectorNodes",ctx);
this._doInAllSectors("_drawEdges",ctx); this._doInAllSectors("_drawEdges",ctx);
@ -1556,9 +1598,8 @@ Graph.prototype._initializeForceCalculation = function() {
* @private * @private
*/ */
Graph.prototype._calculateForces = function() { Graph.prototype._calculateForces = function() {
var screenCenterPos = {"x":0.5*(this.canvasTopLeft.x + this.canvasBottomRight.x),
"y":0.5*(this.canvasTopLeft.y + this.canvasBottomRight.y)}
var screenCenterPos = {"x":(0.5*(this.canvasTopLeft.x + this.canvasBottomRight.x)),
"y":(0.5*(this.canvasTopLeft.y + this.canvasBottomRight.y))}
// create a local edge to the nodes and edges, that is faster // create a local edge to the nodes and edges, that is faster
var dx, dy, angle, distance, fx, fy, var dx, dy, angle, distance, fx, fy,
repulsingForce, springForce, length, edgeLength, repulsingForce, springForce, length, edgeLength,
@ -1570,7 +1611,7 @@ Graph.prototype._calculateForces = function() {
// Gravity is required to keep separated groups from floating off // Gravity is required to keep separated groups from floating off
// the forces are reset to zero in this loop by using _setForce instead // the forces are reset to zero in this loop by using _setForce instead
// of _addForce // of _addForce
var gravity = 0.3 * this.forceFactor;
var gravity = 0.20 * this.forceFactor;
for (i = 0; i < this.nodeIndices.length; i++) { for (i = 0; i < this.nodeIndices.length; i++) {
node = nodes[this.nodeIndices[i]]; node = nodes[this.nodeIndices[i]];
// gravity does not apply when we are in a pocket sector // gravity does not apply when we are in a pocket sector
@ -1774,7 +1815,7 @@ Graph.prototype._isMoving = function(vmin) {
* @private * @private
*/ */
Graph.prototype._discreteStepNodes = function() { Graph.prototype._discreteStepNodes = function() {
var interval = 0.01;
var interval = 0.010;
var nodes = this.nodes; var nodes = this.nodes;
for (var id in nodes) { for (var id in nodes) {
if (nodes.hasOwnProperty(id)) { if (nodes.hasOwnProperty(id)) {
@ -1799,6 +1840,8 @@ Graph.prototype.start = function() {
if (this.moving) { if (this.moving) {
this._doInAllActiveSectors("_initializeForceCalculation"); this._doInAllActiveSectors("_initializeForceCalculation");
this._doInAllActiveSectors("_discreteStepNodes"); this._doInAllActiveSectors("_discreteStepNodes");
this._findCenter(this._getRange())
} }
if (this.moving || this.xIncrement != 0 || this.yIncrement != 0 || this.zoomIncrement != 0) { if (this.moving || this.xIncrement != 0 || this.yIncrement != 0 || this.zoomIncrement != 0) {
@ -1941,6 +1984,7 @@ Graph.prototype._loadUISystem = function() {
if (this.constants.UI.enabled == true) { if (this.constants.UI.enabled == true) {
this._loadUIElements(); this._loadUIElements();
this._createKeyBinds(); this._createKeyBinds();
} }
} }

+ 5
- 5
src/graph/Node.js View File

@ -75,7 +75,7 @@ function Node(properties, imagelist, grouplist, constants) {
this.vy = 0.0; // velocity y this.vy = 0.0; // velocity y
this.minForce = constants.minForce; this.minForce = constants.minForce;
this.damping = 0.9; this.damping = 0.9;
this.dampingFactor = 60;
this.dampingFactor = 75;
this.graphScaleInv = 1; this.graphScaleInv = 1;
this.canvasTopLeft = {"x": -300, "y": -300}; this.canvasTopLeft = {"x": -300, "y": -300};
@ -901,10 +901,10 @@ Node.prototype.getTextSize = function(ctx) {
*/ */
Node.prototype.inArea = function() { Node.prototype.inArea = function() {
if (this.width !== undefined) { if (this.width !== undefined) {
return (this.x + this.width*0.8 >= this.canvasTopLeft.x &&
this.x - this.width*0.8 < this.canvasBottomRight.x &&
this.y + this.height*0.8 >= this.canvasTopLeft.y &&
this.y - this.height*0.8 < this.canvasBottomRight.y);
return (this.x + this.width*this.graphScaleInv >= this.canvasTopLeft.x &&
this.x - this.width*this.graphScaleInv < this.canvasBottomRight.x &&
this.y + this.height*this.graphScaleInv >= this.canvasTopLeft.y &&
this.y - this.height*this.graphScaleInv < this.canvasBottomRight.y);
} }
else { else {
return true; return true;

+ 32
- 13
src/graph/UIMixin.js View File

@ -49,25 +49,27 @@ var UIMixin = {
this.UIclientWidth = 0; this.UIclientWidth = 0;
this.UIclientHeight = 0; this.UIclientHeight = 0;
} }
var offset = 15;
var intermediateOffset = 7;
var UINodes = [ var UINodes = [
{id: 'UI_up', shape: 'image', image: DIR + 'uparrow.png', triggerFunction: "_moveUp", {id: 'UI_up', shape: 'image', image: DIR + 'uparrow.png', triggerFunction: "_moveUp",
verticalAlignTop: false, x: 52, y: this.UIclientHeight - 52},
verticalAlignTop: false, x: 45 + offset + intermediateOffset, y: this.UIclientHeight - 47 - offset},
{id: 'UI_down', shape: 'image', image: DIR + 'downarrow.png', triggerFunction: "_moveDown", {id: 'UI_down', shape: 'image', image: DIR + 'downarrow.png', triggerFunction: "_moveDown",
verticalAlignTop: false, x: 52, y: this.UIclientHeight - 20},
verticalAlignTop: false, x: 45 + offset + intermediateOffset, y: this.UIclientHeight - 15 - offset},
{id: 'UI_left', shape: 'image', image: DIR + 'leftarrow.png', triggerFunction: "_moveLeft", {id: 'UI_left', shape: 'image', image: DIR + 'leftarrow.png', triggerFunction: "_moveLeft",
verticalAlignTop: false, x: 20, y: this.UIclientHeight - 20},
verticalAlignTop: false, x: 15 + offset, y: this.UIclientHeight - 15 - offset},
{id: 'UI_right', shape: 'image', image: DIR + 'rightarrow.png',triggerFunction: "_moveRight", {id: 'UI_right', shape: 'image', image: DIR + 'rightarrow.png',triggerFunction: "_moveRight",
verticalAlignTop: false, x: 84, y: this.UIclientHeight - 20},
verticalAlignTop: false, x: 75 + offset + 2 * intermediateOffset, y: this.UIclientHeight - 15 - offset},
{id: 'UI_plus', shape: 'image', image: DIR + 'plus.png', triggerFunction: "_zoomIn", {id: 'UI_plus', shape: 'image', image: DIR + 'plus.png', triggerFunction: "_zoomIn",
verticalAlignTop: false, horizontalAlignLeft: false, verticalAlignTop: false, horizontalAlignLeft: false,
x: this.UIclientWidth - 52, y: this.UIclientHeight - 20},
x: this.UIclientWidth - 45 - offset - intermediateOffset, y: this.UIclientHeight - 15 - offset},
{id: 'UI_min', shape: 'image', image: DIR + 'minus.png', triggerFunction: "_zoomOut", {id: 'UI_min', shape: 'image', image: DIR + 'minus.png', triggerFunction: "_zoomOut",
verticalAlignTop: false, horizontalAlignLeft: false, verticalAlignTop: false, horizontalAlignLeft: false,
x: this.UIclientWidth - 20, y: this.UIclientHeight - 20},
x: this.UIclientWidth - 15 - offset, y: this.UIclientHeight - 15 - offset},
{id: 'UI_zoomExtends', shape: 'image', image: DIR + 'zoomExtends.png', triggerFunction: "zoomToFit", {id: 'UI_zoomExtends', shape: 'image', image: DIR + 'zoomExtends.png', triggerFunction: "zoomToFit",
verticalAlignTop: false, horizontalAlignLeft: false, verticalAlignTop: false, horizontalAlignLeft: false,
x: this.UIclientWidth - 20, y: this.UIclientHeight - 52}
x: this.UIclientWidth - 15 - offset, y: this.UIclientHeight - 45 - offset - intermediateOffset}
]; ];
var nodeObj = null; var nodeObj = null;
@ -130,6 +132,17 @@ var UIMixin = {
}, },
_preventDefault : function(event) {
if (event !== undefined) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
}
},
/** /**
* move the screen up * move the screen up
* By using the increments, instead of adding a fixed number to the translation, we keep fluent and * By using the increments, instead of adding a fixed number to the translation, we keep fluent and
@ -138,10 +151,11 @@ var UIMixin = {
* *
* @private * @private
*/ */
_moveUp : function() {
_moveUp : function(event) {
this._highlightUIElement("UI_up"); this._highlightUIElement("UI_up");
this.yIncrement = this.constants.UI.yMovementSpeed; this.yIncrement = this.constants.UI.yMovementSpeed;
this.start(); // if there is no node movement, the calculation wont be done this.start(); // if there is no node movement, the calculation wont be done
this._preventDefault(event);
}, },
@ -149,10 +163,11 @@ var UIMixin = {
* move the screen down * move the screen down
* @private * @private
*/ */
_moveDown : function() {
_moveDown : function(event) {
this._highlightUIElement("UI_down"); this._highlightUIElement("UI_down");
this.yIncrement = -this.constants.UI.yMovementSpeed; this.yIncrement = -this.constants.UI.yMovementSpeed;
this.start(); // if there is no node movement, the calculation wont be done this.start(); // if there is no node movement, the calculation wont be done
this._preventDefault(event);
}, },
@ -160,10 +175,11 @@ var UIMixin = {
* move the screen left * move the screen left
* @private * @private
*/ */
_moveLeft : function() {
_moveLeft : function(event) {
this._highlightUIElement("UI_left"); this._highlightUIElement("UI_left");
this.xIncrement = this.constants.UI.xMovementSpeed; this.xIncrement = this.constants.UI.xMovementSpeed;
this.start(); // if there is no node movement, the calculation wont be done this.start(); // if there is no node movement, the calculation wont be done
this._preventDefault(event);
}, },
@ -171,10 +187,11 @@ var UIMixin = {
* move the screen right * move the screen right
* @private * @private
*/ */
_moveRight : function() {
_moveRight : function(event) {
this._highlightUIElement("UI_right"); this._highlightUIElement("UI_right");
this.xIncrement = -this.constants.UI.xMovementSpeed; this.xIncrement = -this.constants.UI.xMovementSpeed;
this.start(); // if there is no node movement, the calculation wont be done this.start(); // if there is no node movement, the calculation wont be done
this._preventDefault(event);
}, },
@ -182,10 +199,11 @@ var UIMixin = {
* Zoom in, using the same method as the movement. * Zoom in, using the same method as the movement.
* @private * @private
*/ */
_zoomIn : function() {
_zoomIn : function(event) {
this._highlightUIElement("UI_plus"); this._highlightUIElement("UI_plus");
this.zoomIncrement = this.constants.UI.zoomMovementSpeed; this.zoomIncrement = this.constants.UI.zoomMovementSpeed;
this.start(); // if there is no node movement, the calculation wont be done this.start(); // if there is no node movement, the calculation wont be done
this._preventDefault(event);
}, },
@ -197,6 +215,7 @@ var UIMixin = {
this._highlightUIElement("UI_min"); this._highlightUIElement("UI_min");
this.zoomIncrement = -this.constants.UI.zoomMovementSpeed; this.zoomIncrement = -this.constants.UI.zoomMovementSpeed;
this.start(); // if there is no node movement, the calculation wont be done this.start(); // if there is no node movement, the calculation wont be done
this._preventDefault(event);
}, },
@ -236,4 +255,4 @@ var UIMixin = {
} }
};
};

+ 3
- 3
src/module/imports.js View File

@ -18,13 +18,13 @@ else {
} }
} }
var mouseTrap;
var mousetrap;
if (typeof window !== 'undefined') { if (typeof window !== 'undefined') {
// load mousetrap.js only when running in a browser (where window is available) // load mousetrap.js only when running in a browser (where window is available)
mouseTrap = window['mouseTrap'] || require('mouseTrap');
mousetrap = window['mousetrap'] || require('mousetrap');
} }
else { else {
mouseTrap = function () {
mousetrap = function () {
throw Error('mouseTrap is only available in a browser, not in node.js.'); throw Error('mouseTrap is only available in a browser, not in node.js.');
} }
} }

Loading…
Cancel
Save