简体   繁体   中英

Using D3 to access nested JSON data

I'm trying to make a table of a nested JSON dataset. I was able to retrieve some of the values ("time", "humidity", "temp"), but so far have been unsuccessful at accessing the nested objects ("FSR_1" ... "FSR_3").

The following code returned no errors, but row[Object.keys(row)[i].resistance] does not return the values from the dataset:

d3.json("test.json", function(error, data){

    var columns = Object.keys(data[0]);

    var table = d3.select("body").append("table"),
    thead = table.append("thead")
    .attr("class", "thead");

    tbody = table.append("tbody");

    thead.append("tr").selectAll("th")
    .data(columns)
    .enter()
    .append("th")
    .text(function(d) { return d; })
    .on("click", function(header, i) {
      tbody.selectAll("tr").sort(function(a, b) {
        return d3.descending(a[header], b[header]);
      });
    });

    var rows = tbody.selectAll("tr.row")
    .data(data)
    .enter()
    .append("tr").attr("class", "row");

    var cells = rows.selectAll("td")
    .data(function(row) {
      return d3.range(Object.keys(row).length).map(function(column, i) {
        return i < 3 ? row[Object.keys(row)[i]] : row[Object.keys(row)[i].resistance];
      });
    })
    .enter()
    .append("td")
    .text(function(d) { return d; })

  });

The data structure looks something like this:

[
{
  "time": 1388477,
  "humidity": 30.7,
  "temp": 34.3,
  "FSR_1": {
    "resistance": 6744,
    "force": 1
  },
  "FSR_2": {
    "resistance": 11682,
    "force": 1
  },
  "FSR_3": {
    "resistance": 12143,
    "force": 1
  }
},
{
  "time": 1448863,
  "humidity": 31.3,
  "temp": 34.1,
  "FSR_1": {
    "resistance": 6829,
    "force": 1
  },
  "FSR_2": {
    "resistance": 11231,
    "force": 1
  },
  "FSR_3": {
    "resistance": 11186,
    "force": 1
  }
}
]

If anyone can point me in the right direction, I'd really appreciate it!

resistance is not part of the bracket notation to get the outer object's property name. Therefore, move it to after the bracket notation:

return i < 3 ? row[Object.keys(row)[i]] : row[Object.keys(row)[i]].resistance;
//outside the bracket notation ----------------------------------^

Not related to your question, but Object.keys() already returns an array. Since you're using the index in the map method, you can drop that d3.range . So, instead of:

d3.range(Object.keys(row).length).map(etc...

It can be just:

Object.keys(row).map(etc...

Here is the resulting code:

 var data = [{ "time": 1388477, "humidity": 30.7, "temp": 34.3, "FSR_1": { "resistance": 6744, "force": 1 }, "FSR_2": { "resistance": 11682, "force": 1 }, "FSR_3": { "resistance": 12143, "force": 1 } }, { "time": 1448863, "humidity": 31.3, "temp": 34.1, "FSR_1": { "resistance": 6829, "force": 1 }, "FSR_2": { "resistance": 11231, "force": 1 }, "FSR_3": { "resistance": 11186, "force": 1 } } ]; var columns = Object.keys(data[0]); var table = d3.select("body").append("table"), thead = table.append("thead") .attr("class", "thead"); tbody = table.append("tbody"); thead.append("tr").selectAll("th") .data(columns) .enter() .append("th") .text(function(d) { return d; }) .on("click", function(header, i) { tbody.selectAll("tr").sort(function(a, b) { return d3.descending(a[header], b[header]); }); }); var rows = tbody.selectAll("tr.row") .data(data) .enter() .append("tr").attr("class", "row"); var cells = rows.selectAll("td") .data(function(row) { return Object.keys(row).map(function(column, i) { return i < 3 ? row[Object.keys(row)[i]] : row[Object.keys(row)[i]].resistance; }); }) .enter() .append("td") .text(function(d) { return d; }) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> 

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