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
let dataSet;
let data;
function readTextFile(file, callback) {
    var rawFile = new XMLHttpRequest();
    rawFile.overrideMimeType("application/json");
    rawFile.open("GET", file, true);
    rawFile.onreadystatechange = function() {
        if (rawFile.readyState === 4 && rawFile.status == "200") {
            callback(rawFile.responseText);
        }
    }
    rawFile.send(null);
}
//usage: 
readTextFile("https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/GDP-data.json", function(text){
    data = JSON.parse(text);
      dataSet = data["data"]
    console.log(dataSet);
});
const w = 700;
const h = 500;
const svg = d3.select("body")
  .append("svg")
  .attr("width",w)
  .attr("heigth",h)
  .attr("style", "outline: thin solid red;");
svg.selectAll("rect")
  .data(dataSet)
  .enter()
       .append("rect")
       .attr("x", (d,i) => d[1][i]+ 10)
       .attr("y", (d, i) => 0 )
       .attr("width", 25)
       .attr("height", (d, i) => d[1] /2 )
       .attr("fill", "navy")
       .attr("class", "bar")
       .append("title")
       .text((d) => d)
  svg.selectAll("text")
       .data(dataSet)
       .enter()
       .append("text")
       .text((d) => d)
       .attr("x", (d, i) => i * 30 +10)
       .attr("y", (d, i) => 15)
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:
readTextFile("https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/GDP-data.json", function(text){
    data = JSON.parse(text);
      dataSet = data["data"]
    console.log(dataSet);
    // Add d3 logic here
    const w = 700;
const h = 500;
const svg = d3.select("body")
  .append("svg")
  .attr("width",w)
  .attr("heigth",h)
  .attr("style", "outline: thin solid red;");
svg.selectAll("rect")
  .data(dataSet)
  .enter()
       .append("rect")
        // Changed this line to remove the [i]
       .attr("x", (d,i) => d[1] + 10)
       .attr("y", (d, i) => 0 )
       .attr("width", 25)
       .attr("height", (d, i) => d[1] /2 )
       .attr("fill", "navy")
       .attr("class", "bar")
       .append("title")
       .text((d) => d)
  svg.selectAll("text")
       .data(dataSet)
       .enter()
       .append("text")
       .text((d) => d)
       .attr("x", (d, i) => i * 30 +10)
       .attr("y", (d, i) => 15)
});
To avoid callback you could wrap the response to readTextFile in a Promise and then use async/await to dataSet = await readTextFile(...).