Objective
Positioning Browser chart, vml,svg, HTML5 canvas used in different ways.
If you use the existing JS library (various implementations of the library summary and comparison of JS Chart), the calling API is certainly different.
For example: Draw2d uses both Addfigure and setposition to set the position of the diagram.
It is clearly not a wise idea to mix in a particular technology or a particular library to layout.
Cut apart, the layout function is useful for any graphic rendering. That's what this chapter is all about.
Realize the idea
In fact, the realization of the idea is very simple, maintain a JS object (Graph). In this object, record the node, the edge of the information;
A node contains the following information:
--representation
--Horizontal axis
--ordinate
Shape--Drawing
In this case, you should first maintain some information about this graph node in this graph before drawing a diagram node.
Graph Example
var Graph = function () {this.nodeset = {};
This.nodes = [];
This.edges = [];
This.adjacency = {};
This.nextnodeid = 0;
This.nextedgeid = 0;
This.eventlisteners = [];
};
var Node = function (ID, data) {this.id = ID; This.data = typeof (data)!== ' undefined '?
Data: {};
};
var Edge = function (ID, source, target, data) {this.id = ID;
This.source = source;
This.target = target; This.data = typeof (data)!== ' undefined '?
Data: {};
}; Graph.prototype.addNode = function (node) {if (typeof (this.nodeset[node.id)) = = ' undefined ') {this.nodes
. push (node);
} This.nodeset[node.id] = node;
This.notify ();
return node;
};
Graph.prototype.addEdge = function (Edge) {var exists = false;
This.edges.forEach (function (e) {if (edge.id = = e.id) {exists = true;}
}); if (!exists) {
This.edges.push (Edge); } if (typeof (This.adjacency[edge.source.id]) = = ' undefined ') {this.adjacency[edge.source.id] = {}
; } if (typeof (This.adjacency[edge.source.id][edge.target.id]) = = ' undefined ') {This.adjacency[edge.source
. id][edge.target.id] = [];
} exists = false; This.adjacency[edge.source.id][edge.target.id].foreach (function (e) {if (edge.id = = e.id) {exists = true;
}
});
if (!exists) {This.adjacency[edge.source.id][edge.target.id].push (edge);
} this.notify ();
return edge;
};
Graph.prototype.newNode = function (data) {var node = new node (this.nextnodeid++, data);
This.addnode (node);
return node;
}; Graph.prototype.newEdge = function (source, target, data) {var edge = new Edge (this.nextedgeid++, source, Target, DA
TA);
This.addedge (Edge);
return edge;
};Find the edges from Node1 to node2 Graph.prototype.getEdges = function (Node1, node2) {if typeof (This.adjacenc Y[node1.id])!== ' undefined ' && typeof (This.adjacency[node1.id][node2.id])!== ' undefined ') {RE
Turn this.adjacency[node1.id][node2.id];
} return [];
}; Remove a node and it ' s associated edges from the graph Graph.prototype.removeNode = function (node) {if (typeof
(This.nodeset[node.id])!== ' undefined ') {delete this.nodeset[node.id];
for (var i = this.nodes.length-1 i >= 0; i--) {if (this.nodes[i].id = = node.id) {
This.nodes.splice (i, 1);
} this.detachnode (node);
}; Removes edges associated with a given node Graph.prototype.detachNode = function (node) {var tmpedges = This.ed
Ges.slice (); Tmpedges.foreach (function (e) {if (e.source.id = = Node.id | | e.target.id = == node.id) {This.removeedge (e);
}, this);
This.notify ();
}; Remove a node and it ' s associated edges from the graph Graph.prototype.removeEdge = function (Edge) {for (Var i = This.edges.length-1; I >= 0;
i--) {if (this.edges[i].id = = edge.id) {This.edges.splice (I, 1); } for (Var x in this.adjacency) {for (Var y in this.adjacency[x]) {var edge
s = this.adjacency[x][y];
for (var j=edges.length-1; j>=0; j--) {if (this.adjacency[x][y][j].id = = edge.id) {
This.adjacency[x][y].splice (J, 1);
}}} this.notify ();
}; /* Merge A list of nodes and edges into the current graph.
eg. var o = {nodes: [{id:123, data: {type: ' user ', userid:123, displayname: ' AAA '}}, {id:234, data : {Type: ' User ', userid:234, displayname: ' BBB '}}], edges: [{from:0, to:1, type: ' Submitted_design ',
Directed:true, data: {weight:}}]} */Graph.prototype.merge = function (data) {var nodes = [];
Data.nodes.forEach (function (n) {Nodes.push (This.addnode (New Node (N.id, n.data));
}, this);
Data.edges.forEach (function (e) {var from = Nodes[e.from];
var to = nodes[e.to]; var id = (e.directed)?
(id = e.type + "-" + from.id + "-" + to.id): (From.id < To.id)//normalise ID for non-directed edges ?
E.type + "-" + from.id + "-" + To.id:e.type + "-" + to.id + "-" + from.id;
var edge = This.addedge (new Edge (ID, from, to, E.data);
Edge.data.type = E.type;
}, this);
};
Graph.prototype.filterNodes = function (fn) {var tmpnodes = This.nodes.slice (); Tmpnodes.foreach (function (n) {if (!FN (n)) {This.removenode (n));
}, this);
};
Graph.prototype.filterEdges = function (fn) {var tmpedges = This.edges.slice ();
Tmpedges.foreach (function (e) {if (!FN (e)) {This.removeedge (e));
}, this);
};
Graph.prototype.addGraphListener = function (obj) {this.eventListeners.push (obj);
};
Graph.prototype.notify = function () {This.eventListeners.forEach (function (obj) {obj.graphchanged ();
}); };