I’m doing a project to learn d3 visualization and I’m stack recs aren’t appearing. Could you help me?
I tried to put a simple array for data and it worked, I could only flip y, but with this JSON data. nothing works
https://codepen.io/DeanWinchester88/pen/XWgjjeW
JavaScript
x
50
50
1
let dataSet;
2
let data;
3
function readTextFile(file, callback) {
4
var rawFile = new XMLHttpRequest();
5
rawFile.overrideMimeType("application/json");
6
rawFile.open("GET", file, true);
7
rawFile.onreadystatechange = function() {
8
if (rawFile.readyState === 4 && rawFile.status == "200") {
9
callback(rawFile.responseText);
10
}
11
}
12
rawFile.send(null);
13
}
14
//usage:
15
readTextFile("https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/GDP-data.json", function(text){
16
data = JSON.parse(text);
17
dataSet = data["data"]
18
console.log(dataSet);
19
});
20
21
const w = 700;
22
const h = 500;
23
24
const svg = d3.select("body")
25
.append("svg")
26
.attr("width",w)
27
.attr("heigth",h)
28
.attr("style", "outline: thin solid red;");
29
30
svg.selectAll("rect")
31
.data(dataSet)
32
.enter()
33
.append("rect")
34
.attr("x", (d,i) => d[1][i]+ 10)
35
.attr("y", (d, i) => 0 )
36
.attr("width", 25)
37
.attr("height", (d, i) => d[1] /2 )
38
.attr("fill", "navy")
39
.attr("class", "bar")
40
.append("title")
41
.text((d) => d)
42
43
svg.selectAll("text")
44
.data(dataSet)
45
.enter()
46
.append("text")
47
.text((d) => d)
48
.attr("x", (d, i) => i * 30 +10)
49
.attr("y", (d, i) => 15)
50
Advertisement
Answer
The issue is that XMLHttpRequest
is asynchronous and you are defining the d3 logic outside of the callback passed to readTextFile
. The easiest solution would be to include the d3 logic inside of the callback:
JavaScript
1
38
38
1
readTextFile("https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/GDP-data.json", function(text){
2
data = JSON.parse(text);
3
dataSet = data["data"]
4
console.log(dataSet);
5
// Add d3 logic here
6
const w = 700;
7
const h = 500;
8
9
const svg = d3.select("body")
10
.append("svg")
11
.attr("width",w)
12
.attr("heigth",h)
13
.attr("style", "outline: thin solid red;");
14
15
svg.selectAll("rect")
16
.data(dataSet)
17
.enter()
18
.append("rect")
19
// Changed this line to remove the [i]
20
.attr("x", (d,i) => d[1] + 10)
21
.attr("y", (d, i) => 0 )
22
.attr("width", 25)
23
.attr("height", (d, i) => d[1] /2 )
24
.attr("fill", "navy")
25
.attr("class", "bar")
26
.append("title")
27
.text((d) => d)
28
29
svg.selectAll("text")
30
.data(dataSet)
31
.enter()
32
.append("text")
33
.text((d) => d)
34
.attr("x", (d, i) => i * 30 +10)
35
.attr("y", (d, i) => 15)
36
37
});
38
To avoid callback you could wrap the response to readTextFile
in a Promise
and then use async/await
to dataSet = await readTextFile(...)
.