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

+1


source to share


2 answers


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.

+2


source


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.

+1


source







All Articles