Permalink
Browse files

Support for: manual layout, directed edges, edge weights

  • Loading branch information...
1 parent d172998 commit d7b4b794693646245a6c81b1076407598fb6b59b @vkaravir committed Feb 15, 2013
Showing with 101 additions and 13 deletions.
  1. +49 −0 examples/manual-graph.html
  2. +17 −1 src/datastructures.js
  3. +35 −12 src/graph.js
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Depth-First Search</title>
+ <link rel="stylesheet" href="../css/JSAV.css" type="text/css" media="screen" title="no title" charset="utf-8" />
+ </head>
+ <body>
+ <h1>JSAV example for graph with manual layout</h1>
+ <div id="av">
+ <div class="jsavcontrols"></div><span class="jsavcounter"></span>
+ <p class="jsavoutput jsavline"></p>
+ </div>
+ <script
+ src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js">
+ </script>
+ <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script>
+ <script src="../lib/jquery.transform.light.js"></script>
+ <script src="../lib/raphael.js"></script>
+ <script src="../build/JSAV.js"></script>
+ <script>
+ var jsav = new JSAV("av"),
+ g, a, b, c, d, e;
+ var initGraph = function() {
+ g = jsav.ds.graph({width: 500, height: 200, layout: "manual", directed: true});
+ a = g.addNode("A", {"left": 0, "top": 80})
+ b = g.addNode("B", {"left": 120})
+ c = g.addNode("C", {"left": 120, "top": 160})
+ d = g.addNode("D", {"left": 260})
+ e = g.addNode("E", {"left": 260, "top": 160});
+ g.addEdge(a, b, {weight: 20});
+ g.addEdge(a, c, {weight: 10});
+ g.addEdge(a, d, {weight: 2});
+ g.addEdge(b, d, {weight: 7});
+ g.addEdge(c, b, {weight: 11});
+ g.addEdge(c, e, {weight: 35});
+ g.addEdge(d, e, {weight: 14});
+ };
+ initGraph();
+ g.layout();
+ jsav.displayInit();
+ a.css({top: "+=20px"});
+ g.layout();
+ jsav.recorded();
+
+ g.mouseenter(function() { this.highlight({record: false}); })
+ .mouseleave(function() { this.unhighlight({record: false}); });
+ </script>
+ </body>
+</html>
View
@@ -98,6 +98,11 @@
}
this.g.rObj.node.setAttribute("data-container", this.container.id());
$(this.g.rObj.node).data("edge", this);
+
+ if (typeof this.options.weight !== "undefined") {
+ this._weight = this.options.weight;
+ this.label(this._weight);
+ }
if (visible) {
this.g.show();
}
@@ -135,7 +140,18 @@
return this;
}
};
+ edgeproto._setweight = JSAV.anim(function(newWeight) {
+ var oldWeight = this._weight;
+ this._weight = newWeight;
+ return [oldWeight];
+ });
edgeproto.weight = function(newWeight) {
+ if (typeof newWeight === "undefined") {
+ return this._weight;
+ } else {
+ this._setweight(newWeight);
+ this.label(newWeight);
+ }
};
edgeproto.clear = function() {
this.g.rObj.remove();
@@ -170,10 +186,10 @@
if (!this._label) {
this._label = this.jsav.label(newLabel, {container: this.container.element});
this._label.element.css({position: "absolute", display: "inline-block"}).addClass("jsavedgelabel");
+ this.jsav.container.on("jsav-updaterelative", positionUpdate);
} else {
this._label.text(newLabel, options);
}
- this.jsav.container.on("jsav-updaterelative", positionUpdate);
}
};
edgeproto.equals = function(otherEdge, options) {
View
@@ -101,6 +101,11 @@
// adds an edge from fromNode to toNode
graphproto.addEdge = function(fromNode, toNode, options) {
+ var opts = $.extend({}, this.options, options);
+ if (opts.directed && !opts["arrow-end"]) {
+ opts["arrow-end"] = "classic-wide-long";
+ }
+
// only allow one edge between two nodes
if (this.hasEdge(fromNode, toNode)) { return; }
// get indices of the nodes
@@ -109,18 +114,18 @@
if (fromIndex === -1 || toIndex === -1) { return; } // no such nodes
// create new edge
- var edge = new Edge(this.jsav, fromNode, toNode, options),
+ var edge = new Edge(this.jsav, fromNode, toNode, opts),
adjlist = this._edges[fromIndex].slice(0);
// add new edge to adjlist
adjlist.push(edge);
// set the adjlist (makes the operation animated)
- this._setadjlist(adjlist, fromIndex, options);
+ this._setadjlist(adjlist, fromIndex, opts);
- if (!this.options.directed) {
- edge = new Edge(this.jsav, toNode, fromNode, options);
+ if (!opts.directed) {
+ edge = new Edge(this.jsav, toNode, fromNode, opts);
adjlist = this._edges[toIndex].slice(0);
adjlist.push(edge);
- this._setadjlist(adjlist, toIndex, options);
+ this._setadjlist(adjlist, toIndex, opts);
}
return edge;
};
@@ -191,14 +196,14 @@
JSAV.utils._events._addEventSupport(graphproto);
// do the graph layout
- graphproto.layout = function() {
- // TODO: check the layout option
- var spring = new SpringLayout(this);
+ graphproto.layout = function(options) {
+ var layoutAlg = this.options.layout || "_default";
+ return this.jsav.ds.layout.graph[layoutAlg](this, options);
};
-var SpringLayout = function(graph) {
+var SpringLayout = function(graph, options) {
this.graph = graph;
- this.iterations = 500;
+ this.iterations = 2000;
this.maxRepulsiveForceDistance = 6;
this.k = 2;
this.c = 0.01;
@@ -368,13 +373,30 @@ SpringLayout.prototype = {
lay1.layoutForceY += attractiveForce * dy / d;
}
};
-/*! End Graph Dracula -based code
+/*! End Graph Dracula -based code
*/
+ var springLayout = function springLayout(graph, options) {
+ var layout = new SpringLayout(graph);
+ };
+ var manualLayout = function manualLayout(graph, options) {
+ var i, l, edge,
+ edges = graph.edges();
+ for (i = 0, l = edges.length; i < l; i++) {
+ edge = edges[i];
+ graph.jsav.ds.layout.edge._default(edge, edge.start().position(), edge.end().position());
+ }
+ };
+ JSAV.ext.ds.layout.graph = {
+ "_default": springLayout,
+ "automatic": springLayout,
+ "manual": manualLayout
+ };
+
var GraphNode = function(container, value, options) {
this.jsav = container.jsav;
this.container = container;
- this.options = $.extend(true, {visible: true}, options);
+ this.options = $.extend(true, {visible: true, left: 0, top: 0}, options);
var el = this.options.nodeelement || $("<div><span class='jsavvalue'>" + this._valstring(value) + "</span></div>"),
valtype = typeof(value);
if (valtype === "object") { valtype = "string"; }
@@ -387,6 +409,7 @@ SpringLayout.prototype = {
}
this.container.element.append(el);
+ JSAV.utils._helpers.handlePosition(this);
JSAV.utils._helpers.handleVisibility(this, this.options);
};
var nodeproto = GraphNode.prototype;

0 comments on commit d7b4b79

Please sign in to comment.