D3.js can't load json file - javascript

I am trying to create a D3.js packed circle diagram.
When I embed the data in the HTML file, it works fine. When I put the data in an external file, I get nothing (blank DOM, no console msgs).
If you uncomment the var data declaration and comment out the d3.json (and the corresponding closing parentheses) it works fine.
I can see the "2013 Inf-2.json" file in the browser and it appears well formed (it passes jsonlint validation). It includes everything from the first "{" through/including the last "}". Much as the embedded example.
I'm running this through httpd (:80) on OSX Mavericks and trying to render the chart in Chrome or Safari.
<!DOCTYPE html>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript" src="./d3.v3.min.js"></script>
</head>
<body>
<div id="chart2"></div>
<script type="text/javascript">
var w = 640, h = 480;
/*
var data ={
"name" : "root",
"children" : [
{
"name":"URIN TRACT INFECTION NOS",
"size":12196
},
{
"name":"ACUTE PHARYNGITIS",
"size":6679
},
{
"name":"PNEUMONIA ORGANISM NOS",
"size":6452
},
{
"name":"BRONCHITIS NOS",
"size":2636
},
{
"name":"CELLULITIS OF LEG",
"size":2348
},
{
"name":"OBSTR CHRONIC BRONCHITIS W (ACUTE) EXACERBATION",
"size":2203
}
]
}
*/
var data = d3.json("2013 Inf-2.json", function(error, root) {
var canvas = d3.select("#chart2")
.append("svg:svg")
.attr("width", w)
.attr("height", h);
var nodes = d3.layout.pack()
.value(function(d) { return d.size; })
.size([w, h])
.nodes(data);
// Get rid of root node
nodes.shift();
canvas.selectAll("circles")
.data(nodes)
.enter().append("svg:circle")
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("r", function(d) { return d.r; })
.attr("fill", "green")
.attr("stroke", "grey");
});
</script>
</html>

