There are many occasions, where I have just a few data points to be visualized via d3.js. In these cases I thougt it makes sense to send these datapoints already in the main static request, rather than loading them dynamically via ajax later.
This means, i would save the data in a javascript variable like this
var data = ... ;
Most of the basic examples of d3.js depend on a data structure like this:
{[
{"key1" : "val11", "key2" : "val21"},
{"key1" : "val12", "key2" : "val22"},
...
]}
because in each function for processing the data/labels, d3 uses the .
-notation
function(d){return d.key1;}
I achieve this structure by modifying the basic d3.js examples by removing the
d3.tsv("data.tsv", function(error, data) {});
loop, because my data is already in the dom.
The question is now:
How can use template languages to make sure, that the data is in the appropriate format?
Example PhP
My use case on server side is, that I generate an array with values like this:
$dbresult = dbqueryfunction();
$respone = array();
foreach($dbresult as $key => $value){
if(!array_key_exists($value->column1,$response))
$response[$value->column1] = 0;
$response[$value->column1] += someMath($value->column2);
which is a grouping over column1. To output this I do
var data = <?php echo json_encode($response); ?> ;
But this means, that I have to iterate over the data once again on client side, to achieve the desired structure (for example with jQuery):
var dataJS = new Array();
$.each(dataPHP, function(phpKeys, phpVals){
dataJS.push({"key1" phpKeys: , "key2" : phpVals});
})
Example Django
In Django the problem is different, because the response ist sent in a dictionary, not in an array:
response = defaultdict(int)
dbresult = stats.SomeModule.objects.all()
for val in dbresult:
response[val.c1] += someMath(val.c2)
This means, that I either use
return render(request, "someTemplate.html" , {"data" : repr(response)})
and in the template
{% autoescape off %}
var data = {{ data }};
{% endautoescape %}
or I use
return render(request, "someTemplate.html" , {"data" : response})
and in the template again
var data = {"content": [
{% for di,value in data %}
{"key1": "{{ di }}", "key2": "{{ value }}" },
{% endfor %}
]
};
data = data.content;
So as you can see, I tried many things and am still not sure: What is the best way to proceed to achieve the d3.js standard desired data structure?
EDIT:
I also thought about using d3.js functions differently, since one has function(d,i){};
as well, one could always use the index to access data like:
function(d,i){return data.key1[i];}
or is this a bad style?