SnarkShark SnarkShark - 1 year ago 199
Javascript Question

Problems with parsing JSON for D3

I am building an app with Flask and Python, and I want to pass some of my Python-generated results into JSON, so that they can be visualized with D3 under a container fluid. To do this, I am trying to use the Jinja method

var myjson = {{jsonDict|tojson }};
. Here
is a variable in my Python code that is a string of a dict, where single quotes have been replaced with double quotes with a regular expression, so that it looks like proper JSON. I am also using the JS method
root = JSON.parse( myjson );
. I believe that the combination of these two should solve my problem, but when I run the code, however I am getting the error:

Uncaught SyntaxError: Unexpected token y in JSON at position 0
uo @ d3.v3.min.js:3
i @ d3.v3.min.js:1

Here is the D3 template that I am trying to use:

Here is my implementation of this D3 (just the relevant script):


var margin = 20,
diameter = 960;

var color = d3.scale.linear()
.domain([-1, 5])
.range(["hsl(152,80%,80%)", "hsl(228,30%,40%)"])

var pack = d3.layout.pack()
.size([diameter - margin, diameter - margin])
.value(function(d) { return d.size; })

var svg ="#dan").append("svg") //#dan is name of my container fluid
.attr("width", diameter)
.attr("height", diameter)
.attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")");

//this is the part of the code I have added //
var myjson = {{ jsonDict|tojson }};
root = JSON.parse( myjson );
//this is the part of the code I have added //

d3.json("root", function(error, root) {
if (error) throw error; //this is index 2222

var focus = root,
nodes = pack.nodes(root),

var circle = svg.selectAll("circle")
.attr("class", function(d) { return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root"; })
.style("fill", function(d) { return d.children ? color(d.depth) : null; })
.on("click", function(d) { if (focus !== d) zoom(d), d3.event.stopPropagation(); });

var text = svg.selectAll("text")
.attr("class", "label")
.style("fill-opacity", function(d) { return d.parent === root ? 1 : 0; })
.style("display", function(d) { return d.parent === root ? "inline" : "none"; })
.text(function(d) { return; });

var node = svg.selectAll("circle,text");"#dan")
.style("background", color(-1))
.on("click", function() { zoom(root); });

zoomTo([root.x, root.y, root.r * 2 + margin]);

function zoom(d) {
var focus0 = focus; focus = d;

var transition = d3.transition()
.duration(d3.event.altKey ? 7500 : 750)
.tween("zoom", function(d) {
var i = d3.interpolateZoom(view, [focus.x, focus.y, focus.r * 2 + margin]);
return function(t) { zoomTo(i(t)); };

.filter(function(d) { return d.parent === focus || === "inline"; })
.style("fill-opacity", function(d) { return d.parent === focus ? 1 : 0; })
.each("start", function(d) { if (d.parent === focus) = "inline"; })
.each("end", function(d) { if (d.parent !== focus) = "none"; });

function zoomTo(v) {
var k = diameter / v[2]; view = v;
node.attr("transform", function(d) { return "translate(" + (d.x - v[0]) * k + "," + (d.y - v[1]) * k + ")"; });
circle.attr("r", function(d) { return d.r * k; });
});"height", diameter + "px");


As you can see, I replaced the original JS lines from the D3 code:

d3.json("flare.json", function(error, root) {
if (error) throw error;


var myjson = {{ jsonDict|tojson }};
root = JSON.parse( myjson );

d3.json("root", function(error, root) {

As I have my code now, if I inspect the page, the
shows up on the webpage in the correct place, but it is blank.

I am new to D3 and Javascript. Any help would be much appreciated! Thank you!

EDIT - console logs

if I do console.log(myjson), the console prints the string of the JSON properly (see below)

if I do console.log(root), the console prints

Object {children: Array[2], name: "flare"}
__defineSetter__: __defineSetter__()
get __proto__:__proto__()
set __proto__:__proto__()

So it seems that the
method is failing me somehow.

EDIT -- my JSON string that is being passed from Python into
var myjson

{"name": "flare", "children": [{"name": "concept0", "children": [{"name": "intermediate host", "size": 700}, {"name": "abstrusus brevior", "size": 700}, {"name": "stage larva", "size": 700}, {"name": "anterior extremity", "size": 700}, {"name": "crenosoma vulpi", "size": 700}]}, {"name": "concept1", "children": [{"name": "infected cat", "size": 700}, {"name": "abstrusus infection", "size": 700}, {"name": "domestic cat", "size": 700}, {"name": "feline aelurostrongylosis", "size": 700}, {"name": "cat infect", "size": 700}]}]}

pagesource for

{"name": "flare", "children": [{"name": "concept0", "children": [{"size": 700, "name": "intermediate host"}, {"size": 700, "name": "abstrusus brevior"}, {"size": 700, "name": "stage larva"}, {"size": 700, "name": "anterior extremity"}, {"size": 700, "name": "crenosoma vulpi"}]}, {"name": "concept1", "children": [{"size": 700, "name": "infected cat"}, {"size": 700, "name": "abstrusus infection"}, {"size": 700, "name": "domestic cat"}, {"size": 700, "name": "feline aelurostrongylosis"}, {"size": 700, "name": "cat infect"}]}]}

EDIT - I think the problem can be seen in
. I've checked other D3 visualizations and the log should typically look like this:

Object {name: "flare", children: Array[5]}
children: Array[5]

Answer Source

Because you are already passing your json to your client via your flask application there is no need to use d3's d3.json() method. d3.json() is essentially an ajax GET request which requests the file from the server.

d3.json(url[, callback])

Creates a request for the JSON file at the specified url with the mime type "application/json". If a callback is specified, the request is immediately issued with the GET method, and the callback will be invoked asynchronously when the file is loaded or the request fails; the callback is invoked with two arguments: the error, if any, and the parsed JSON. The parsed JSON is undefined if an error occurs. If no callback is specified, the returned request can be issued using xhr.get or similar, and handled using xhr.on.

You already had your data stored in a variable on in your javascript so there was no need to request it from the server.
Also when you tried to request it you were passing in an invalid url.
Removing the d3.json() function and just running the rest of the code should work.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download