Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In D3, how can I create multiple elements for each data element based on value in data?

I have a simple array with objects for my data and I generate divs from it. Instead of creating only one div for each data element, I would like to create several divs, depends on the number that appears in the data (as one of the object's properties).

For example in case that the "num" for a data element is 4, it will generate 4 divs.

Here is the code I have for this part:

data = [
  {num: 4, category: 'A'},
  {num: 3, category: 'B'},  
  {num: 2, category: 'D'},  
  {num: 5, category: 'A'}    
]

d3.select('body')
  .selectAll('div')
  .data(data)
  .enter()
  .append('div')
  .text((d)=> d.num)
  .style('width', (d) => d.num * 20 + "px")

I've tried to solve it with a for loop but I'm not sure how to loop in the middle of a d3 selection, while still having access to the data.

Any idea would be very much appreciated!

like image 952
Vered R Avatar asked Oct 19 '25 05:10

Vered R


1 Answers

Here's how I'd do it:

<!DOCTYPE html>
<html>

<head>
  <script data-require="[email protected]" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>

<body>
  <script>
    data = [{
      num: 4,
      category: 'A'
    }, {
      num: 3,
      category: 'B'
    }, {
      num: 2,
      category: 'D'
    }, {
      num: 5,
      category: 'A'
    }]

    d3.select('body')
      .selectAll('div')
      .data(data) // bind our data
      .enter()
      // inner selection
      .selectAll('div')
      // inner selection data binding
      // creates array of repeating datum that is length of num
      .data((d) =>
        d3.range(d.num).map(() => d)
      ) 
      .enter()
      .append('div')
      .text((d) => d.num)
      .style('width', (d) => d.num * 20 + "px");
  </script>
</body>

</html>
like image 113
Mark Avatar answered Oct 21 '25 18:10

Mark



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!