MayaGans
MayaGans

Reputation: 1845

D3.js scatterplot from nested object

I want to create a simple scatter plot looping through the X and Y in a nested object. I know how to make a scatterplot from a simple array of X, Y values but was hoping to get some help looping through the nested X and Y values. Do I need to be using a forEach or some other functional operation in order to access these values? Any help appreciated!

//Width and height
    var w = 500;
    var h = 100;

    var dataset = [
      {
        "key": 1,
        "sub_object": [
          { "name": "A", "X": 1, "Y": 1 },
          { "name": "B", "X": 2, "Y": 2 },
          { "name": "C", "X": 3, "Y": 3 },
          { "name": "D", "X": 4, "Y": 4 },
          { "name": "E", "X": 5, "Y": 5 }
        ]
      }
    ]

    //Create SVG element
    var svg = d3.select("body")
      .append("svg")
      .attr("width", w)
      .attr("height", h);

    svg.selectAll("circle")
      .data(dataset)
      .enter()
      .append("circle")
      .attr("cx", function (d) {
        return dataset.sub_object.X;
      })
      .attr("cy", function (d) {
        return dataset.sub_object.Y;
      })

      .attr("r", function (d) {
        return Math.sqrt((h - dataset.sub_object.Y))
      });
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.13/d3.js"></script>
</head>

<body>
</body>

</html>

Upvotes: 0

Views: 429

Answers (1)

Mark
Mark

Reputation: 92461

Generally speaking, you will often need to process your data to be in a form that is convenient for D3. How you do that depends on the data you are trying to display.

For example for a simple X,Y plot from your data you could make an array of simple X,Y objects which you know how to plot:

var dataset = [
      {
        "key": 1,
        "sub_object": [
          { "name": "A", "X": 1, "Y": 1 },
          { "name": "B", "X": 2, "Y": 2 },
          { "name": "C", "X": 3, "Y": 3 },
          { "name": "D", "X": 4, "Y": 4 },
          { "name": "E", "X": 5, "Y": 5 }
        ]
      }
    ]
let processedData = dataset.reduce((arr, obj) => {
    return arr.concat(obj.sub_object.map(({X, Y}) => ({X, Y})))
  }, [])
  
 // simple array of X, Y objects
 console.log(processedData)

Then in D3, just make sure you are using the d argument passed to the functions to get the X and Y values.

//Width and height
    var w = 500;
    var h = 100;

    var dataset = [
      {
        "key": 1,
        "sub_object": [
          { "name": "A", "X": 1, "Y": 1 },
          { "name": "B", "X": 2, "Y": 2 },
          { "name": "C", "X": 3, "Y": 3 },
          { "name": "D", "X": 4, "Y": 4 },
          { "name": "E", "X": 5, "Y": 5 }
        ]
      }
    ]

  // transform data into convenient form:
  let processedData = dataset.reduce((arr, obj) => {
    return arr.concat(obj.sub_object.map(({X, Y}) => ({X, Y})))
  }, [])

    //Create SVG element
    var svg = d3.select("body")
      .append("svg")
      .attr("width", w)
      .attr("height", h);

    svg.selectAll("circle")
      .data(processedData)
      .enter()
      .append("circle")
      .attr("cx", function (d) {
        return d.X*19;
      })
      .attr("cy", function (d) {
        return d.Y*19;
      })

      .attr("r", function (d) {
        return 2
      });
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.13/d3.js"></script>
</head>

<body>
</body>

</html>

Upvotes: 1

Related Questions