freeCodeCamp/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/dynamically-set-the-coordin...

4.8 KiB

id title challengeType
587d7fa9367417b2b2512bce Dynamically Set the Coordinates for Each Bar 6

Description

The last challenge created and appended a rectangle to the svg element for each point in dataset to represent a bar. Unfortunately, they were all stacked on top of each other. The placement of a rectangle is handled by the x and y attributes. They tell D3 where to start drawing the shape in the svg area. The last challenge set them each to 0, so every bar was placed in the upper-left corner. For a bar chart, all of the bars should sit on the same vertical level, which means the y value stays the same (at 0) for all bars. The x value, however, needs to change as you add new bars. Remember that larger x values push items farther to the right. As you go through the array elements in dataset, the x value should increase. The attr() method in D3 accepts a callback function to dynamically set that attribute. The callback function takes two arguments, one for the data point itself (usually d) and one for the index of the data point in the array. The second argument for the index is optional. Here's the format:
selection.attr("property", (d, i) => {
  /* 
  * d is the data point value
  * i is the index of the data point in the array
  */
})

It's important to note that you do NOT need to write a for loop or use forEach() to iterate over the items in the data set. Recall that the data() method parses the data set, and any method that's chained after data() is run once for each item in the data set.

Instructions

Change the x attribute callback function so it returns the index times 30. Note
Each bar has a width of 25, so increasing each x value by 30 adds some space between the bars. Any value greater than 25 would work in this example.

Tests

tests:
  - text: The first <code>rect</code> should have an <code>x</code> value of 0.
    testString: assert($('rect').eq(0).attr('x') == '0', 'The first <code>rect</code> should have an <code>x</code> value of 0.');
  - text: The second <code>rect</code> should have an <code>x</code> value of 30.
    testString: assert($('rect').eq(1).attr('x') == '30', 'The second <code>rect</code> should have an <code>x</code> value of 30.');
  - text: The third <code>rect</code> should have an <code>x</code> value of 60.
    testString: assert($('rect').eq(2).attr('x') == '60', 'The third <code>rect</code> should have an <code>x</code> value of 60.');
  - text: The fourth <code>rect</code> should have an <code>x</code> value of 90.
    testString: assert($('rect').eq(3).attr('x') == '90', 'The fourth <code>rect</code> should have an <code>x</code> value of 90.');
  - text: The fifth <code>rect</code> should have an <code>x</code> value of 120.
    testString: assert($('rect').eq(4).attr('x') == '120', 'The fifth <code>rect</code> should have an <code>x</code> value of 120.');
  - text: The sixth <code>rect</code> should have an <code>x</code> value of 150.
    testString: assert($('rect').eq(5).attr('x') == '150', 'The sixth <code>rect</code> should have an <code>x</code> value of 150.');
  - text: The seventh <code>rect</code> should have an <code>x</code> value of 180.
    testString: assert($('rect').eq(6).attr('x') == '180', 'The seventh <code>rect</code> should have an <code>x</code> value of 180.');
  - text: The eighth <code>rect</code> should have an <code>x</code> value of 210.
    testString: assert($('rect').eq(7).attr('x') == '210', 'The eighth <code>rect</code> should have an <code>x</code> value of 210.');
  - text: The ninth <code>rect</code> should have an <code>x</code> value of 240.
    testString: assert($('rect').eq(8).attr('x') == '240', 'The ninth <code>rect</code> should have an <code>x</code> value of 240.');

Challenge Seed

<body>
  <script>
    const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];

    const w = 500;
    const h = 100;

    const svg = d3.select("body")
                  .append("svg")
                  .attr("width", w)
                  .attr("height", h);

    svg.selectAll("rect")
       .data(dataset)
       .enter()
       .append("rect")
       .attr("x", (d, i) => {
         // Add your code below this line



         // Add your code above this line
       })
       .attr("y", 0)
       .attr("width", 25)
       .attr("height", 100);
  </script>
</body>

Solution

// solution required