Browse Source

Merge branch 'develop' into linegraph

Conflicts:
	dist/vis.js
	dist/vis.min.js
css_transitions
Alex de Mulder 10 years ago
parent
commit
29fdab8699
8 changed files with 196 additions and 123 deletions
  1. +11
    -0
      HISTORY.md
  2. +81
    -58
      dist/vis.js
  3. +8
    -8
      dist/vis.min.js
  4. +16
    -0
      docs/graph.html
  5. +51
    -42
      src/graph/Graph.js
  6. +12
    -10
      src/graph/graphMixins/physics/PhysicsMixin.js
  7. +14
    -2
      src/timeline/TimeStep.js
  8. +3
    -3
      src/timeline/component/ItemSet.js

+ 11
- 0
HISTORY.md View File

@ -1,6 +1,17 @@
# vis.js history # vis.js history
http://visjs.org http://visjs.org
## not yet released, version 1.0.2
### Timeline
- Some tweaks in snapping dragged items to nice dates.
- Fixed a bug in replacing the DataSet of groups via `Timeline.setGroups(groups)`.
### Graph
- added zoomable and moveable options.
- changes setOptions to avoid resetting view.
## 2014-05-09, version 1.0.1 ## 2014-05-09, version 1.0.1

+ 81
- 58
dist/vis.js View File

