Glinkot Glinkot - 5 months ago 32
JSON Question

Using JSON data in D3 Javascript visualisation

I'm working through the use of JSON data to drive some charts made with the javascript D3 visualisation tools (http://mbostock.github.com/d3/). I've setup my WCF service, and this code in Jquery works fine:

$('#getDataItems').click(function () {

var $DataList = $('#DataList');
$DataList.empty().appendLi('Loading...');

// Get the JsonP data
$.getJSON('http://localhost:65025/CustomersService.svc/GetMyDataItems?callback=?', null, function (somedata) {
alert('Received ' + somedata.length + ' Items');

$DataList.empty();
$.each(somedata, function () {
$DataList.appendLi(this.ID + " - " + this.Value);
}); // end each dataitem function
}); // end success function
}); // end #getDataItems.click


D3 has a function for using JSON data also, but I haven't yet had success. It looks like this:

// this works
//var data = [4, 8, 15, 16, 23, 42];

// this doesn't
var data = function () {
d3.json('http://localhost:65025/CustomersService.svc/GetMyDataItems?callback=?',
function (data) } })
}

//.. rest of the example is known working code so its here only for reference

// create the chart class as an append to the body element.
var chart = d3.select("body")
.append("svg:svg")
.attr("class", "chart")
.attr("width", 420)
.attr("height", 20 * data.length);

// Set the width relative to max data value
var x = d3.scale.linear()
.domain([0, d3.max(data)])
.range([0, 420]);

var y = d3.scale.ordinal()
.domain(data)
.rangeBands([0, 120]);

chart.selectAll("rect")
.data(data)
.enter().append("svg:rect")
.attr("y", y)
.attr("width", x)
.attr("height", y.rangeBand());

chart.selectAll("text")
.data(data)
.enter().append("svg:text")
.attr("x", x)
.attr("y", function (d) { return y(d) + y.rangeBand() / 2; })
.attr("dx", -3) // padding-right
.attr("dy", ".35em") // vertical-align: middle
.attr("text-anchor", "end") // text-align: right
.text(String);


Pretty much all the code is from the 'bar chart' example in the D3 download, which works fine. If I declare the data manually (per the array of integers above) it works, but not with the JSON command. I also simplified the data returned so it consisted only of integers. Ultimately though, I'd want to be able to access JSON data with an 'id field', 'value field' etc and reference these in the code.

Anyone have any ideas on whether my syntax is incorrect? I realise the function (data) is meant to be used to add data to the chart, but the code in this example works so I'd prefer to start from that point.

Answer

D3 has its own json getting function for completeness of the framework but you don't have to use it. You could try your d3 chart with the jQuery $.getJSON and it should work. This is what I do since most of my development is done using jQuery.

As for your example, the d3.json semantics is exactly the same as the $.getJSON. It is asynchronous call in which the function is called after the data is retrieved. Try something like this:

d3.json(
  'http://localhost:65025/CustomersService.svc/GetMyDataItems?callback=?',
  function (jsondata) {

    // create the chart here with
    // the returned data

    console.log(jsondata);

    var data = jsondata.map(function(d) { return d.Value; });
    console.log(data);

  });