freeCodeCamp/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/invert-svg-elements.md

144 lines
3.7 KiB
Markdown

---
id: 587d7fa9367417b2b2512bd0
title: Invert SVG Elements
challengeType: 6
forumTopicId: 301488
dashedName: invert-svg-elements
---
# --description--
You may have noticed the bar chart looked like it's upside-down, or inverted. This is because of how SVG uses (x, y) coordinates.
In SVG, the origin point for the coordinates is in the upper-left corner. An `x` coordinate of 0 places a shape on the left edge of the SVG area. A `y` coordinate of 0 places a shape on the top edge of the SVG area. Higher `x` values push the rectangle to the right. Higher `y` values push the rectangle down.
To make the bars right-side-up, you need to change the way the `y` coordinate is calculated. It needs to account for both the height of the bar and the total height of the SVG area.
The height of the SVG area is 100. If you have a data point of 0 in the set, you would want the bar to start at the bottom of the SVG area (not the top). To do this, the `y` coordinate needs a value of 100. If the data point value were 1, you would start with a `y` coordinate of 100 to set the bar at the bottom. Then you need to account for the height of the bar of 1, so the final `y` coordinate would be 99.
The `y` coordinate that is `y = heightOfSVG - heightOfBar` would place the bars right-side-up.
# --instructions--
Change the callback function for the `y` attribute to set the bars right-side-up. Remember that the `height` of the bar is 3 times the data value `d`.
**Note:** In general, the relationship is `y = h - m * d`, where `m` is the constant that scales the data points.
# --hints--
The first `rect` should have a `y` value of `64`.
```js
assert($('rect').eq(0).attr('y') == h - dataset[0] * 3);
```
The second `rect` should have a `y` value of `7`.
```js
assert($('rect').eq(1).attr('y') == h - dataset[1] * 3);
```
The third `rect` should have a `y` value of `34`.
```js
assert($('rect').eq(2).attr('y') == h - dataset[2] * 3);
```
The fourth `rect` should have a `y` value of `49`.
```js
assert($('rect').eq(3).attr('y') == h - dataset[3] * 3);
```
The fifth `rect` should have a `y` value of `25`.
```js
assert($('rect').eq(4).attr('y') == h - dataset[4] * 3);
```
The sixth `rect` should have a `y` value of `46`.
```js
assert($('rect').eq(5).attr('y') == h - dataset[5] * 3);
```
The seventh `rect` should have a `y` value of `13`.
```js
assert($('rect').eq(6).attr('y') == h - dataset[6] * 3);
```
The eighth `rect` should have a `y` value of `58`.
```js
assert($('rect').eq(7).attr('y') == h - dataset[7] * 3);
```
The ninth `rect` should have a `y` value of `73`.
```js
assert($('rect').eq(8).attr('y') == h - dataset[8] * 3);
```
# --seed--
## --seed-contents--
```html
<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) => i * 30)
.attr("y", (d, i) => {
// Add your code below this line
// Add your code above this line
})
.attr("width", 25)
.attr("height", (d, i) => 3 * d);
</script>
</body>
```
# --solutions--
```html
<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) => i * 30)
.attr("y", (d, i) => h - 3 * d)
.attr("width", 25)
.attr("height", (d, i) => 3 * d);
</script>
</body>
```