Easy way to enlarge visualization in D3 (without zooming in browser) - javascript

I'd have a few different visualizations (containing primarily nodes, links and paths), which I would like to enlarge by a factor 3 without having to change the width and length of every single class. Is there a simple way in D3 to make the whole visualization bigger? I'm currently zooming in using the browser, but that is not a good solution as it requires other users to do so as well.

Related

How to get the same node positions in d3's force layout graph

I would like to create a force directed graph, but i need it to stay the same every time it is generated (with the same data).
Is there any way to do this using d3.js?
UPDATE:
I found working solution, which is based on using seeded random number generator
// set the random seed
Math.seedrandom('mySeed');
You could by modifying D3's force layout, or by creating your own layout based on it. There are at least 3 places where randomness (Math.Random) is used in the positioning of nodes (there may be more, given the force layout references other code). You would have to eliminate all randomness in order to get the graph to display in the same way each time:
https://github.com/mbostock/d3/blob/master/src/layout/force.js
However, this would hamper how the layout works – it's using randomness to sort itself out into a legible diagram quickly. If your number of nodes is small, then it probably wouldn't be an issue, but a large number of nodes could just end up a tangle.

D3.js scattergraph with large (>500,000) points? Clustering?

I'm looking at plotting a scatterplot with a large number of points (500,000 and upwards).
Currently, we're doing this in Python with Matplotlib. It plots the points, and it provides controls to pan and zoom. I don't believe it provides any clustering or points, it just plots them all - doesn't make much sense at the zoomed out view, I suppose, but you can zoom in and they're all there.
I was looking at doing the chart in JavaScript, to make it a bit easier to distribute. I was looking at D3.js, to see if something similar is feasible there. I did find this example of a basic scatterplot:
http://bl.ocks.org/mbostock/3887118
Firstly, would you be able to plot that number of points? (500,000 and upwards) I was under the impression you couldn't due to the overhead of all the DOM objects? Are there ways around this?
Secondly, is there any kind of clustering available, either a library or even just an example of this being done in D3.js?
Thirdly, if anybody knows any good examples of pan/zoom functionality and clustering, or even just a packaged JS library that handles it, that would be awesome.
Fourth, it would be also nice to have click handlers for each point - and to display some text either in a overlay, or even just in a separate window. Any thoughts on this?
Can you draw half a million points with D3? Sure, but not with SVG. You'll have to use canvas (here's a simple example with 10,000 points that includes brush-based selection: http://bl.ocks.org/emeeks/306e64e0d687a4374bcd) and that means that you no longer have individual elements to assign click handlers to. You will not be able to render half a million points with SVG, because all those DOM elements will choke your interface, as you mentioned.
D3 does include quadtree support that can be leveraged for clustering. It's in use in the above example to speed up search but you could use it to nest elements in proximity at certain scales.
Ultimately, your choices are:
1) Some other library/custom implementation that renders in canvas and polls the mouse position to give you the data element rendered at that point.
2) A sophisticated custom D3 approach that nests elements in proximity and only renders SVG elements appropriate at the zoom level and canvas position (pan) you're at.
Yes, D3.js can be made to work with million scale data with two things:
pre-rendering on the server side. For more see here: https://mango-is.com/blog/engineering/pre-render-d3-js-charts-at-server-side/
By aggregating (or clustering) part of the data so that user can interact and expand the graph if need be. For this use collapsible nodes if you can (http://bl.ocks.org/mbostock/1062288).
Also avoid using force layout. It takes time to settle and converge to a stable positioning.
For clustering libraries, I would pick one up off the shelf. I would choose the scikits library from python, there are many in JavaScript but they are not very robust as they mostly cover k-means or hierarchical clustering. I would precalculate the coordinates using scikits by clustering and then render it using D3.
D3 handles Pan and zoom. Again click handlers and text display are available in D3. (http://bl.ocks.org/robschmuecker/7880033)

d3: Make a static directed graph

I'd like to visualize a 20K node dependency graph in d3. Force-directed graphs such as http://bl.ocks.org/mbostock/1153292 are too slow to render in the browser for this number of nodes.
Basically I want to represent nodes containing text and directed edges from one node to another, and add zooming and panning functionality. How can I go about doing this in d3?
Here's an alternative which doesn't seem to use force to lay out the nodes - there's no springing, performs well, and has built in upload/download facility. Its license is MIT/X:
Interactive tool for creating directed graphs using d3.js
directed-graph-creator
Operation:
drag/scroll to translate/zoom the graph
shift-click on graph to create a node
shift-click on a node and then drag to another node to connect them with a directed edge
shift-click on a node to change its title
click on node or edge and press backspace/delete to delete
The zoom behaviour (and pan) you would get basically for free through the zoom behaviour. The layout you would have to do yourself though -- the force layout is pretty much the only thing in D3 you can use to lay out a graph of this kind.
Regardless of what you're using, with 20K nodes anything dynamic is going to be pretty slow -- simply rendering all the elements is going to take quite some time during which the browser will seem unresponsive. An alternative you may want to consider is to pre-render the graph using something more suitable for large amounts of data, save the result as an image (or even static SVG) and add a little bit of D3 code on top for zoom/pan.

Static D3 Force-Directed Graph performance

So currently I'm trying to create a force-directed graph of a couple thousand nodes and about 30k links in the graph. As you may guess, the simulation is very very slow. What I would like to do instead is to precompute all the positions for the nodes and just render a static (but interactive) graph. Is there a way to use d3.js to calculate a force directed graph without rendering it (making it much faster) and then just render the static graph from the pre-calculated values? My code is currently based off Mike Bostock's example.
The method d3 uses for force directed graph layout is the standard repulsive force and attractive force model, you can find the pseudo code on Wikipedia (http://en.wikipedia.org/wiki/Force-based_algorithms_%28graph_drawing%29#Pseudocode) or check out the d3 source itself (https://github.com/mbostock/d3/blob/master/src/layout/force.js).
That algorithm has an O(n^2) complexity per tick (or time slice) and it takes about n ticks to reach an equilibrium so O(n^3) for the whole layout process (http://www.ecs.umass.edu/ece/labs/vlsicad/ece665/presentations/Force-Directed-Adel.ppt). For thousands of nodes this isn't practical.
To try and answer your specific question, just use CSS, display: none on your SVG container element. Once the initial simulation "eventually" finishes you can grab the HTML source of the SVG elements and use that as your basis for the static but interactive representation. (once you have html of all the elements you'd just have to add the mouse hover event onto them to have them display their details.

Render large matrix (1000*1000) in Javascript

I need to display a large matrix within our web-based application. The matrix dimensions are approx. 1000*1000 and each cell is either filled or not.
Basically, it should look like this (much larger and without the colors):
http://mbostock.github.com/protovis/ex/matrix.html
I need basic interaction, such as zooming and clicking on a cell. The matrix is likely to to be a sparse matrix.
I tried Protovis but rendering takes forever if the matrix is larger than 80*80.
What Javascript library might be suitable for this task?
I would use an HTML5 Canvas for fast drawing. (This super-simple demo renders in a few seconds on my computer.) If you want to zoom in, you can see this answer.
In order to display a million items to a user, each element would probably have to be the size of a single pixel.
I'd just use a canvas.
You could try the JavaScript library clustergrammer.js (see https://github.com/cornhundred/clustergrammer.js). It uses D3.js to make interactive (zoomable, reorderable, filterable, etc) visualizations. It can handle on the order of 100,000 data points, but if you matrix is sparse enough then you can render large matrices.
Here's an example of clustergrammer.js being used to visualize a 6000x230 matrix http://amp.pharm.mssm.edu/clustergrammer/viz/568affd5b6541b84f3a68234

Categories