简体   繁体   中英

How to retrieve nested values in a JSON file using D3/JS?

I am struggling to find a way to call data from a json URL due to the way it is nested, shown below.

[
{"data":
  "Aatrox":
    "id": "Aatrox"
    "hp": "500"
   "Ashe":
     "id": "Ashe"
     "hp": "350"
}]

I am trying to use the 'hp' value as the height data point for a bar graph using d3.js, and using the 'id' value as a label under each bar, but I'm unsure how to call upon the data and store it in variables that I can use in my d3 code.

d3.json("https://ddragon.leagueoflegends.com/cdn/4.7.16/data/em_us/champion.json
", function(data) {
console.log(data);
});

Currently I'm just logging the data in the console because I'm not sure how to store the specific parts of it that I want in a variable.

How to retrieve the key values of a nested data set in D3

This question helped me a little bit as a starting point but I'm still not totally sure how to proceed.

The main issue I am having is the file structure of the JSON is a bit strange and I'm not sure what 'x' would be in the case that I wanted to pull just 'hp' in:

data.'x'.stats.hp

In D3, the data() function accepts three things:

  1. An array
  2. A function
  3. Nothing

Right now, your JSON contains just a bunch of nested objects:

{
    "data": {
        "Aatrox": {...
        },
        "Ahri": {...
        }
    }
}

Thus, the first step is converting this into an array of objects, which we can use to bind data. There are several ways for doing that, this one being easy for a beginner:

var data = [];
var obj = json.data;
for (var key in obj) {
    data.push(obj[key])
}

Now that we have an array of objects (named data ), like this...

[{
    id: "Aatrox"
}, {
    id: "Ahri"
}]

... we can get the hp property:

.attr('width', function(d) {
    return scale(d.stats.hp)
}) 

Here is a working demo using your code and changing the data array only:

  var canvas = d3.select('body').append('svg') .attr('width', 500) .attr('height', 500) d3.json("https://ddragon.leagueoflegends.com/cdn/4.7.16/data/en_US/champion.json", function(json) { var data = []; var obj = json.data; for (var key in obj) { data.push(obj[key]) } var scale = d3.scaleLinear() .domain([0, d3.max(data, function(d) { return d.stats.hp })]) .range([0, 500]); canvas.selectAll('rect') .data(data) .enter() .append('rect') .attr('width', function(d) { return scale(d.stats.hp) }) .attr('height', 6) .attr('y', function(d, i) { return i * 7 }) .attr('fill', 'blue') }); 
 <script src="https://d3js.org/d3.v4.min.js"></script> 

you can use like this.

d3.json("https://ddragon.leagueoflegends.com/cdn/4.7.16/data/em_us/champion.json
", function(data) {
    console.log(data);
    var canvas = d3.select('body').append('svg');
    canvas.selectAll('rect')
        .data(Object.values(data.data))
        .enter()
        .append('rect')
        .attr('y', function(d) {
            return d.stats.hp;
        });

    canvas.selectAll('text')
        .data(Object.values(data.data))
        .enter()
        .append('text')
        .text(function(d) {
            return d.id
        });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM