Permalink
Browse files

New tutorial: Showing how to display two edges connecting the same no…

…des.
  • Loading branch information...
1 parent bdf7329 commit e6d2602d012b91fb869c5b70ff1d98a288b51281 @anvaka committed Sep 23, 2012
Showing with 181 additions and 3 deletions.
  1. +47 −0 demos/tutorial_svg/07 - Show Dual Links.html
  2. +133 −2 dist/vivagraph.js
  3. +1 −1 dist/vivagraph.min.js
View
47 demos/tutorial_svg/07 - Show Dual Links.html
@@ -0,0 +1,47 @@
+<html>
+<head>
+ <title>Dual Connected Links Demo</title>
+ <script type="text/javascript" src='../../dist/vivagraph.js'></script>
+ <script type="text/javascript">
+ function main() {
+ var graph = Viva.Graph.graph(),
+ graphics = Viva.Graph.View.svgGraphics(),
+ renderer = Viva.Graph.View.renderer(graph, {
+ graphics: graphics
+ });
+
+ graph.addLink(1, 2, 'Buy');
+ graph.addLink(1, 2, 'Sell');
+
+ graphics.link(function(link){
+ var isBuy = (link.data === 'Buy'),
+ ui = Viva.Graph.svg('path')
+ .attr('stroke', isBuy ? 'red' : 'blue')
+ .attr('fill', 'none');
+
+ ui.isBuy = isBuy; // remember for future.
+
+ return ui;
+ }).placeLink(function(linkUI, fromPos, toPos) {
+ // linkUI - is the object returend from link() callback above.
+ var ry = linkUI.isBuy ? 10 : 0,
+ // using arc command: http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands
+ data = 'M' + fromPos.x + ',' + fromPos.y +
+ ' A 10,' + ry + ',-30,0,1,' + toPos.x + ',' + toPos.y;
+
+ // 'Path data' (http://www.w3.org/TR/SVG/paths.html#DAttribute )
+ // is a common way of rendering paths in SVG:
+ linkUI.attr("d", data);
+ });
+
+ renderer.run();
+ }
+ </script>
+ <style type="text/css">
+ html, body, svg { width: 100%; height: 100%;}
+ </style>
+</head>
+<body onload='main()'>
+
+</body>
+</html>
View
135 dist/vivagraph.js
@@ -946,7 +946,24 @@ Viva.Graph.geom = function() {
return s;
}
};
-};/**
+};/**
+ * Very generic rectangle.
+ */
+Viva.Graph.Rect = function(x1, y1, x2, y2) {
+ this.x1 = x1 || 0;
+ this.y1 = y1 || 0;
+ this.x2 = x2 || 0;
+ this.y2 = y2 || 0;
+};
+
+/**
+ * Very generic two-dimensional point.
+ */
+Viva.Graph.Point2d = function(x, y) {
+ this.x = x || 0;
+ this.y = y || 0;
+}
+/**
* @fileOverview Contains definition of the core graph object.
*
* @author Andrei Kashcha (aka anvaka) / http://anvaka.blogspot.com
@@ -2837,7 +2854,7 @@ Viva.Graph.Layout.forceDirected = function(graph, userSettings) {
initializationRequired = true,
- graphRect = {x1: 0, y1 : 0, x2 : 0, y2 : 0},
+ graphRect = new Viva.Graph.Rect(),
random = Viva.random('ted.com', 103, 114, 101, 97, 116),
@@ -3098,6 +3115,120 @@ Viva.Graph.Layout.forceDirected = function(graph, userSettings) {
}
}
};
+};/*global Viva*/
+
+Viva.Graph.Layout = Viva.Graph.Layout || {};
+
+/**
+ * Does not really perform any layouting algorithm but is compliant
+ * with renderer interface. Allowing clients to provide specific positioning
+ * callback and get static layout of the graph
+ *
+ * @param {Viva.Graph.graph} graph to layout
+ * @param {Object} userSettings
+ */
+Viva.Graph.Layout.constant = function(graph, userSettings) {
+ userSettings = userSettings || {};
+
+ var seed = userSettings.seed || 'Deterministic randomness made me do this',
+ maxX = (typeof userSettings.maxX === 'number') ? userSettings.maxX : 1024,
+ maxY = (typeof userSettings.maxY === 'number') ? userSettings.maxY : 1024,
+ rand = Viva.random(seed),
+
+ graphRect = new Viva.Graph.Rect(),
+
+ placeNodeCallback = function(node) {
+ return new Viva.Graph.Point2d(rand.next(maxX), rand.next(maxY));
+ },
+
+ updateNodePositions = function() {
+ var x1 = Number.MAX_VALUE,
+ y1 = Number.MAX_VALUE,
+ x2 = Number.MIN_VALUE,
+ y2 = Number.MIN_VALUE;
+ if (graph.getNodesCount() === 0) { return ;}
+
+ graph.forEachNode(function(node) {
+ if (!node.hasOwnProperty('position')) {
+ node.position = placeNodeCallback(node);
+ }
+
+ if (node.position.x < x1) { x1 = node.position.x; }
+ if (node.position.x > x2) { x2 = node.position.x; }
+ if (node.position.y < y1) { y1 = node.position.y; }
+ if (node.position.y > y2) { y2 = node.position.y; }
+ });
+
+ graphRect.x1 = x1;
+ graphRect.x2 = x2;
+ graphRect.y1 = y1;
+ graphRect.y2 = y2;
+ };
+
+ return {
+ /**
+ * Attempts to layout graph within given number of iterations.
+ *
+ * @param {integer} [iterationsCount] number of algorithm's iterations.
+ * The constant layout ignores this parameter.
+ */
+ run : function(iterationsCount) {
+ this.step();
+ },
+
+ /**
+ * One step of layout algorithm.
+ */
+ step : function() {
+ updateNodePositions();
+
+ return false; // no need to continue.
+ },
+
+ /**
+ * Returns rectangle structure {x1, y1, x2, y2}, which represents
+ * current space occupied by graph.
+ */
+ getGraphRect : function() {
+ return graphRect;
+ },
+
+ addNode : function(node) { /* nop */ },
+
+ removeNode : function(node) { /* nop */ },
+
+ addLink : function(link) { /* nop */ },
+
+ removeLink : function(link) { /* nop */ },
+
+ // Layout specific methods:
+
+ /**
+ * Based on argument either update default node placement callback or
+ * attempts to place given node using current placement callback.
+ * Setting new node callback triggers position update for all nodes.
+ *
+ * @param {Object} newPlaceNodeCallbackOrNode - if it is a function then
+ * default node placement callback is replaced with new one. Node placement
+ * callback has a form of function(node) {}, and is expected to return an
+ * object with x and y properties set to numbers.
+ *
+ * Otherwise if it's not a function the argument is treated as graph node
+ * and current node placement callback will be used to place it.
+ */
+ placeNode : function(newPlaceNodeCallbackOrNode) {
+ if (typeof(newPlaceNodeCallbackOrNode) === 'function') {
+ placeNodeCallback = newPlaceNodeCallbackOrNode;
+ updateNodePositions();
+ return this;
+ }
+
+ // it is not a request to update placeNodeCallback, trying to place
+ // a node using current callback:
+ return placeNodeCallback(newPlaceNodeCallbackOrNode);
+ }
+
+ };
};/**
* @fileOverview Defines a graph renderer that uses CSS based drawings.
*
View
2 dist/vivagraph.min.js
1 addition, 1 deletion not shown because the diff is too large. Please use a local Git client to view these changes.

0 comments on commit e6d2602

Please sign in to comment.