Browse Source

Merge branch 'develop' into simplified

Conflicts:
	dist/vis.js
css_transitions
jos 10 years ago
parent
commit
c78dce7440
18 changed files with 2163 additions and 1306 deletions
  1. +1
    -0
      .gitignore
  2. +16
    -0
      HISTORY.md
  3. +1
    -1
      README.md
  4. +1
    -1
      bower.json
  5. +1768
    -1171
      dist/vis.js
  6. +1
    -1
      dist/vis.min.css
  7. +11
    -11
      dist/vis.min.js
  8. +138
    -9
      docs/graph.html
  9. +1
    -11
      misc/how_to_publish.md
  10. +1
    -1
      package.json
  11. +5
    -3
      src/graph/Edge.js
  12. +89
    -8
      src/graph/Graph.js
  13. +1
    -1
      src/graph/Groups.js
  14. +5
    -60
      src/graph/Node.js
  15. +40
    -13
      src/graph/Popup.js
  16. +12
    -0
      src/graph/graphMixins/HierarchicalLayoutMixin.js
  17. +15
    -15
      src/graph/graphMixins/ManipulationMixin.js
  18. +57
    -0
      src/util.js

+ 1
- 0
.gitignore View File

@ -1,4 +1,5 @@
.idea .idea
*.iml
node_modules node_modules
.project .project
.settings/.jsdtscope .settings/.jsdtscope

+ 16
- 0
HISTORY.md View File

@ -1,6 +1,22 @@
vis.js history vis.js history
http://visjs.org http://visjs.org
## 2014-04-16, version 0.7.3
### Graph
- fixed color bug.
- added pull requests from kannonboy and vierja: tooltip styling, label fill color
## 2014-04-09, version 0.7.2
### Graph
- fixed edge select bug.
- fixed zoom bug on empty initialization.
## 2014-03-27, version 0.7.1 ## 2014-03-27, version 0.7.1
### Graph ### Graph

+ 1
- 1
README.md View File

@ -143,7 +143,7 @@ Then, the project can be build running:
## Test ## Test
To test teh library, install the project dependencies once:
To test the library, install the project dependencies once:
npm install npm install

+ 1
- 1
bower.json View File

