D3 Pre-render
I am still new to JS + Python and I would be very happy to help you with one problem. Basically what I need to do is pre-render d3js network renderings (e.g. http://bl.ocks.org/mbostock/4062045 ) to a static page. The main goal is to reduce the pageload. As a side effect, a static page would also be a better entry point for scripts that render a png that can be used for graph thumbnails.
So I present one site where I run the Force Directed algorithm once and then store the end position values of a node in a static file (where the node positions are then placed). The system is currently running Python / Django on Google App Engine. Is it possible?
Code samples / fiddle would be great!
Disclosure: here I read here d3js great server side strength orientation and this one http://mango-is.com/blog/engineering/pre-render-d3-js-charts-at-server-side.html
source to share
You can satisfy both requirements with CasperJS . Casper is a library that will use a mute browser to request a web page that it can also programmatically interact with. A simple snippet of how to capture a screenshot looks something like this:
casper.start('http://ninjaPixel.io/', function() {
this.capture('page.png', undefined, {
format: 'png'
});
});
You can add a delay to this to make sure your power diagram is in a stable state when you take the screenshot. Casper can grab anything from the page, so if you are showing your computed node values in an html table, for example, tell Casper the id of that table and then he can grab it and store the values for you. You can even save the SVG object generated by your d3.js code.
source to share
This nifty graphic (by mbostock for nytimes) shows how to render a static plot in the DOM based on pre-computed positions. All the code is in the main html document, so just "view the source".
It first loads the data and then calls ready
:
queue()
.defer(d3.json, "http://graphics8.nytimes.com/newsgraphics/2013/09/07/director-star-chart/ed9eaa686bc2e11f0657a78d9be292a730c0567a/graph.json")
.defer(d3.json, "http://graphics8.nytimes.com/newsgraphics/2013/09/07/director-star-chart/ed9eaa686bc2e11f0657a78d9be292a730c0567a/layout.json")
.await(ready);
If you take a look inside the .json files, you can see how they chose to capture the graph data.
The handler ready
starts like this:
function ready(error, graph, positions) {
force
.nodes(graph.nodes)
.links(graph.links)
.on("tick", ticked)
.start();
if (positions) force.alpha(.0051);
....
You can see that it initializes the propulsion layout and sets it alpha()
to a very low number, signaling that the layout is essentially set. As a result, the tick handler ticked()
probably only gets it once before the layout stops ticking due to the low alpha value.
However, also note that setting alpha to a very low value is conditional, depending on availability positions
. Therefore, if positions
not preloaded and therefore would have been undefined
, the layout will tick several times for a while until it drops some positioning. This suggests that the same code displaying this static layout was also used - perhaps with some additional code but not loaded positions
- during the line item export process. This is really very clever (!).
The code that was used to collect and write the line items to a file does not appear to be part of the source code for this page, which makes sense, but you can hopefully find a way to do this within your project environment.
source to share