You should change line
var data = d3.json("2013 Inf-2.json", function(error, root) {
to
var data = d3.json("2013 Inf-2.json", function(error, data) {
So you just have to replace "root" with "data"

Related

D3 JS - Why d3 is not appending a string?

I have this json file:
[
{
"id": "1",
"name": "Hello world",
"shape": "rect",
"fill": "pink"
}
]
And I also have this javascript file:
const svg = d3.select('svg')
var stringToHTML = function (str) {
var parser = new DOMParser();
var doc = parser.parseFromString(str, 'text/html');
return doc.body;
};
d3.json("tree.json").then(data => {
const elements = svg.selectAll('*')
.data(data);
elements.enter()
.append("rect")
.attr("x", 20)
.attr("y", 20)
.attr("width", 100)
.attr("height", 100)
.attr("fill", d => d.fill)
elements.enter()
.append('text')
.attr("x", 50)
.attr("y", 60)
.html("text", d => {d.name})
})
and this html file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<svg width="600" height="600">
</svg>
<script src="https://d3js.org/d3.v7.min.js"></script>
<script src="index.js"></script>
</body>
</html>
Now the output is:
1st output
but when I switch "rect" with d => d.shape it doesn't behave as before.
d3.json("tree.json").then(data => {
const elements = svg.selectAll('*')
.data(data);
elements.enter()
.append(d => d.)
.attr("x", 20)
.attr("y", 20)
.attr("width", 100)
.attr("height", 100)
.attr("fill", d => d.fill)
But how is it different than the previous one? I also tried outputting d.shape, and it prints string. Then how can I make something that will create a shape according to the shape data?

Unable to understand d3js zoom functionality

The following SIMPLE :) code gives following error. Please help me what mistake I am making to ZOOM on onClick on the Circle ?
Similarly I will be very thankful if someone can give some idea that if i want to zoom to 3rd Circle DIRECTLY without clicking on it; what should I do ?
ERROR: Uncaught TypeError: Cannot read property 'apply' of undefined
at qr.call (d3.min.js:2)
at SVGCircleElement.clicked (index.html:52)
at SVGCircleElement.<anonymous> (d3.min.js:2)
And here is the code.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1" />
<title>Zoom & Pan</title>
<link rel="stylesheet" type="text/css" href="styles.css" />
<script type="text/javascript" src="d3.min.js"></script>
<style type="text/css">
</style>
</head>
<body>
<script type="text/javascript">
var width = 600, height = 350;
var data = [
{ "r": 10, "cx": 100, "cy": 150 },
{ "r": 30, "cx": 200, "cy": 150 },
{ "r": 15, "cx": 300, "cy": 150 }
];
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.call(
d3.zoom()
.scaleExtent([1, 7])
.on("zoom", zoom)
);
const g = svg.append("g");
g.selectAll("circle")
.data(data)
.enter()
.append("circle")
//.attr("fill", function (d) { return d.color; })
.attr("fill", (d, i) => d3.interpolateRainbow(i / 3))
.on("click", clicked)
.attr("r", function (d) { return d.r; })
.attr("cx", function (d) { return d.cx; })
.attr("cy", function (d) { return d.cy; });
function clicked(d,i,nodes) {
console.log(nodes);
svg.transition().duration(750).call(
zoom.transform,
d3.zoomIdentity.translate(width / 2, height / 2).scale(40).translate(-d.cx, -d.cy),
d3.mouse(svg.node())
);
}
function zoom() {
g.attr("transform", d3.event.transform);
}
</script>
</body>
</html>
The issue is that zoom.transform is not a thing. You have created a function called zoom, if that is important then you'll need to create another variable called something else, e.g. zoomer, probably in window scope, like width and height:
var zoomer = d3.zoom();
Then in your click handler change zoom.transform to zoomer.transform:
function clicked(d,i,nodes) {
console.log(nodes);
svg.transition().duration(750).call(
zoomer.transform, //change here
d3.zoomIdentity.translate(width / 2, height / 2).scale(40).translate(-d.cx, -d.cy),
d3.mouse(svg.node())
);
}
If you don't need the zoom function, then delete that and create the zoom variable like the zoomer one above and don't change the click handler.

No Output of the apparent right "D3.js - Code" (Simple Scatterplot)

I am new in D3.js and can't fix a seemingly small problem. The thing is I don't realy understand what's wrong with "my" code. The error that I get on the console tells me: "SyntaxError: expected expression, got '<' ", which doesn't make any sense for me. May be some of you can help me with this. Here it is:
var xyr = [
{x:1,y:1,r:1},
{x:2,y:2,r:2},
{x:3,y:3,r:3}
];
var body = d3.select("body");
var svg = body.append("svg").attr("width",250).attr("height",250);
var scaleX = d3.scaleLinear().range([0,250]);
var scaleY = d3.scaleLinear().range([0,250]);
function render(data){
//Data Binding
var circles = svg.selectAll("circle").data(data);
scaleX.domain(d3.extent(data,function(d){ return d.x; }));
scaleY.domain(d3.extent(data,function(d){ return d.y; }));
//Debugging (working correct --> 125)
circles
//Enter
.enter().apend("circle").attr("r",5)
//Update
.merge(circles)
.attr("cx", function (d){ return scaleX; })
.attr("cy", function (d){ return scaleY; });
//Exit
circles.exit().remove();
};
//Invoking the funktion with var xyr
render(xyr);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
</body>
</html>
First remove the <script> and </script> tags, those are throwing the errors. Second, you link v3 when your code is v4/5 (I used v4 in my snippet). Third you had some spelling mistakes that threw some errors. Lastly (and the biggest issue with d3 rendering), is with this:
.merge(circles)
.attr("cx", function (d){ return scaleX; })
.attr("cy", function (d){ return scaleY; });
which was missing the link to the data, which was updated to
.merge(circles)
.attr("cx", function (d){ return scaleX(d.x); })
.attr("cy", function (d){ return scaleY(d.y); });
var xyr = [{
x: 1,
y: 1,
r: 1
},
{
x: 2,
y: 2,
r: 2
},
{
x: 3,
y: 3,
r: 3
}
];
var body = d3.select("body");
var svg = body.append("svg").attr("width", 250).attr("height", 250);
var scaleX = d3.scaleLinear().range([0, 250]);
var scaleY = d3.scaleLinear().range([0, 250]);
function render(data) {
//Data Binding
var circles = svg.selectAll("circle").data(data);
scaleX.domain(d3.extent(data, function(d) {
return d.x;
}));
scaleY.domain(d3.extent(data, function(d) {
return d.y;
}));
//Debugging (working correct --> 125)
circles
//Enter
.enter().append("circle").attr("r", 5)
//Update
.merge(circles)
.attr("cx", function(d) {
return scaleX(d.x);
})
.attr("cy", function(d) {
return scaleY(d.y);
});
//Exit
circles.exit().remove();
};
//Invoking the funktion with var xyr
render(xyr);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
</body>
</html>

Cannot color svg elements in D3

I made a D3 map following Let's make a map tutorial by M. Bostock.
It is intended to create .subunit.id class and color it using CSS like .subunit.23 { fill: #f44242; }. But while .subunit is adressed well I can not reach each unit by specifying its id. Any ideas?
TopoJSON file is available here
https://gist.github.com/Avtan/649bbf5a28fd1f76278c752aca703d18
<!DOCTYPE html>
<meta charset="utf-8">
<html lang="en">
<style>
.subunit {
fill: #4286f4;
stroke: #efbfe9;}
.subunit.23 { fill: #f44242; }
</style>
<head>
<title>D3 Uzbekisztan map</title>
<meta charset="utf-8">
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script> -->
</head>
<body>
<script>
var width = 960,
height = 1160;
var projection = d3.geo.albers()
.center([-10, 40])
.rotate([-75, 0])
.parallels([38, 44])
.scale(4000)
.translate([width / 2, height / 2]);
var path = d3.geo.path()
.projection(projection);
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
d3.json("uzb_topo.json", function (error, uzb) {
if (error) return console.error(error);
console.log(uzb);
svg.selectAll(".subunit")
.data(topojson.feature(uzb, uzb.objects.uzb).features)
.enter().append("path")
.attr("class", function(d) { return "subunit " + d.id; })
.attr("d", path);
});
</script>
</body>
</html>
IDs cannot start by a number. Right now, you're setting two different classes, and the last one start with a number.
A simple solution is removing the space in your class name. So, this:
.attr("class", function(d) { return "subunit " + d.id; })
Should be this:
.attr("class", function(d) { return "subunit" + d.id; })//no space
And set your CSS accordingly.
Another solution is adding a letter before the number, like this:
.attr("class", function(d) { return "subunit " + "a" + d.id; })
So, you'll have the classes "a01", "a02", "a03" etc...

Starting out with d3.js visualizations

I'm new to d3.js. I just set up a local server and i'm trying to load a sample json file into my html file to play around with different visualizations. Nothing will display when i open it in my browser, & I'm getting this error in the console. "Uncaught TypeError: Cannot read property 'length' of null"
See code below. First block is the .html file and the second block is the sample .json. Thanks!
<!doctype html>
<html>
<head>
<title> D3 Arrays </title>
<script src="http://d3js.org/d3.v3.min.js"> </script>
</head>
<body>
<script>
d3.json("mydata.json", function (data) {
var canvas = d3.select("body").append("svg")
.attr("width", 500)
.attr("height", 500)
canvas.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("width", function (d) { return d.age * 10;})
.attr("height", 50)
.attr("y", function (d, i) { return i * 48; })
.attr("fill", "blue")
})
</script>
</body>
</html>
json data
[
{"name": "Judy", "age": 56},
{"name": "Glen", "age": 59},
{"name": "Dave", "age": 23}
]
Uncaught TypeError: Cannot read property 'length' of null
from the message, maybe you did not load the json correctly. you can check the data before
pass it to d3.
d3.json("mydata.json", function (data) {
console.log(data); // check the console output to judge if you get the data
var canvas = d3.select("body").append("svg")
.attr("width", 500)
.attr("height", 500)
canvas.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("width", function (d) { return d.age * 10;})
.attr("height", 50)
.attr("y", function (d, i) { return i * 48; })
.attr("fill", "blue")
})
i copy your code and data to http://jsfiddle.net/x5WzU/ and it works correctly
so:
check your server to check the path of mydata.json
The first argument in the d3.json callback is the error, and the second is the parsed data. If you don't have errors loading or parsing the data, your data variable will be null. You should use:
d3.json('mydata.json', function(error, data) {
if (error) {
console.error(error);
}
// visualization code...
});
Regards,

Categories