Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 878
tiffknee Avatar asked Dec 08 '25 09:12

tiffknee


1 Answers

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>
like image 198
Gerardo Furtado Avatar answered Dec 10 '25 23:12

Gerardo Furtado



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!