@ -5,7 +5,7 @@
* A dynamic, browser-based visualization library. * A dynamic, browser-based visualization library.
* *
* @version 1.0.2-SNAPSHOT * @version 1.0.2-SNAPSHOT
* @date 2014-05-13
* @date 2014-05-26
* *
* @license * @license
* Copyright (C) 2011-2014 Almende B.V, http://almende.com * Copyright (C) 2011-2014 Almende B.V, http://almende.com
@ -2885,8 +2885,7 @@ TimeStep.prototype.snap = function(date) {
clone.setSeconds(0); clone.setSeconds(0);
clone.setMilliseconds(0); clone.setMilliseconds(0);
} }
else if (this.scale == TimeStep.SCALE.DAY ||
this.scale == TimeStep.SCALE.WEEKDAY) {
else if (this.scale == TimeStep.SCALE.DAY) {
//noinspection FallthroughInSwitchStatementJS //noinspection FallthroughInSwitchStatementJS
switch (this.step) { switch (this.step) {
case 5: case 5:
@ -2899,6 +2898,19 @@ TimeStep.prototype.snap = function(date) {
clone.setSeconds(0); clone.setSeconds(0);
clone.setMilliseconds(0); clone.setMilliseconds(0);
} }
else if (this.scale == TimeStep.SCALE.WEEKDAY) {
//noinspection FallthroughInSwitchStatementJS
switch (this.step) {
case 5:
case 2:
clone.setHours(Math.round(clone.getHours() / 12) * 12); break;
default:
clone.setHours(Math.round(clone.getHours() / 6) * 6); break;
}
clone.setMinutes(0);
clone.setSeconds(0);
clone.setMilliseconds(0);
}
else if (this.scale == TimeStep.SCALE.HOUR) { else if (this.scale == TimeStep.SCALE.HOUR) {
switch (this.step) { switch (this.step) {
case 4: case 4:
@ -5564,7 +5576,8 @@ ItemSet.prototype.setGroups = function setGroups(groups) {
// remove all drawn groups // remove all drawn groups
ids = this.groupsData.getIds(); ids = this.groupsData.getIds();
this._onRemoveGroups(ids);
this.groupsData = null;
this._onRemoveGroups(ids); // note: this will cause a repaint
} }
// replace the dataset // replace the dataset
@ -5815,8 +5828,7 @@ ItemSet.prototype._orderGroups = function () {
// hide all groups, removes them from the DOM // hide all groups, removes them from the DOM
var groups = this.groups; var groups = this.groups;
groupIds.forEach(function (groupId) { groupIds.forEach(function (groupId) {
var group = groups[groupId];
group.hide();
groups[groupId].hide();
}); });
// show the groups again, attach them to the DOM in correct order // show the groups again, attach them to the DOM in correct order
@ -11474,7 +11486,7 @@ var physicsMixin = {
*/ */
_calculateSpringForces: function () { _calculateSpringForces: function () {
var edgeLength, edge, edgeId; var edgeLength, edge, edgeId;
var dx, dy, fx, fy, springForce, length;
var dx, dy, fx, fy, springForce, distance;
var edges = this.edges; var edges = this.edges;
// forces caused by the edges, modelled as springs // forces caused by the edges, modelled as springs
@ -11490,13 +11502,14 @@ var physicsMixin = {
dx = (edge.from.x - edge.to.x); dx = (edge.from.x - edge.to.x);
dy = (edge.from.y - edge.to.y); dy = (edge.from.y - edge.to.y);
length = Math.sqrt(dx * dx + dy * dy);
distance = Math.sqrt(dx * dx + dy * dy);
if (length == 0) {
length = 0.01;
if (distance == 0) {
distance = 0.01;
} }
springForce = this.constants.physics.springConstant * (edgeLength - length) / length;
// the 1/distance is so the fx and fy can be calculated without sine or cosine.
springForce = this.constants.physics.springConstant * (edgeLength - distance) / distance;
fx = dx * springForce; fx = dx * springForce;
fy = dy * springForce; fy = dy * springForce;
@ -11558,17 +11571,18 @@ var physicsMixin = {
* @private * @private
*/ */
_calculateSpringForce: function (node1, node2, edgeLength) { _calculateSpringForce: function (node1, node2, edgeLength) {
var dx, dy, fx, fy, springForce, length;
var dx, dy, fx, fy, springForce, distance;
dx = (node1.x - node2.x); dx = (node1.x - node2.x);
dy = (node1.y - node2.y); dy = (node1.y - node2.y);
length = Math.sqrt(dx * dx + dy * dy);
distance = Math.sqrt(dx * dx + dy * dy);
if (length == 0) {
length = 0.01;
if (distance == 0) {
distance = 0.01;
} }
springForce = this.constants.physics.springConstant * (edgeLength - length) / length;
// the 1/distance is so the fx and fy can be calculated without sine or cosine.
springForce = this.constants.physics.springConstant * (edgeLength - distance) / distance;
fx = dx * springForce; fx = dx * springForce;
fy = dy * springForce; fy = dy * springForce;
@ -16106,7 +16120,9 @@ function Graph (container, data, options) {
border: '#666', border: '#666',
background: '#FFFFC6' background: '#FFFFC6'
} }
}
},
moveable: true,
zoomable: true
}; };
this.editMode = this.constants.dataManipulation.initiallyVisible; this.editMode = this.constants.dataManipulation.initiallyVisible;
@ -16138,8 +16154,11 @@ function Graph (container, data, options) {
this._loadHierarchySystem(); this._loadHierarchySystem();
// apply options // apply options
this._setTranslation(this.frame.clientWidth / 2, this.frame.clientHeight / 2);
this._setScale(1);
this.setOptions(options); this.setOptions(options);
// other vars // other vars
this.freezeSimulation = false;// freeze the simulation this.freezeSimulation = false;// freeze the simulation
this.cachedFunctions = {}; this.cachedFunctions = {};
@ -16429,6 +16448,7 @@ Graph.prototype.setData = function(data, disableStart) {
/** /**
* Set options * Set options
* @param {Object} options * @param {Object} options
* @param {Boolean} [initializeView] | set zoom and translation to default.
*/ */
Graph.prototype.setOptions = function (options) { Graph.prototype.setOptions = function (options) {
if (options) { if (options) {
@ -16442,7 +16462,8 @@ Graph.prototype.setOptions = function (options) {
if (options.freezeForStabilization !== undefined) {this.constants.freezeForStabilization = options.freezeForStabilization;} if (options.freezeForStabilization !== undefined) {this.constants.freezeForStabilization = options.freezeForStabilization;}
if (options.configurePhysics !== undefined){this.constants.configurePhysics = options.configurePhysics;} if (options.configurePhysics !== undefined){this.constants.configurePhysics = options.configurePhysics;}
if (options.stabilizationIterations !== undefined) {this.constants.stabilizationIterations = options.stabilizationIterations;} if (options.stabilizationIterations !== undefined) {this.constants.stabilizationIterations = options.stabilizationIterations;}
if (options.moveable !== undefined) {this.constants.moveable = options.moveable;}
if (options.zoomable !== undefined) {this.constants.zoomable = options.zoomable;}
if (options.labels !== undefined) { if (options.labels !== undefined) {
@ -16657,11 +16678,10 @@ Graph.prototype.setOptions = function (options) {
// bind keys. If disabled, this will not do anything; // bind keys. If disabled, this will not do anything;
this._createKeyBinds(); this._createKeyBinds();
this.setSize(this.width, this.height); this.setSize(this.width, this.height);
this._setTranslation(this.frame.clientWidth / 2, this.frame.clientHeight / 2);
this._setScale(1);
this._redraw();
this.moving = true;
this.start();
}; };
/** /**
@ -16892,16 +16912,18 @@ Graph.prototype._handleOnDrag = function(event) {
} }
} }
else { else {
// move the graph
var diffX = pointer.x - this.drag.pointer.x;
var diffY = pointer.y - this.drag.pointer.y;
this._setTranslation(
this.drag.translation.x + diffX,
this.drag.translation.y + diffY);
this._redraw();
this.moving = true;
this.start();
if (this.constants.moveable == true) {
// move the graph
var diffX = pointer.x - this.drag.pointer.x;
var diffY = pointer.y - this.drag.pointer.y;
this._setTranslation(
this.drag.translation.x + diffX,
this.drag.translation.y + diffY);
this._redraw();
this.moving = true;
this.start();
}
} }
}; };
@ -16989,37 +17011,38 @@ Graph.prototype._onPinch = function (event) {
* @private * @private
*/ */
Graph.prototype._zoom = function(scale, pointer) { Graph.prototype._zoom = function(scale, pointer) {
var scaleOld = this._getScale();
if (scale < 0.00001) {
scale = 0.00001;
}
if (scale > 10) {
scale = 10;
}
// + this.frame.canvas.clientHeight / 2
var translation = this._getTranslation();
var scaleFrac = scale / scaleOld;
var tx = (1 - scaleFrac) * pointer.x + translation.x * scaleFrac;
var ty = (1 - scaleFrac) * pointer.y + translation.y * scaleFrac;
if (this.constants.zoomable == true) {
var scaleOld = this._getScale();
if (scale < 0.00001) {
scale = 0.00001;
}
if (scale > 10) {
scale = 10;
}
// + this.frame.canvas.clientHeight / 2
var translation = this._getTranslation();
this.areaCenter = {"x" : this._canvasToX(pointer.x),
"y" : this._canvasToY(pointer.y)};
var scaleFrac = scale / scaleOld;
var tx = (1 - scaleFrac) * pointer.x + translation.x * scaleFrac;
var ty = (1 - scaleFrac) * pointer.y + translation.y * scaleFrac;
this._setScale(scale);
this._setTranslation(tx, ty);
this.updateClustersDefault();
this._redraw();
this.areaCenter = {"x" : this._canvasToX(pointer.x),
"y" : this._canvasToY(pointer.y)};
if (scaleOld < scale) {
this.emit("zoom", {direction:"+"});
}
else {
this.emit("zoom", {direction:"-"});
}
this._setScale(scale);
this._setTranslation(tx, ty);
this.updateClustersDefault();
this._redraw();
if (scaleOld < scale) {
this.emit("zoom", {direction:"+"});
}
else {
this.emit("zoom", {direction:"-"});
}
return scale;
return scale;
}
}; };

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


+ 16
- 0
docs/graph.html View File

@ -798,6 +798,14 @@ var options = {
Configuration options for shortcuts keys. Sortcut keys are turned off by default. See section <a href="#Keyboard_navigation">Keyboard navigation</a> for an overview of the available options. Configuration options for shortcuts keys. Sortcut keys are turned off by default. See section <a href="#Keyboard_navigation">Keyboard navigation</a> for an overview of the available options.
</td> </td>
</tr> </tr>
<tr>
<td>moveable</td>
<td>Boolean</td>
<td>true</td>
<td>
Toggle if the graph can be dragged. This will not affect the dragging of nodes.
</td>
</tr>
<tr> <tr>
<td><a href="#Navigation_controls">navigation</a></td> <td><a href="#Navigation_controls">navigation</a></td>
@ -854,6 +862,14 @@ var options = {
<td>"400px"</td> <td>"400px"</td>
<td>The width of the graph in pixels or as a percentage.</td> <td>The width of the graph in pixels or as a percentage.</td>
</tr> </tr>
<tr>
<td>zoomable</td>
<td>Boolean</td>
<td>true</td>
<td>
Toggle if the graph can be zoomed.
</td>
</tr>
</table> </table>

+ 51
- 42
src/graph/Graph.js View File

@ -179,7 +179,9 @@ function Graph (container, data, options) {
border: '#666', border: '#666',
background: '#FFFFC6' background: '#FFFFC6'
} }
}
},
moveable: true,
zoomable: true
}; };
this.editMode = this.constants.dataManipulation.initiallyVisible; this.editMode = this.constants.dataManipulation.initiallyVisible;
@ -211,8 +213,11 @@ function Graph (container, data, options) {
this._loadHierarchySystem(); this._loadHierarchySystem();
// apply options // apply options
this._setTranslation(this.frame.clientWidth / 2, this.frame.clientHeight / 2);
this._setScale(1);
this.setOptions(options); this.setOptions(options);
// other vars // other vars
this.freezeSimulation = false;// freeze the simulation this.freezeSimulation = false;// freeze the simulation
this.cachedFunctions = {}; this.cachedFunctions = {};
@ -502,6 +507,7 @@ Graph.prototype.setData = function(data, disableStart) {
/** /**
* Set options * Set options
* @param {Object} options * @param {Object} options
* @param {Boolean} [initializeView] | set zoom and translation to default.
*/ */
Graph.prototype.setOptions = function (options) { Graph.prototype.setOptions = function (options) {
if (options) { if (options) {
@ -515,7 +521,8 @@ Graph.prototype.setOptions = function (options) {
if (options.freezeForStabilization !== undefined) {this.constants.freezeForStabilization = options.freezeForStabilization;} if (options.freezeForStabilization !== undefined) {this.constants.freezeForStabilization = options.freezeForStabilization;}
if (options.configurePhysics !== undefined){this.constants.configurePhysics = options.configurePhysics;} if (options.configurePhysics !== undefined){this.constants.configurePhysics = options.configurePhysics;}
if (options.stabilizationIterations !== undefined) {this.constants.stabilizationIterations = options.stabilizationIterations;} if (options.stabilizationIterations !== undefined) {this.constants.stabilizationIterations = options.stabilizationIterations;}
if (options.moveable !== undefined) {this.constants.moveable = options.moveable;}
if (options.zoomable !== undefined) {this.constants.zoomable = options.zoomable;}
if (options.labels !== undefined) { if (options.labels !== undefined) {
@ -730,11 +737,10 @@ Graph.prototype.setOptions = function (options) {
// bind keys. If disabled, this will not do anything; // bind keys. If disabled, this will not do anything;
this._createKeyBinds(); this._createKeyBinds();
this.setSize(this.width, this.height); this.setSize(this.width, this.height);
this._setTranslation(this.frame.clientWidth / 2, this.frame.clientHeight / 2);
this._setScale(1);
this._redraw();
this.moving = true;
this.start();
}; };
/** /**
@ -965,16 +971,18 @@ Graph.prototype._handleOnDrag = function(event) {
} }
} }
else { else {
// move the graph
var diffX = pointer.x - this.drag.pointer.x;
var diffY = pointer.y - this.drag.pointer.y;
this._setTranslation(
this.drag.translation.x + diffX,
this.drag.translation.y + diffY);
this._redraw();
this.moving = true;
this.start();
if (this.constants.moveable == true) {
// move the graph
var diffX = pointer.x - this.drag.pointer.x;
var diffY = pointer.y - this.drag.pointer.y;
this._setTranslation(
this.drag.translation.x + diffX,
this.drag.translation.y + diffY);
this._redraw();
this.moving = true;
this.start();
}
} }
}; };
@ -1062,37 +1070,38 @@ Graph.prototype._onPinch = function (event) {
* @private * @private
*/ */
Graph.prototype._zoom = function(scale, pointer) { Graph.prototype._zoom = function(scale, pointer) {
var scaleOld = this._getScale();
if (scale < 0.00001) {
scale = 0.00001;
}
if (scale > 10) {
scale = 10;
}
// + this.frame.canvas.clientHeight / 2
var translation = this._getTranslation();
var scaleFrac = scale / scaleOld;
var tx = (1 - scaleFrac) * pointer.x + translation.x * scaleFrac;
var ty = (1 - scaleFrac) * pointer.y + translation.y * scaleFrac;
if (this.constants.zoomable == true) {
var scaleOld = this._getScale();
if (scale < 0.00001) {
scale = 0.00001;
}
if (scale > 10) {
scale = 10;
}
// + this.frame.canvas.clientHeight / 2
var translation = this._getTranslation();
this.areaCenter = {"x" : this._canvasToX(pointer.x),
"y" : this._canvasToY(pointer.y)};
var scaleFrac = scale / scaleOld;
var tx = (1 - scaleFrac) * pointer.x + translation.x * scaleFrac;
var ty = (1 - scaleFrac) * pointer.y + translation.y * scaleFrac;
this._setScale(scale);
this._setTranslation(tx, ty);
this.updateClustersDefault();
this._redraw();
this.areaCenter = {"x" : this._canvasToX(pointer.x),
"y" : this._canvasToY(pointer.y)};
if (scaleOld < scale) {
this.emit("zoom", {direction:"+"});
}
else {
this.emit("zoom", {direction:"-"});
}
this._setScale(scale);
this._setTranslation(tx, ty);
this.updateClustersDefault();
this._redraw();
if (scaleOld < scale) {
this.emit("zoom", {direction:"+"});
}
else {
this.emit("zoom", {direction:"-"});
}
return scale;
return scale;
}
}; };

+ 12
- 10
src/graph/graphMixins/physics/PhysicsMixin.js View File

@ -188,7 +188,7 @@ var physicsMixin = {
*/ */
_calculateSpringForces: function () { _calculateSpringForces: function () {
var edgeLength, edge, edgeId; var edgeLength, edge, edgeId;
var dx, dy, fx, fy, springForce, length;
var dx, dy, fx, fy, springForce, distance;
var edges = this.edges; var edges = this.edges;
// forces caused by the edges, modelled as springs // forces caused by the edges, modelled as springs
@ -204,13 +204,14 @@ var physicsMixin = {
dx = (edge.from.x - edge.to.x); dx = (edge.from.x - edge.to.x);
dy = (edge.from.y - edge.to.y); dy = (edge.from.y - edge.to.y);
length = Math.sqrt(dx * dx + dy * dy);
distance = Math.sqrt(dx * dx + dy * dy);
if (length == 0) {
length = 0.01;
if (distance == 0) {
distance = 0.01;
} }
springForce = this.constants.physics.springConstant * (edgeLength - length) / length;
// the 1/distance is so the fx and fy can be calculated without sine or cosine.
springForce = this.constants.physics.springConstant * (edgeLength - distance) / distance;
fx = dx * springForce; fx = dx * springForce;
fy = dy * springForce; fy = dy * springForce;
@ -272,17 +273,18 @@ var physicsMixin = {
* @private * @private
*/ */
_calculateSpringForce: function (node1, node2, edgeLength) { _calculateSpringForce: function (node1, node2, edgeLength) {
var dx, dy, fx, fy, springForce, length;
var dx, dy, fx, fy, springForce, distance;
dx = (node1.x - node2.x); dx = (node1.x - node2.x);
dy = (node1.y - node2.y); dy = (node1.y - node2.y);
length = Math.sqrt(dx * dx + dy * dy);
distance = Math.sqrt(dx * dx + dy * dy);
if (length == 0) {
length = 0.01;
if (distance == 0) {
distance = 0.01;
} }
springForce = this.constants.physics.springConstant * (edgeLength - length) / length;
// the 1/distance is so the fx and fy can be calculated without sine or cosine.
springForce = this.constants.physics.springConstant * (edgeLength - distance) / distance;
fx = dx * springForce; fx = dx * springForce;
fy = dy * springForce; fy = dy * springForce;

+ 14
- 2
src/timeline/TimeStep.js View File

@ -314,8 +314,7 @@ TimeStep.prototype.snap = function(date) {
clone.setSeconds(0); clone.setSeconds(0);
clone.setMilliseconds(0); clone.setMilliseconds(0);
} }
else if (this.scale == TimeStep.SCALE.DAY ||
this.scale == TimeStep.SCALE.WEEKDAY) {
else if (this.scale == TimeStep.SCALE.DAY) {
//noinspection FallthroughInSwitchStatementJS //noinspection FallthroughInSwitchStatementJS
switch (this.step) { switch (this.step) {
case 5: case 5:
@ -328,6 +327,19 @@ TimeStep.prototype.snap = function(date) {
clone.setSeconds(0); clone.setSeconds(0);
clone.setMilliseconds(0); clone.setMilliseconds(0);
} }
else if (this.scale == TimeStep.SCALE.WEEKDAY) {
//noinspection FallthroughInSwitchStatementJS
switch (this.step) {
case 5:
case 2:
clone.setHours(Math.round(clone.getHours() / 12) * 12); break;
default:
clone.setHours(Math.round(clone.getHours() / 6) * 6); break;
}
clone.setMinutes(0);
clone.setSeconds(0);
clone.setMilliseconds(0);
}
else if (this.scale == TimeStep.SCALE.HOUR) { else if (this.scale == TimeStep.SCALE.HOUR) {
switch (this.step) { switch (this.step) {
case 4: case 4:

+ 3
- 3
src/timeline/component/ItemSet.js View File

@ -519,7 +519,8 @@ ItemSet.prototype.setGroups = function setGroups(groups) {
// remove all drawn groups // remove all drawn groups
ids = this.groupsData.getIds(); ids = this.groupsData.getIds();
this._onRemoveGroups(ids);
this.groupsData = null;
this._onRemoveGroups(ids); // note: this will cause a repaint
} }
// replace the dataset // replace the dataset
@ -770,8 +771,7 @@ ItemSet.prototype._orderGroups = function () {
// hide all groups, removes them from the DOM // hide all groups, removes them from the DOM
var groups = this.groups; var groups = this.groups;
groupIds.forEach(function (groupId) { groupIds.forEach(function (groupId) {
var group = groups[groupId];
group.hide();
groups[groupId].hide();
}); });
// show the groups again, attach them to the DOM in correct order // show the groups again, attach them to the DOM in correct order

Loading…
Cancel
Save