@ -1,6 +1,6 @@
{ {
"name": "vis", "name": "vis",
"version": "0.7.2-SNAPSHOT",
"version": "0.7.4-SNAPSHOT",
"description": "A dynamic, browser-based visualization library.", "description": "A dynamic, browser-based visualization library.",
"homepage": "http://visjs.org/", "homepage": "http://visjs.org/",
"repository": { "repository": {

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


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


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


+ 138
- 9
docs/graph.html View File

@ -60,12 +60,14 @@
<li><a href="#Nodes_configuration">Nodes</a></li> <li><a href="#Nodes_configuration">Nodes</a></li>
<li><a href="#Edges_configuration">Edges</a></li> <li><a href="#Edges_configuration">Edges</a></li>
<li><a href="#Groups_configuration">Groups</a></li> <li><a href="#Groups_configuration">Groups</a></li>
<li><a href="#Physics">Physics</a></li>
<li><a href="#Data_manipulation">Data manipulation</a></li>
<li><a href="#Clustering">Clustering</a></li>
<li><a href="#Physics">Physics</a></li>
<li><a href="#Data_manipulation">Data manipulation</a></li>
<li><a href="#Clustering">Clustering</a></li>
<li><a href="#Navigation_controls">Navigation controls</a></li> <li><a href="#Navigation_controls">Navigation controls</a></li>
<li><a href="#Keyboard_navigation">Keyboard navigation</a></li> <li><a href="#Keyboard_navigation">Keyboard navigation</a></li>
<li><a href="#Hierarchical_layout">Hierarchical layout</a></li> <li><a href="#Hierarchical_layout">Hierarchical layout</a></li>
<li><a href="#Localization">Localization</a></li>
<li><a href="#Tooltips">Tooltips</a></li>
</ul> </ul>
</li> </li>
<li><a href="#Methods">Methods</a></li> <li><a href="#Methods">Methods</a></li>
@ -416,10 +418,11 @@ var nodes = [
<tr> <tr>
<td>title</td> <td>title</td>
<td>string</td>
<td>string | function</td>
<td>no</td> <td>no</td>
<td>Title to be displayed when the user hovers over the node. <td>Title to be displayed when the user hovers over the node.
The title can contain HTML code.</td>
The title can contain HTML code. If using a function, returning <code>undefined</code>
will prevent the tooltip from being displayed.</td>
</tr> </tr>
<tr> <tr>
@ -573,6 +576,14 @@ var edges = [
Only applicable when property <code>label</code> is defined.</td> Only applicable when property <code>label</code> is defined.</td>
</tr> </tr>
<tr>
<td>fontFill</td>
<td>string</td>
<td>no</td>
<td>Font fill for the background color of the text label of the edge.
Only applicable when property <code>label</code> is defined.</td>
</tr>
<tr> <tr>
<td>from</td> <td>from</td>
<td>Number | String</td> <td>Number | String</td>
@ -606,10 +617,11 @@ var edges = [
</tr> </tr>
<tr> <tr>
<td>title</td> <td>title</td>
<td>string</td>
<td>string | function</td>
<td>no</td> <td>no</td>
<td>Title to be displayed when the user hovers over the edge. <td>Title to be displayed when the user hovers over the edge.
The title can contain HTML code.</td>
The title can contain HTML code. If using a function, returning <code>undefined</code>
will prevent the tooltip from being displayed.</td>
</tr> </tr>
<tr> <tr>
@ -1388,7 +1400,7 @@ var options = {
<td>This is the damping constant. It is used to dissipate energy from the system to have it settle in an equilibrium. More information is available <a href="http://en.wikipedia.org/wiki/Damping" target="_blank">here</a>.</td> <td>This is the damping constant. It is used to dissipate energy from the system to have it settle in an equilibrium. More information is available <a href="http://en.wikipedia.org/wiki/Damping" target="_blank">here</a>.</td>
</tr> </tr>
</table> </table>
<h4 id="PhysicsConfiguration">Configuration:</h5>
<h4 id="PhysicsConfiguration">Configuration:</h4>
Every dataset is different. Nodes can have different sizes based on content, interconnectivity can be high or low etc. Because of this, graph has a special option Every dataset is different. Nodes can have different sizes based on content, interconnectivity can be high or low etc. Because of this, graph has a special option
that the user can use to explore which settings may be good for him or her. This is ment to be used during the development phase when you are implementing vis.js. Once you have found that the user can use to explore which settings may be good for him or her. This is ment to be used during the development phase when you are implementing vis.js. Once you have found
settings you are happy with, you can supply them to graph using the physics options as described above. settings you are happy with, you can supply them to graph using the physics options as described above.
@ -1830,9 +1842,126 @@ var options: {
<td>String</td> <td>String</td>
<td>UD</td> <td>UD</td>
<td>This defines the direction the graph is drawn in. The supported directions are: Up-Down (UD), Down-Up (DU), Left-Right (LR) and Right-Left (RL). <td>This defines the direction the graph is drawn in. The supported directions are: Up-Down (UD), Down-Up (DU), Left-Right (LR) and Right-Left (RL).
These need to be supplied by the acronyms in parentheses.</td>
These need to be supplied by the acronyms in parentheses.</td>
</tr> </tr>
</table> </table>
<h3 id="Localization">Localization</h3>
<p>
When using vis.js in other languages, one can use the localization option to overwrite the labels used in the data manipulation interface.
</p>
<pre class="prettyprint">
var options: {
labels:{
add:"Add Node",
edit:"Edit",
link:"Add Link",
delete:"Delete selected",
editNode:"Edit Node",
back:"Back",
addDescription:"Click in an empty space to place a new node.",
linkDescription:"Click on a node and drag the edge to another
node to connect them.",
addError:"The function for add does not support two arguments
(data,callback).",
linkError:"The function for connect does not support two arguments
(data,callback).",
editError:"The function for edit does not support two arguments
(data, callback).",
editBoundError:"No edit function has been bound to this button.",
deleteError:"The function for delete does not support two arguments
(data, callback).",
deleteClusterError:"Clusters cannot be deleted."
}
}
</pre>
<table>
<tr>
<th>Name</th>
<th>Type</th>
<th>Default</th>
<th>Description</th>
</tr>
<tr>
<td>labels</td>
<td>object</td>
<td>(shown above)</td>
<td>Overwrite one or all labels used in the datamanipulation interface with localized strings.
</td>
</tr>
</table>
<h3 id="Tooltips">Tooltips</h3>
<p>
The behaviour and style of the tooltips used to display node and edge title attributes can be customized.
</p>
<pre class="prettyprint">
// tooltip behaviour and style options
var options: {
tooltip: {
delay: 300,
fontColor: "black",
fontSize: 14, // px
fontFace: "verdana",
color: {
border: "#666",
background: "#FFFFC6"
}
}
}
</pre>
<table>
<tr>
<th>Name</th>
<th>Type</th>
<th>Default</th>
<th>Description</th>
</tr>
<tr>
<td>delay</td>
<td>Number</td>
<td>300</td>
<td>Time in milliseconds a user must hover over a node or edge before a tooltip appears.</td>
</tr>
<tr>
<td>fontColor</td>
<td>String</td>
<td>"black"</td>
<td>Default color for tooltip text.</td>
</tr>
<tr>
<td>fontSize</td>
<td>Number</td>
<td>14</td>
<td>Size in pixels of tooltip text.</td>
</tr>
<tr>
<td>fontFace</td>
<td>String</td>
<td>"verdana"</td>
<td>Font family to used for tooltip text.</td>
</tr>
<tr>
<td>color.background</td>
<td>String</td>
<td>"#FFFFC6"</td>
<td>Background color for the node.</td>
</tr>
<tr>
<td>color.border</td>
<td>String</td>
<td>"#666"</td>
<td>Border color for the node.</td>
</tr>
</table>
<h2 id="Methods">Methods</h2> <h2 id="Methods">Methods</h2>
<p> <p>
Graph supports the following methods. Graph supports the following methods.

+ 1
- 11
misc/how_to_publish.md View File

@ -55,17 +55,7 @@ This generates the vis.js library in the folder `./dist`.
Verify if it installs the just released version, and verify if it works. Verify if it installs the just released version, and verify if it works.
- Publish the library at cdnjs.org
- clone the cdnjs project
- pull changes: `git pull upstream`
- add the new version of the library under /ajax/libs/vis/
- add new folder /x.y.z/ with the new library
- update the version number in package.json
- test the library by running `npm test`
- then do a pull request with as title "[author] Update vis.js to x.y.z"
(with correct version).
- Verify within an hour whether vis.js is updated on http://cdnjs.com/
## Update website ## Update website

+ 1
- 1
package.json View File

@ -1,6 +1,6 @@
{ {
"name": "vis", "name": "vis",
"version": "0.7.2-SNAPSHOT",
"version": "0.7.4-SNAPSHOT",
"description": "A dynamic, browser-based visualization library.", "description": "A dynamic, browser-based visualization library.",
"homepage": "http://visjs.org/", "homepage": "http://visjs.org/",
"repository": { "repository": {

+ 5
- 3
src/graph/Edge.js View File

@ -81,10 +81,12 @@ Edge.prototype.setProperties = function(properties, constants) {
this.fontSize = constants.edges.fontSize; this.fontSize = constants.edges.fontSize;
this.fontFace = constants.edges.fontFace; this.fontFace = constants.edges.fontFace;
this.fontColor = constants.edges.fontColor; this.fontColor = constants.edges.fontColor;
this.fontFill = constants.edges.fontFill;
if (properties.fontColor !== undefined) {this.fontColor = properties.fontColor;} if (properties.fontColor !== undefined) {this.fontColor = properties.fontColor;}
if (properties.fontSize !== undefined) {this.fontSize = properties.fontSize;} if (properties.fontSize !== undefined) {this.fontSize = properties.fontSize;}
if (properties.fontFace !== undefined) {this.fontFace = properties.fontFace;} if (properties.fontFace !== undefined) {this.fontFace = properties.fontFace;}
if (properties.fontFill !== undefined) {this.fontFill = properties.fontFill;}
} }
if (properties.title !== undefined) {this.title = properties.title;} if (properties.title !== undefined) {this.title = properties.title;}
@ -175,7 +177,7 @@ Edge.prototype.disconnect = function () {
* has been set. * has been set.
*/ */
Edge.prototype.getTitle = function() { Edge.prototype.getTitle = function() {
return this.title;
return typeof this.title === "function" ? this.title() : this.title;
}; };
@ -216,7 +218,7 @@ Edge.prototype.draw = function(ctx) {
* @return {boolean} True if location is located on the edge * @return {boolean} True if location is located on the edge
*/ */
Edge.prototype.isOverlappingWith = function(obj) { Edge.prototype.isOverlappingWith = function(obj) {
if (this.connected == true) {
if (this.connected) {
var distMax = 10; var distMax = 10;
var xFrom = this.from.x; var xFrom = this.from.x;
var yFrom = this.from.y; var yFrom = this.from.y;
@ -348,7 +350,7 @@ Edge.prototype._label = function (ctx, text, x, y) {
// TODO: cache the calculated size // TODO: cache the calculated size
ctx.font = ((this.from.selected || this.to.selected) ? "bold " : "") + ctx.font = ((this.from.selected || this.to.selected) ? "bold " : "") +
this.fontSize + "px " + this.fontFace; this.fontSize + "px " + this.fontFace;
ctx.fillStyle = 'white';
ctx.fillStyle = this.fontFill;
var width = ctx.measureText(text).width; var width = ctx.measureText(text).width;
var height = this.fontSize; var height = this.fontSize;
var left = x - width / 2; var left = x - width / 2;

+ 89
- 8
src/graph/Graph.js View File

@ -27,6 +27,7 @@ function Graph (container, data, options) {
this.stabilize = true; // stabilize before displaying the graph this.stabilize = true; // stabilize before displaying the graph
this.selectable = true; this.selectable = true;
this.initializing = true;
// these functions are triggered when the dataset is edited // these functions are triggered when the dataset is edited
this.triggerFunctions = {add:null,edit:null,connect:null,delete:null}; this.triggerFunctions = {add:null,edit:null,connect:null,delete:null};
@ -71,6 +72,7 @@ function Graph (container, data, options) {
fontColor: '#343434', fontColor: '#343434',
fontSize: 14, // px fontSize: 14, // px
fontFace: 'arial', fontFace: 'arial',
fontFill: 'white',
dash: { dash: {
length: 10, length: 10,
gap: 5, gap: 5,
@ -150,7 +152,33 @@ function Graph (container, data, options) {
smoothCurves: true, smoothCurves: true,
maxVelocity: 10, maxVelocity: 10,
minVelocity: 0.1, // px/s minVelocity: 0.1, // px/s
stabilizationIterations: 1000 // maximum number of iteration to stabilize
stabilizationIterations: 1000, // maximum number of iteration to stabilize
labels:{
add:"Add Node",
edit:"Edit",
link:"Add Link",
delete:"Delete selected",
editNode:"Edit Node",
back:"Back",
addDescription:"Click in an empty space to place a new node.",
linkDescription:"Click on a node and drag the edge to another node to connect them.",
addError:"The function for add does not support two arguments (data,callback).",
linkError:"The function for connect does not support two arguments (data,callback).",
editError:"The function for edit does not support two arguments (data, callback).",
editBoundError:"No edit function has been bound to this button.",
deleteError:"The function for delete does not support two arguments (data, callback).",
deleteClusterError:"Clusters cannot be deleted."
},
tooltip: {
delay: 300,
fontColor: 'black',
fontSize: 14, // px
fontFace: 'verdana',
color: {
border: '#666',
background: '#FFFFC6'
}
}
}; };
this.editMode = this.constants.dataManipulation.initiallyVisible; this.editMode = this.constants.dataManipulation.initiallyVisible;
@ -245,6 +273,7 @@ function Graph (container, data, options) {
this.setData(data,this.constants.clustering.enabled || this.constants.hierarchicalLayout.enabled); this.setData(data,this.constants.clustering.enabled || this.constants.hierarchicalLayout.enabled);
// hierarchical layout // hierarchical layout
this.initializing = false;
if (this.constants.hierarchicalLayout.enabled == true) { if (this.constants.hierarchicalLayout.enabled == true) {
this._setupHierarchicalLayout(); this._setupHierarchicalLayout();
} }
@ -482,6 +511,16 @@ Graph.prototype.setOptions = function (options) {
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.labels !== undefined) {
for (prop in options.labels) {
if (options.labels.hasOwnProperty(prop)) {
this.constants.labels[prop] = options.labels[prop];
}
}
}
if (options.onAdd) { if (options.onAdd) {
this.triggerFunctions.add = options.onAdd; this.triggerFunctions.add = options.onAdd;
} }
@ -590,6 +629,7 @@ Graph.prototype.setOptions = function (options) {
if (options.edges.color !== undefined) { if (options.edges.color !== undefined) {
if (util.isString(options.edges.color)) { if (util.isString(options.edges.color)) {
this.constants.edges.color = {};
this.constants.edges.color.color = options.edges.color; this.constants.edges.color.color = options.edges.color;
this.constants.edges.color.highlight = options.edges.color; this.constants.edges.color.highlight = options.edges.color;
} }
@ -630,7 +670,7 @@ Graph.prototype.setOptions = function (options) {
} }
if (options.nodes.color) { if (options.nodes.color) {
this.constants.nodes.color = Node.parseColor(options.nodes.color);
this.constants.nodes.color = util.parseColor(options.nodes.color);
} }
/* /*
@ -646,6 +686,17 @@ Graph.prototype.setOptions = function (options) {
} }
} }
} }
if (options.tooltip) {
for (prop in options.tooltip) {
if (options.tooltip.hasOwnProperty(prop)) {
this.constants.tooltip[prop] = options.tooltip[prop];
}
}
if (options.tooltip.color) {
this.constants.tooltip.color = util.parseColor(options.tooltip.color);
}
}
} }
@ -1089,7 +1140,7 @@ Graph.prototype._onMouseMoveTitle = function (event) {
clearInterval(this.popupTimer); // stop any running calculationTimer clearInterval(this.popupTimer); // stop any running calculationTimer
} }
if (!this.drag.dragging) { if (!this.drag.dragging) {
this.popupTimer = setTimeout(checkShow, 300);
this.popupTimer = setTimeout(checkShow, this.constants.tooltip.delay);
} }
}; };
@ -1146,7 +1197,7 @@ Graph.prototype._checkShowPopup = function (pointer) {
if (this.popupNode != lastPopupNode) { if (this.popupNode != lastPopupNode) {
var me = this; var me = this;
if (!me.popup) { if (!me.popup) {
me.popup = new Popup(me.frame);
me.popup = new Popup(me.frame, me.constants.tooltip);
} }
// adjust a small offset such that the mouse cursor is located in the // adjust a small offset such that the mouse cursor is located in the
@ -1279,6 +1330,10 @@ Graph.prototype._addNodes = function(ids) {
this.moving = true; this.moving = true;
} }
this._updateNodeIndexList(); this._updateNodeIndexList();
if (this.constants.hierarchicalLayout.enabled == true && this.initializing == false) {
this._resetLevels();
this._setupHierarchicalLayout();
}
this._updateCalculationNodes(); this._updateCalculationNodes();
this._reconnectEdges(); this._reconnectEdges();
this._updateValueRange(this.nodes); this._updateValueRange(this.nodes);
@ -1328,6 +1383,10 @@ Graph.prototype._removeNodes = function(ids) {
delete nodes[id]; delete nodes[id];
} }
this._updateNodeIndexList(); this._updateNodeIndexList();
if (this.constants.hierarchicalLayout.enabled == true && this.initializing == false) {
this._resetLevels();
this._setupHierarchicalLayout();
}
this._updateCalculationNodes(); this._updateCalculationNodes();
this._reconnectEdges(); this._reconnectEdges();
this._updateSelection(); this._updateSelection();
@ -1406,6 +1465,10 @@ Graph.prototype._addEdges = function (ids) {
this.moving = true; this.moving = true;
this._updateValueRange(edges); this._updateValueRange(edges);
this._createBezierNodes(); this._createBezierNodes();
if (this.constants.hierarchicalLayout.enabled == true && this.initializing == false) {
this._resetLevels();
this._setupHierarchicalLayout();
}
this._updateCalculationNodes(); this._updateCalculationNodes();
}; };
@ -1436,6 +1499,10 @@ Graph.prototype._updateEdges = function (ids) {
} }
this._createBezierNodes(); this._createBezierNodes();
if (this.constants.hierarchicalLayout.enabled == true && this.initializing == false) {
this._resetLevels();
this._setupHierarchicalLayout();
}
this.moving = true; this.moving = true;
this._updateValueRange(edges); this._updateValueRange(edges);
}; };
@ -1461,6 +1528,10 @@ Graph.prototype._removeEdges = function (ids) {
this.moving = true; this.moving = true;
this._updateValueRange(edges); this._updateValueRange(edges);
if (this.constants.hierarchicalLayout.enabled == true && this.initializing == false) {
this._resetLevels();
this._setupHierarchicalLayout();
}
this._updateCalculationNodes(); this._updateCalculationNodes();
}; };
@ -1879,13 +1950,23 @@ if (typeof window !== 'undefined') {
/** /**
* Schedule a animation step with the refreshrate interval. * Schedule a animation step with the refreshrate interval.
*
* @poram {Boolean} runCalculationStep
*/ */
Graph.prototype.start = function() { Graph.prototype.start = function() {
if (this.moving || this.xIncrement != 0 || this.yIncrement != 0 || this.zoomIncrement != 0) { if (this.moving || this.xIncrement != 0 || this.yIncrement != 0 || this.zoomIncrement != 0) {
if (!this.timer) {
this.timer = window.requestAnimationFrame(this._animationStep.bind(this), this.renderTimestep); // wait this.renderTimeStep milliseconds and perform the animation step function
if (!this.timer) {
var ua = navigator.userAgent.toLowerCase();
if (ua.indexOf('safari') != -1) {
if (ua.indexOf('chrome') <= -1) {
// safari
this.timer = window.setTimeout(this._animationStep.bind(this), this.renderTimestep); // wait this.renderTimeStep milliseconds and perform the animation step function
}
else {
this.timer = window.requestAnimationFrame(this._animationStep.bind(this), this.renderTimestep); // wait this.renderTimeStep milliseconds and perform the animation step function
}
}
else{
this.timer = window.requestAnimationFrame(this._animationStep.bind(this), this.renderTimestep); // wait this.renderTimeStep milliseconds and perform the animation step function
}
} }
} }
else { else {

+ 1
- 1
src/graph/Groups.js View File

@ -74,7 +74,7 @@ Groups.prototype.get = function (groupname) {
Groups.prototype.add = function (groupname, style) { Groups.prototype.add = function (groupname, style) {
this.groups[groupname] = style; this.groups[groupname] = style;
if (style.color) { if (style.color) {
style.color = Node.parseColor(style.color);
style.color = util.parseColor(style.color);
} }
return style; return style;
}; };

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

@ -54,6 +54,8 @@ function Node(properties, imagelist, grouplist, constants) {
this.radiusMin = constants.nodes.radiusMin; this.radiusMin = constants.nodes.radiusMin;
this.radiusMax = constants.nodes.radiusMax; this.radiusMax = constants.nodes.radiusMax;
this.level = -1; this.level = -1;
this.preassignedLevel = false;
this.imagelist = imagelist; this.imagelist = imagelist;
this.grouplist = grouplist; this.grouplist = grouplist;
@ -146,7 +148,7 @@ Node.prototype.setProperties = function(properties, constants) {
if (properties.x !== undefined) {this.x = properties.x;} if (properties.x !== undefined) {this.x = properties.x;}
if (properties.y !== undefined) {this.y = properties.y;} if (properties.y !== undefined) {this.y = properties.y;}
if (properties.value !== undefined) {this.value = properties.value;} if (properties.value !== undefined) {this.value = properties.value;}
if (properties.level !== undefined) {this.level = properties.level;}
if (properties.level !== undefined) {this.level = properties.level; this.preassignedLevel = true;}
// physics // physics
@ -175,7 +177,7 @@ Node.prototype.setProperties = function(properties, constants) {
if (properties.shape !== undefined) {this.shape = properties.shape;} if (properties.shape !== undefined) {this.shape = properties.shape;}
if (properties.image !== undefined) {this.image = properties.image;} if (properties.image !== undefined) {this.image = properties.image;}
if (properties.radius !== undefined) {this.radius = properties.radius;} if (properties.radius !== undefined) {this.radius = properties.radius;}
if (properties.color !== undefined) {this.color = Node.parseColor(properties.color);}
if (properties.color !== undefined) {this.color = util.parseColor(properties.color);}
if (properties.fontColor !== undefined) {this.fontColor = properties.fontColor;} if (properties.fontColor !== undefined) {this.fontColor = properties.fontColor;}
if (properties.fontSize !== undefined) {this.fontSize = properties.fontSize;} if (properties.fontSize !== undefined) {this.fontSize = properties.fontSize;}
@ -219,63 +221,6 @@ Node.prototype.setProperties = function(properties, constants) {
this._reset(); this._reset();
}; };
/**
* Parse a color property into an object with border, background, and
* hightlight colors
* @param {Object | String} color
* @return {Object} colorObject
*/
Node.parseColor = function(color) {
var c;
if (util.isString(color)) {
if (util.isValidHex(color)) {
var hsv = util.hexToHSV(color);
var lighterColorHSV = {h:hsv.h,s:hsv.s * 0.45,v:Math.min(1,hsv.v * 1.05)};
var darkerColorHSV = {h:hsv.h,s:Math.min(1,hsv.v * 1.25),v:hsv.v*0.6};
var darkerColorHex = util.HSVToHex(darkerColorHSV.h ,darkerColorHSV.h ,darkerColorHSV.v);
var lighterColorHex = util.HSVToHex(lighterColorHSV.h,lighterColorHSV.s,lighterColorHSV.v);
c = {
background: color,
border:darkerColorHex,
highlight: {
background:lighterColorHex,
border:darkerColorHex
}
};
}
else {
c = {
background:color,
border:color,
highlight: {
background:color,
border:color
}
};
}
}
else {
c = {};
c.background = color.background || 'white';
c.border = color.border || c.background;
if (util.isString(color.highlight)) {
c.highlight = {
border: color.highlight,
background: color.highlight
}
}
else {
c.highlight = {};
c.highlight.background = color.highlight && color.highlight.background || c.background;
c.highlight.border = color.highlight && color.highlight.border || c.border;
}
}
return c;
};
/** /**
* select this node * select this node
*/ */
@ -315,7 +260,7 @@ Node.prototype._reset = function() {
* has been set. * has been set.
*/ */
Node.prototype.getTitle = function() { Node.prototype.getTitle = function() {
return this.title;
return typeof this.title === "function" ? this.title() : this.title;
}; };
/** /**

+ 40
- 13
src/graph/Popup.js View File

@ -4,14 +4,39 @@
* @param {Number} [x] * @param {Number} [x]
* @param {Number} [y] * @param {Number} [y]
* @param {String} [text] * @param {String} [text]
* @param {Object} [style] An object containing borderColor,
* backgroundColor, etc.
*/ */
function Popup(container, x, y, text) {
function Popup(container, x, y, text, style) {
if (container) { if (container) {
this.container = container; this.container = container;
} }
else { else {
this.container = document.body; this.container = document.body;
} }
// x, y and text are optional, see if a style object was passed in their place
if (style === undefined) {
if (typeof x === "object") {
style = x;
x = undefined;
} else if (typeof text === "object") {
style = text;
text = undefined;
} else {
// for backwards compatibility, in case clients other than Graph are creating Popup directly
style = {
fontColor: 'black',
fontSize: 14, // px
fontFace: 'verdana',
color: {
border: '#666',
background: '#FFFFC6'
}
}
}
}
this.x = 0; this.x = 0;
this.y = 0; this.y = 0;
this.padding = 5; this.padding = 5;
@ -25,18 +50,20 @@ function Popup(container, x, y, text) {
// create the frame // create the frame
this.frame = document.createElement("div"); this.frame = document.createElement("div");
var style = this.frame.style;
style.position = "absolute";
style.visibility = "hidden";
style.border = "1px solid #666";
style.color = "black";
style.padding = this.padding + "px";
style.backgroundColor = "#FFFFC6";
style.borderRadius = "3px";
style.MozBorderRadius = "3px";
style.WebkitBorderRadius = "3px";
style.boxShadow = "3px 3px 10px rgba(128, 128, 128, 0.5)";
style.whiteSpace = "nowrap";
var styleAttr = this.frame.style;
styleAttr.position = "absolute";
styleAttr.visibility = "hidden";
styleAttr.border = "1px solid " + style.color.border;
styleAttr.color = style.fontColor;
styleAttr.fontSize = style.fontSize + "px";
styleAttr.fontFamily = style.fontFace;
styleAttr.padding = this.padding + "px";
styleAttr.backgroundColor = style.color.background;
styleAttr.borderRadius = "3px";
styleAttr.MozBorderRadius = "3px";
styleAttr.WebkitBorderRadius = "3px";
styleAttr.boxShadow = "3px 3px 10px rgba(128, 128, 128, 0.5)";
styleAttr.whiteSpace = "nowrap";
this.container.appendChild(this.frame); this.container.appendChild(this.frame);
} }

+ 12
- 0
src/graph/graphMixins/HierarchicalLayoutMixin.js View File

@ -1,6 +1,18 @@
var HierarchicalLayoutMixin = { var HierarchicalLayoutMixin = {
_resetLevels : function() {
for (var nodeId in this.nodes) {
if (this.nodes.hasOwnProperty(nodeId)) {
var node = this.nodes[nodeId];
if (node.preassignedLevel == false) {
node.level = -1;
}
}
}
},
/** /**
* This is the main function to layout the nodes in a hierarchical way. * This is the main function to layout the nodes in a hierarchical way.
* It checks if the node details are supplied correctly * It checks if the node details are supplied correctly

+ 15
- 15
src/graph/graphMixins/ManipulationMixin.js View File

@ -83,21 +83,21 @@ var manipulationMixin = {
// add the icons to the manipulator div // add the icons to the manipulator div
this.manipulationDiv.innerHTML = "" + this.manipulationDiv.innerHTML = "" +
"<span class='graph-manipulationUI add' id='graph-manipulate-addNode'>" + "<span class='graph-manipulationUI add' id='graph-manipulate-addNode'>" +
"<span class='graph-manipulationLabel'>Add Node</span></span>" +
"<span class='graph-manipulationLabel'>"+this.constants.labels['add'] +"</span></span>" +
"<div class='graph-seperatorLine'></div>" + "<div class='graph-seperatorLine'></div>" +
"<span class='graph-manipulationUI connect' id='graph-manipulate-connectNode'>" + "<span class='graph-manipulationUI connect' id='graph-manipulate-connectNode'>" +
"<span class='graph-manipulationLabel'>Add Link</span></span>";
"<span class='graph-manipulationLabel'>"+this.constants.labels['link'] +"</span></span>";
if (this._getSelectedNodeCount() == 1 && this.triggerFunctions.edit) { if (this._getSelectedNodeCount() == 1 && this.triggerFunctions.edit) {
this.manipulationDiv.innerHTML += "" + this.manipulationDiv.innerHTML += "" +
"<div class='graph-seperatorLine'></div>" + "<div class='graph-seperatorLine'></div>" +
"<span class='graph-manipulationUI edit' id='graph-manipulate-editNode'>" + "<span class='graph-manipulationUI edit' id='graph-manipulate-editNode'>" +
"<span class='graph-manipulationLabel'>Edit Node</span></span>";
"<span class='graph-manipulationLabel'>"+this.constants.labels['editNode'] +"</span></span>";
} }
if (this._selectionIsEmpty() == false) { if (this._selectionIsEmpty() == false) {
this.manipulationDiv.innerHTML += "" + this.manipulationDiv.innerHTML += "" +
"<div class='graph-seperatorLine'></div>" + "<div class='graph-seperatorLine'></div>" +
"<span class='graph-manipulationUI delete' id='graph-manipulate-delete'>" + "<span class='graph-manipulationUI delete' id='graph-manipulate-delete'>" +
"<span class='graph-manipulationLabel'>Delete selected</span></span>";
"<span class='graph-manipulationLabel'>"+this.constants.labels['delete'] +"</span></span>";
} }
@ -123,7 +123,7 @@ var manipulationMixin = {
else { else {
this.editModeDiv.innerHTML = "" + this.editModeDiv.innerHTML = "" +
"<span class='graph-manipulationUI edit editmode' id='graph-manipulate-editModeButton'>" + "<span class='graph-manipulationUI edit editmode' id='graph-manipulate-editModeButton'>" +
"<span class='graph-manipulationLabel'>Edit</span></span>"
"<span class='graph-manipulationLabel'>"+this.constants.labels['edit'] +"</span></span>"
var editModeButton = document.getElementById("graph-manipulate-editModeButton"); var editModeButton = document.getElementById("graph-manipulate-editModeButton");
editModeButton.onclick = this._toggleEditMode.bind(this); editModeButton.onclick = this._toggleEditMode.bind(this);
} }
@ -146,10 +146,10 @@ var manipulationMixin = {
// create the toolbar contents // create the toolbar contents
this.manipulationDiv.innerHTML = "" + this.manipulationDiv.innerHTML = "" +
"<span class='graph-manipulationUI back' id='graph-manipulate-back'>" + "<span class='graph-manipulationUI back' id='graph-manipulate-back'>" +
"<span class='graph-manipulationLabel'>Back</span></span>" +
"<span class='graph-manipulationLabel'>" + this.constants.labels['back'] + " </span></span>" +
"<div class='graph-seperatorLine'></div>" + "<div class='graph-seperatorLine'></div>" +
"<span class='graph-manipulationUI none' id='graph-manipulate-back'>" + "<span class='graph-manipulationUI none' id='graph-manipulate-back'>" +
"<span class='graph-manipulationLabel'>Click in an empty space to place a new node</span></span>";
"<span id='graph-manipulatorLabel' class='graph-manipulationLabel'>" + this.constants.labels['addDescription'] + "</span></span>";
// bind the icon // bind the icon
var backButton = document.getElementById("graph-manipulate-back"); var backButton = document.getElementById("graph-manipulate-back");
@ -182,10 +182,10 @@ var manipulationMixin = {
this.manipulationDiv.innerHTML = "" + this.manipulationDiv.innerHTML = "" +
"<span class='graph-manipulationUI back' id='graph-manipulate-back'>" + "<span class='graph-manipulationUI back' id='graph-manipulate-back'>" +
"<span class='graph-manipulationLabel'>Back</span></span>" +
"<span class='graph-manipulationLabel'>" + this.constants.labels['back'] + " </span></span>" +
"<div class='graph-seperatorLine'></div>" + "<div class='graph-seperatorLine'></div>" +
"<span class='graph-manipulationUI none' id='graph-manipulate-back'>" + "<span class='graph-manipulationUI none' id='graph-manipulate-back'>" +
"<span id='graph-manipulatorLabel' class='graph-manipulationLabel'>Click on a node and drag the edge to another node to connect them.</span></span>";
"<span id='graph-manipulatorLabel' class='graph-manipulationLabel'>" + this.constants.labels['linkDescription'] + "</span></span>";
// bind the icon // bind the icon
var backButton = document.getElementById("graph-manipulate-back"); var backButton = document.getElementById("graph-manipulate-back");
@ -306,7 +306,7 @@ var manipulationMixin = {
}); });
} }
else { else {
alert("The function for add does not support two arguments (data,callback).");
alert(this.constants.labels['addError']);
this._createManipulatorBar(); this._createManipulatorBar();
this.moving = true; this.moving = true;
this.start(); this.start();
@ -340,7 +340,7 @@ var manipulationMixin = {
}); });
} }
else { else {
alert("The function for connect does not support two arguments (data,callback).");
alert(this.constants.labels["linkError"]);
this.moving = true; this.moving = true;
this.start(); this.start();
} }
@ -384,11 +384,11 @@ var manipulationMixin = {
}); });
} }
else { else {
alert("The function for edit does not support two arguments (data, callback).")
alert(this.constants.labels["editError"]);
} }
} }
else { else {
alert("No edit function has been bound to this button.")
alert(this.constants.labels["editBoundError"]);
} }
}, },
@ -416,7 +416,7 @@ var manipulationMixin = {
}); });
} }
else { else {
alert("The function for edit does not support two arguments (data, callback).")
alert(this.constants.labels["deleteError"])
} }
} }
else { else {
@ -428,7 +428,7 @@ var manipulationMixin = {
} }
} }
else { else {
alert("Clusters cannot be deleted.");
alert(this.constants.labels["deleteClusterError"]);
} }
} }
} }

+ 57
- 0
src/util.js View File

@ -722,6 +722,63 @@ util.GiveHex = function GiveHex(Dec) {
return Value; return Value;
}; };
/**
* Parse a color property into an object with border, background, and
* highlight colors
* @param {Object | String} color
* @return {Object} colorObject
*/
util.parseColor = function(color) {
var c;
if (util.isString(color)) {
if (util.isValidHex(color)) {
var hsv = util.hexToHSV(color);
var lighterColorHSV = {h:hsv.h,s:hsv.s * 0.45,v:Math.min(1,hsv.v * 1.05)};
var darkerColorHSV = {h:hsv.h,s:Math.min(1,hsv.v * 1.25),v:hsv.v*0.6};
var darkerColorHex = util.HSVToHex(darkerColorHSV.h ,darkerColorHSV.h ,darkerColorHSV.v);
var lighterColorHex = util.HSVToHex(lighterColorHSV.h,lighterColorHSV.s,lighterColorHSV.v);
c = {
background: color,
border:darkerColorHex,
highlight: {
background:lighterColorHex,
border:darkerColorHex
}
};
}
else {
c = {
background:color,
border:color,
highlight: {
background:color,
border:color
}
};
}
}
else {
c = {};
c.background = color.background || 'white';
c.border = color.border || c.background;
if (util.isString(color.highlight)) {
c.highlight = {
border: color.highlight,
background: color.highlight
}
}
else {
c.highlight = {};
c.highlight.background = color.highlight && color.highlight.background || c.background;
c.highlight.border = color.highlight && color.highlight.border || c.border;
}
}
return c;
};
/** /**
* http://www.yellowpipe.com/yis/tools/hex-to-rgb/color-converter.php * http://www.yellowpipe.com/yis/tools/hex-to-rgb/color-converter.php
* *

Loading…
Cancel
Save