1

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?

Milla Well
  • 3,193
  • 3
  • 35
  • 50

1 Answers1

0

If you're just grabbing some data out of a model, you can do something like this.

View

import json

def view(request):

    stats = stats.SomeModule.objects.all().values("id","value")
    # returns a list of dicts => [{"id":__,"value":__},...]

    return render(request, "someTemplate.html" , {"data": json.dumps(stats)})

Template

<script>var data = {{ data|safe }}</script>
Thomas
  • 11,757
  • 4
  • 41
  • 57
  • complex groupings are not always solved easily without having a DB2 database or similar. But I guess by starting to mess around with django-side grouping, you always kind of end up converting data structures. – Milla Well Mar 28 '13 at 12:39
  • It would help if you could post a more concrete example of your models and the transformations you want to do to the data. But if all your doing is pulling data out of a database and stuffing it into a JSON object then this is all you need. – Thomas Mar 28 '13 at 12:51
  • I wrote a small example of passing grouped data from Django to d3 here: http://stackoverflow.com/questions/26453916/passing-data-from-django-to-d3 – Fernando Macedo Dec 18 '14 at 13:57