-
-
Save JackHowa/57ccead2fd6f7d2f40a49cf1990c4b2b to your computer and use it in GitHub Desktop.
d3 on fcc won't let be me |
https://learn.freecodecamp.org/data-visualization/data-visualization-with-d3/work-with-data-in-d3
- d3 has ... a data-driven approach
.data()
method attaches data to selected elements
A common workflow pattern is to create a new element in the document for each piece of data in the set. D3 has the enter() method for this purpose.
enter()
seems to fill in the gaps fordata()
attach
When enter() is combined with the data() method, it looks at the selected elements from the page and compares them to the number of data items in the set. If there are fewer elements than data items, it creates the missing elements.
enter()
seems kind of like a looper, for each item in dataset- you add a data item, new element appended
<body>
<script>
const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
// Add your code below this line
d3.select('body')
.selectAll('h2')
.data(dataset)
.enter()
.append('h2')
.text('New Title')
</script>
</body>
d
in callback function as argument refers to the data point- used string literal for interpolation with automatic return
`${d} USD`
The D3 text() method can take a string or a callback function as an argument:
selection.text((d) => d)
<body>
<script>
const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
d3.select("body").selectAll("h2")
.data(dataset)
.enter()
.append("h2")
.text(d => `${d} USD`);
</script>
</body>
- can get in-line styles via method
.style('color', 'red)
- sets style for all elements in the selection
<body>
<script>
const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
d3.select("body").selectAll("h2")
.data(dataset)
.enter()
.append("h2")
.text(d => d + " USD")
.style('font-family', 'verdana');
</script>
</body>
- woah this is cool
selection.style("color", (d) => {
/* Logic that returns the color based on a condition */
});
- used ternary here for readability with in-line
<body>
<script>
const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
d3.select("body").selectAll("h2")
.data(dataset)
.enter()
.append("h2")
.text((d) => (d + " USD"))
.style('color', d => d < 20 ? 'red' : 'green' );
</script>
</body>
https://learn.freecodecamp.org/data-visualization/data-visualization-with-d3/add-classes-with-d3
.attr()
is similar to.style()
because it can take in a callback function as an arg and it uses key-value pairs- d3 has
.attr()
to add any attribute to an element - adds class of 'container' :
selection.attr("class", "container");
- can assign multiple classnames to that target selection via space separated (stack)
<style>
.bar {
width: 25px;
height: 100px;
display: inline-block;
background-color: blue;
}
</style>
<body>
<script>
const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr('class', 'bar');
</script>
</body>
- can create pretty slick graph fairily easily ...
- dynamic height use
- alright add margin between the elements
- can multiple the height in-line, which is nice
https://learn.freecodecamp.org/data-visualization/data-visualization-with-d3/learn-about-svg-in-d3
- scalable in scalable vector graphic means that it won't be pixelated on any screen
added svg, still need to style ->-> not sure
<style>
svg {
background-color: pink;
}
</style>
<body>
<script>
const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
const w = 500;
const h = 100;
const svg = d3.select("body")
// Add your code below this line
.append('svg')
.style('height', h)
.style('width', (d) => w + 'px')
// Add your code above this line
</script>
</body>
- interestingly, width and height attributes don't have any units
-> it'll be 5:1 anywhere, cool - before was making the istake of adding a px at the end
<style>
svg {
background-color: pink;
}
</style>
<body>
<script>
const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
const w = 500;
const h = 100;
// attr feels a lot like jquery here
const svg = d3.select("body")
.append('svg')
.attr('height', h)
.attr('width', w);
</script>
</body>
https://learn.freecodecamp.org/data-visualization/data-visualization-with-d3/display-shapes-with-svg
- coordinates are done just via attributes as well
<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)
.append("rect")
.attr("width", 25)
.attr("height", 100)
.attr("x", 0)
.attr("y", 0)
</script>
</body>
rects
must be appended to an svg element before appended to the body
<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('svg') /* need to first append svg before rect */
.append('rect')
.attr("x", 0)
.attr("y", 0)
.attr("width", 25)
.attr("height", 100);
</script>
</body>
- loop through using a callback
- don't need to write a for-loop because enter() already go through the data
<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) /* es6 implicit return */
.attr("y", 0)
.attr("width", 25)
.attr("height", 100);
</script>
</body>
- can also return data value in the callback
<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", 0)
.attr("width", 25)
.attr("height", (d, i) => d * 3);
</script>
</body>
https://learn.freecodecamp.org/data-visualization/data-visualization-with-d3/invert-svg-elements
m
is typically the multiplier for the data relationship to the actual ratio-
In general, the relationship is y = h - m * d, where m is the constant that scales the data points.
- wanted to make the multiplication more explicit with parens
- have to accomodate how d3 scales things with the top upper being 0,0 by subtracting from height
<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>
fill
attribute is what makes up the elements
<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)
.attr('fill', 'navy')
</script>
</body>
- Not sure why
d
returns itself but ok, guess it could be anything - Weird have to subtract to go HIGHER
<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)
.attr("fill", "navy");
svg.selectAll("text")
.data(dataset)
.enter()
.append('text')
.attr('x', (d, i) => i * 30)
/* three units higher is subtraction */
.attr('y', (d, i) => h - (3 * d) - 3)
.text(d => d) /* returns d data value */
</script>
<body>
https://learn.freecodecamp.org/data-visualization/data-visualization-with-d3/style-d3-labels
- even text has a
fill
color property
<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) => d * 3)
.attr("fill", "navy");
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) => d)
.attr("x", (d, i) => i * 30)
.attr("y", (d, i) => h - (3 * d) - 3)
.style('font-size', '25px')
.style('fill', 'red')
</script>
</body>
- add a class via attr
<style>
.bar:hover {
fill: brown;
}
</style>
<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)
.attr("fill", "navy")
.attr('class', 'bar')
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) => d)
.attr("x", (d, i) => i * 30)
.attr("y", (d, i) => h - (3 * d) - 3);
</script>
</body>
https://learn.freecodecamp.org/data-visualization/data-visualization-with-d3/select-a-group-of-elements-with-d3
d3.selectAll('a')
would grab all the elements