Vis.js - set a set of nodes on the screen

I have a network graph in vis.js with many nodes. When choosing a specific group, I would like to pan and scale the graph so that all the nodes of this group fit the screen.

I look at each node in the graph and compute the bounding box for all the nodes that interest me, then I use the moveTo method to move and scale the graph to the center of this bounding box. Pseudo Code:

 var allNodes = data.nodes.get({ returnType: "Object" }); var bounds; for (n in allNodes) { if (matchesCondition(allNodes[n])) { bounds = extendBounds(bounds, graph.getBoundingBox(allNodes[n])); } } var newViewport = { position: { x: (bounds.x1+bounds.x2)/2; y: (bounds.y1+bounds.y2)/2; }, // What is the visible width, where do I get it from? scale: Math.min(??? / (bounds.x2-bounds.x1), ??? / (bounds.y2-bounds.y1)) } graph.moveTo(newViewport); 

Question: how can I calculate the scale, that is, what will I replace ??? with in the pseudocode above?

+6
source share
1 answer

Sample data from Sample Vis.js Groups .

To set the viewport, you can simply use your own .fit() method. Since the documentation does not provide hackable links, here's a description of the API:

Reduces the scale so that all nodes fit on the canvas. You can specify options, configure this:

 { nodes:[Array of nodeIds], animation: { //can be a boolean too duration: Number easingFunction: String } } 

Nodes can be used for scaling to fit only specific nodes in a view.

With that in mind, all we need to do is get all the nodes in this group. Surprisingly, the user API does not offer a method for this (?), Therefore a small filtering method is needed.

 //TODO: Is there no user-land API for this? var getGroup = function getGroup(nodeId) { var nodesHandler = network.nodesHandler; var innerNodes = nodesHandler.body.nodes; //Lazily assume ids match indices var node = innerNodes[nodeId]; return node.options.group; }; var getGroupNodes = function getGroupNodes(group) { // http://elijahmanor.com/reducing-filter-and-map-down-to-reduce/ var filtered = nodes.reduce(function(output, node) { if (node.group === group) { output.push(node.id); } return output; }, []); return filtered; }; //START Vis.js group example var color = 'gray'; var len = undefined; var nodes = [{ id: 0, label: "0", group: 0 }, { id: 1, label: "1", group: 0 }, { id: 2, label: "2", group: 0 }, { id: 3, label: "3", group: 1 }, { id: 4, label: "4", group: 1 }, { id: 5, label: "5", group: 1 }, { id: 6, label: "6", group: 2 }, { id: 7, label: "7", group: 2 }, { id: 8, label: "8", group: 2 }, { id: 9, label: "9", group: 3 }, { id: 10, label: "10", group: 3 }, { id: 11, label: "11", group: 3 }, { id: 12, label: "12", group: 4 }, { id: 13, label: "13", group: 4 }, { id: 14, label: "14", group: 4 }, { id: 15, label: "15", group: 5 }, { id: 16, label: "16", group: 5 }, { id: 17, label: "17", group: 5 }, { id: 18, label: "18", group: 6 }, { id: 19, label: "19", group: 6 }, { id: 20, label: "20", group: 6 }, { id: 21, label: "21", group: 7 }, { id: 22, label: "22", group: 7 }, { id: 23, label: "23", group: 7 }, { id: 24, label: "24", group: 8 }, { id: 25, label: "25", group: 8 }, { id: 26, label: "26", group: 8 }, { id: 27, label: "27", group: 9 }, { id: 28, label: "28", group: 9 }, { id: 29, label: "29", group: 9 }]; var edges = [{ from: 1, to: 0 }, { from: 2, to: 0 }, { from: 4, to: 3 }, { from: 5, to: 4 }, { from: 4, to: 0 }, { from: 7, to: 6 }, { from: 8, to: 7 }, { from: 7, to: 0 }, { from: 10, to: 9 }, { from: 11, to: 10 }, { from: 10, to: 4 }, { from: 13, to: 12 }, { from: 14, to: 13 }, { from: 13, to: 0 }, { from: 16, to: 15 }, { from: 17, to: 15 }, { from: 15, to: 10 }, { from: 19, to: 18 }, { from: 20, to: 19 }, { from: 19, to: 4 }, { from: 22, to: 21 }, { from: 23, to: 22 }, { from: 22, to: 13 }, { from: 25, to: 24 }, { from: 26, to: 25 }, { from: 25, to: 7 }, { from: 28, to: 27 }, { from: 29, to: 28 }, { from: 28, to: 0 }]; // create a network var container = document.getElementById('mynetwork'); var data = { nodes: nodes, edges: edges }; var options = { nodes: { shape: 'dot', size: 30, font: { size: 32, color: '#ffffff' }, borderWidth: 2 }, edges: { width: 2 } }; network = new vis.Network(container, data, options); //END Vis.js group example network.on("click", function(e) { //Zoom only on single node clicks, zoom out otherwise if (e.nodes.length !== 1) { network.fit(); return; } var nodeId = e.nodes[0]; //Find out what group the node belongs to var group = getGroup(nodeId); //TODO: How do you want to handle ungrouped nodes? if (group === undefined) return; var groupNodes = getGroupNodes(group); network.fit({ nodes: groupNodes }); }); 
 html, body, #mynetwork { width: 100%; height: 100%; margin: 0; } 
 <script src="http://cdnjs.cloudflare.com/ajax/libs/vis/4.3.0/vis.min.js"></script> <div id="mynetwork"></div> 
+8
source

All Articles