Closed QuincyLarson closed 7 years ago
What I think it could work is the following: Based on reference: http://chimera.labs.oreilly.com/books/1230000000345/index.html
Other chapters (7 and 8) are about adding components and styling the just-created charts, but I think that those 8 points given above would cover the basis. I think they could be split in 3-5 exercises (average) per point, but I would emphasis on point 6 and more specially point 7, which is one of the most difficult things to understand, IMO.
Working with transitions and layouts (Ch 9 and beyond) is important but better if you master the Enter-Update-Exit cycle and understand selections and appends FIRST. Also, the selection can add hard-to-debug errors (silent ones) that would affect the whole cycle. What I haven't seen in practice but not in tutorials is the impact of wrongly coding selections and appends. Sometimes the chaining nature of JS could play you a trick. I would recommend to find and include 1 to 3 exercises working with selections that involve the SVG group element in ways that are prone to error and try to debug. The group element is an important one that could be tricky to handle.
Also, the book was very helpful in suggesting ideas of how to debug d3.js but there is no specific chapter.
Some advice from a professor teaching D3.js to her journalism class that may help develop this portion of the curriculum http://blogger.ghostweather.com/2016/01/teaching-semester-of-d3js.html
Possible Related Exercises (TENTATIVE LIST):
[] d3 select
:
Select ONE paragraph element and add the following text "This is a paragraph!"
[] d3 selectAll
and data
:
Select SEVERAL paragraph elements and take the previous exercise but write "This is paragraph!" for 5 paragraph elements using the following list [ 5, 10, 15, 20, 25 ]
[] d3 accessing data
:
Take the previous list but write "This is the value x" for 5 paragraph elements using the following list [ 5, 10, 15, 20, 25 ]; substitute x by the value of the list using an anonymous function when writing the text
[] d3 modifying attributes:
Take the following css bar
div.bar { display: inline-block; width: 20px; height: 75px; /* We'll override height later */ background-color: teal; }
make a selectAll for bar class, and modify its height with the list from previous exercise
[] d3 - just testing a new list:
Use previous exercise but use this list instead: [ 25, 7, 5, 26, 11, 8, 25, 14, 23, 19, 14, 11, 22, 29, 11, 13, 12, 17, 18, 10, 24, 18, 25, 9, 3 ]
[] d3 working with svg:
Select/Append a non-existing svg; use the following width and height = [400,400] as svg attributes
[] d3 appending circles:
Select/Append several svg
circle
to the svg above, using the list above to add attribute radius. Use the following function:circles.attr("cx", function(d, i) { return (i * 50) + 25; }) .attr("cy", h/2) .attr("r", function(d) { return d; });
to spread the position of those circles
[] d3 creating bars with rect
:
Use the same list to draw bars: use shape
rect
instead
[] d3 more about working with rect
to create bars:
Correct spacing between bars functionally using padding attritute of the rectshape using the following
.attr("width", w / dataset.length - barPadding)
[] d3 understanding svg coordinates:
Correct bar direction by modifying the height and y attributes of the selected
rect
shapes accordingly; Remember: svg coordinates start at x=0, y=0 at the top-left and it is always positive through out the whole svg area
[] d3 attribute color:
Color you bars: makes them all look blue!
[] d3 preparing for Enter-Update-Exit:
Take your previous bars, but only for the following list [15, 8, 42, 4]
[] d3 preparing for Update:
Build an update function: add all the functionality but the list into an update function:
function update(){...}
and then call the function
[] d3 Enter:
Substitute the list by adding a value: [15, 8, 42, 4, 32], and add and
enter()
step to your update function
[] d3 Using event for Update:
Add an event to the update function and see what happens:
.on(“click”, function(e, i){ numbers.splice(i, 1); update(); })
[] d3 Exit:
Now add the following line at the end of your update function and see what happens:
selection.exit().remove();
@QuincyLarson : FYI I have already mentioned in a post in the CT area and the DSR that d3.js v4 is already launched and it is a bit different (apparently easier) than the usual version, 3.x.
@QuincyLarson I think the only way to test if the exercises are correct is by evaluating that the tags, elements and attributes are correct, so it is about checking the html for having an specific structure. Exercises should be then VERY specific to avoid correct behaviours but incorrect html structures. I see this in general as a parsing of the html and comparing against a template html.
@evaristoc yes - we should definitely focus on d3.js v4.
I agree with you on making sure that the exercises are very specific. All challenges should basically ask the camper to do exactly one task. The less ambiguous, the better (as ambiguity tends to make people get frustrated and quit - campers can cope with ambiguity when they reach the projects).
This might be outdated with the new version of D3. But here's the original post in its entirety.
I imagine that the D3 Waypoints will be very similar to the jQuery waypoints structure wise. Meaning there will be HTML/CSS/JS breakdown on the page.
d3.select()
append()
[ ] attr()
selectAll()
data()
enter()
exit()
style()
text()
d3.scale.linear()
domain()
extent()
min()
max()
range()
axis()
scale()
orient()
tick()
tickPadding()
call()
d3.time.scale()
d3.time.format()
d3.xhr()
.header()
.response()
@cdikibo Sounds a very comprehensive lists. I will let you lead the process, as I cannot take ownership of the activities related to this project. Please count on my support, I will be helping this section.
Hope the exercises I am proposing fit your list?
Quincy wrote to me:
if you could come up with titles for these challenges (in addition to your descriptions) and the sequence in which you think we should teach htem, that would be really helpfull.
I would say, @cdikibo: [x] Sequence: as suggested in my list [x] Adding names to each exercise
See guidelines given by Quincy at the beginning of this thread
See https://github.com/FreeCodeCamp/CurriculumExpansion/issues/10#issuecomment-230450274, https://github.com/FreeCodeCamp/CurriculumExpansion/issues/6#issue-163615115
The closer to this type of outcome, the better
I'll take ownership of these challenges. I'll have another list of potential exercises and their names coming out soon.
@cdikibo Thank you for taking ownership of these challenges. I will be around https://gitter.im/freecodecamp/curriculumdevelopment all weekend helping coordinate this. Let me know if I can help with anything 😄
@cdikibo Have you had a chance to work on that list of potential exercises? Please let me know whether I can do anything to help.
@cdikibo any update on this? These challenges are one of our highest priority and we'd love to get these shipped!
cc/ @QuincyLarson
@atjonathan I think we have another candidate for a topic that need an owner. I don't know what happened to @cdikibo - I hope she is OK.
@QuincyLarson I think @elibei might be interested in contributing as well.
@alayek yes, thanks for this suggestion :)
@elibei just finished a nonprofit project. I've reached out on Gitter to see whether @elibei is up for taking over these D3 challenges.
Challenge Text
D3 JS lets you add, edit, or delete documents based on data. In this exercise, we shall start with adding a simple text in the page; using D3.
The
select()
function lets you pick the first element that matches the input string.const anchor = d3.select("a");
It returns an HTML node, on which you can use even binding functions.
Similarly, there are
append()
andtext()
functions.The
append()
function appends a HTML node, and returns a handle to the nodeThe
text()
function either sets the text of the selected node, or gets the current text. To set the value, you would have to pass a string as argument.
Challenge Instructions
Add the text
"Learning D3"
in the empty webpage. Target thebody
node using D3select
and append a<h1>
tag, whose text is the desired string.
Note
You can chain three functions mentioned above. Also, use string to select tags, not HTML notation. For example, if you want to append or select
<h2>
, use"h2"
.
Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
/* Add your code below */
/* Add your code above */
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has h2
// Check if h2 has the text "Learning D3"
// Check if the code uses d3.select().append().text()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
d3.select("body").append("h1").text("Learning D3 Again!");
</script>
</body>
</html>
Challenge Text
As stated earlier, D3 JS focuses on data-driven approach. So, let's start by working with an array of data.
We want to display some things on the webpage based on the data at hand.
To make D3 aware of the data we have, we have to use the
data()
function and pass our array into the function.We would also need to use
enter()
function, which is used to create missing elements in-memory before rendering.Say, you want to create 5 lines of texts, based on 5 entries of the array. Then you need to call
enter()
on the selection, before proceeding to creating the text elements.
Helpful links
Challenge Instructions
Target the
body
node using D3select
and append as many<h1>
tags as many are there elements in the array
Note
You can chain the functions mentioned above. Also, use string to select tags, not HTML notation. For example, if you want to append or select
<h2>
, use"h2"
.
Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
var dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5]
/* Add your code below */
/* Add your code above */
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
var dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5]
/* Add your code below */
d3.select("body").selectAll("h1")
.data(dataset)
.enter()
.append("h1")
.text('New Title');
/* Add your code above */
</script>
</body>
</html>
Challenge Text
We have learned the tools to display dynamic data.
Let's start with displaying array elements.
We have already learned about
data()
function andenter()
; to pass an array to D3 and let it display some text according to the number of data elements present.But now it's time we display the actual data, no cloak-and-dagger about it. We need to modify the
text()
function we had used earlier.The
text()
function takes a callback, where you can simply return the argument to callback to display the data. Obviously, the argument to callback is an invidual data-point itself.selection.text((d) => d)
Helpful links
Challenge Instructions
Display the content of the array, and append "USD" (with a space; like
"10 USD"
) to each of them. Useh1
to hold each node.
Note
You can chain the functions mentioned above. Also, use string to select tags, not HTML notation. For example, if you want to append or select
<h2>
, use"h2"
.
Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
var dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5]
/* Add your code below */
/* Add your code above */
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
var dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5]
/* Add your code below */
d3.select("body").selectAll("h1")
.data(dataset)
.enter()
.append("h1")
.text((d) => d + " USD ");
/* Add your code above */
</script>
</body>
</html>
Challenge Text
We can use
style()
function on anyselection
in D3, to give the rendered value an inline style.The input to the
style()
function can be a comma-separated key value pair.selection.style("color","blue");
Helpful links
Challenge Instructions
Turn all the displayed text into verdana font.
Note
Use
font-family
property.
Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
d3.select("body").selectAll("h1")
.data(dataset)
.enter()
.append("h2")
.text((d) => ("Value : " + d))
/* Add your code below */
/* Add your code above */
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
d3.select("body").selectAll("h1")
.data(dataset)
.enter()
.append("h2")
.text((d) => ("Value : " + d))
/* Add your code below */
.style('font-family', 'verdana')
/* Add your code above */
</script>
</body>
</html>
@alayek can you please test if my code is correct when using ES6? Not installed in my case..
This exercise should be broken in different stages though...
-- Challenge Text
Change attributes of bars created using css attributes on div elements
//Someone else can work on this please?
-- Helpful links
//Someone else can work on this please?
-- Challenge Instructions
//Someone else can work on this please?
-- Challenge Seed
--- Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
div.bar {
display: inline-block;
width: 20px;
height: 75px; /* We'll override height later */
background-color: teal;
}
</style>
</head>
<body>
<script type="text/javascript">
var dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5]
/* Add your code below */
/* Add your code above */
</script>
</body>
</html>
Challenge Tests
// TODO //Someone else please?
-- Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
div.bar {
display: inline-block;
width: 20px;
height: 75px; /* We'll override height later */
background-color: teal;
}
</style>
</head>
<body>
<script type="text/javascript">
var dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5]
/* Add your code below */
d3.select("body").selectAll(".bar")
.data(dataset)
.enter()
.append("div")
.attr("class", "bar")
.style("height", (d) => (d + "px"));
/* Add your code above */
</script>
</body>
</html>
Challenge Text
Since D3 is all about visualization and presentation of data, it is expected that, you would need to provide some logic in your styling
In this challenge, we would render styling conditionally on each data element.
Say, we would want to color each data point blue, if they are less than 20; else red.
We can pass this as an
if-else
logic into thestyle()
function. It accepts a callback, which has each of the data point as its argument.selection.style("color", (d) => { /* Some logic that returns conditional value of color */ });
This can be used with other properties as well.
Helpful links
Challenge Instructions
Write the callback function that returns proper styling - for data element value less than 20, returns `"color",
Note
You can also use ternary operator.
Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
d3.select("body").selectAll("h1")
.data(dataset)
.enter()
.append("h1")
.text((d) => ("Value : " + d))
/* Add your code below */
/* Add your code above */
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
d3.select("body").selectAll("h1")
.data(dataset)
.enter()
.append("h2")
.text((d) => ("Value : " + d))
/* Add your code below */
.style("color", d => d >= 20 ? "red" : "blue");
/* Add your code above */
</script>
</body>
</html>
Challenge Text
It's not always a good idea to keep adding inline styles in HTML elements. It could get cumbersome for even smaller apps.
What we would ideally want to do, is to add CSS
class
es to HTML nodes, withattr()
; maybe even conditionally.But keeping the actual styling better left inside the CSS classes.
We can add a class by using
"class"
property insideattr()
.selection.attr("class", "container");
This can be used with other properties as well.
Helpful links
Challenge Instructions
Add the CSS class
bar
to the selection usingattr()
Note
Write code only inside where you are asked to add your code.
Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar {
width: 25px;
height: 100px;
display: inline-block;
background-color: blue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
/* Add your code below */
/* Add your code above */
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar {
width: 25px;
height: 100px;
display: inline-block;
background-color: blue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
/* Add your code below */
.attr("class", "bar");
/* Add your code above */
</script>
</body>
</html>
Challenge Text
Now that we know how to display data from an array, and how to add CSS classes, we are finally at a place where we can use both of these tricks and display a bar chart!
There are two phases to this:
- Create a
div
for each of the data points in the array.- Give each of these
div
s a dynamic height, usingstyle()
, that matches their value.
Helpful links
Challenge Instructions
After calling
enter()
, useappend()
to add a<div>
for each of the data points. Then useattr()
to add a CSS classbar
to each of the elements.Finally, add dynamic height using
style()
and a callback function; which returns the value of the data point and a"px"
string added to it.
Note
Write code only inside where you are asked to add your code.
Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar {
width: 25px;
height: 100px;
display: inline-block;
background-color: blue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr("class", "bar")
/* Add your code below */
/* Add your code above */
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar {
width: 25px;
height: 100px;
display: inline-block;
background-color: blue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr("class", "bar")
/* Add your code below */
.style("height", (d) => d + "px")
/* Add your code above */
</script>
</body>
</html>
Challenge Text
We have a bar chart, except it could be better.
There are two phases to doing this:
- Make each of the bar separate from each other, instead of being coalesced together. This can be obtained by adding margin to the CSS of
.bar
class.- Present each of the bars distinctly from each other. This can be done by multiplying the value to get the height.
Helpful links
Challenge Instructions
Add a margin of
3px
to the.bar
class in CSS styling.The callback that sets the height, should return a value 10 times the original data point value.
Note
Write code only inside where you are asked to add your code.
Multiplying by the same constant only alters the scale. Kinda like zooming in. It doesn't alter any data.
Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar {
width: 25px;
height: 100px;
/* Add code only below this line */
/* Add code only above this line */
display: inline-block;
background-color: blue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr("class", "bar")
/* Add your code below */
/* Add your code above */
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar {
width: 25px;
height: 100px;
margin: 3px;
display: inline-block;
background-color: blue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr("class", "bar")
/* Add your code below */
.style("height", (d) => 10 * d + "px")
/* Add your code above */
</script>
</body>
</html>
Challenge Text
SVG stands for Scalable Vector Graphics.
Scalable
in this context means that an SVG media object would not appear pixelated when you zoom in or zoom out. It would scale with the display system the right way, whether it's Apple Watch or a large screen TV monitor.SVG has great support for common geometric shapes.
Since D3 is about presenting data and helping you visualize; it's important that we also use SVG whenever possible.
CSS can be made scalable too, by using relative parameters (
vh
orvw
; and percentages); but SVG is much more easy to use.
Helpful links
Challenge Instructions
Add an
<svg>
node usingappend()
, and give it awidth
attribute of500
andheight
attribute of100
Note
Note that width and height attributes have no units. Just numbers.
This is the building block of scaling, because the element will always have a 5:1 width to height ratio, no matter what the zoom level is.
Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar {
width: 25px;
height: 100px;
margin: 3px;
display: inline-block;
background-color: blue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
const w = 500;
const h = 100;
const svg = d3.select("body")
/* Add your code below */
/* Add your code above */
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar {
width: 25px;
height: 100px;
margin: 3px;
display: inline-block;
background-color: blue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
const w = 500;
const h = 100;
const svg = d3.select("body")
/* Add your code below */
.append("svg")
.attr("width", w)
.attr("height", h);
/* Add your code above */
</script>
</body>
</html>
Challenge Text
We have created an SVG element so far, with a given width and height.
But it's not showing, right?
SVG only created the space of given width and height.
We have to render a rectangle
<rect>
SVG shape to actually display something, like, say a bar.
Helpful links
Challenge Instructions
Add a
<rect>
SVG shape usingappend()
, and give it awidth
attribute of25
andheight
attribute of100
. Also, setx
andy
attribute to0
each.
Note
Read up on different attributes of
<rect>
from the documentation on MDN and other sources.You might need to use
select()
from earlier, because<rect>
would be added inside a<svg>
node. Also don't forget to usedata()
andenter()
.Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar {
width: 25px;
height: 100px;
margin: 3px;
display: inline-block;
background-color: blue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
const w = 500;
const h = 100;
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
/* Add your code below */
/* Add your code above */
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar {
width: 25px;
height: 100px;
margin: 3px;
display: inline-block;
background-color: blue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
const w = 500;
const h = 100;
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
/* Add your code below */
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", 25)
.attr("height", 100);
/* Add your code above */
</script>
</body>
</html>
Challenge Text
We have created an SVG Rect element, next we need to make lot of rectangles like this.
Actually, not a lot. To be precise, exactly the number of rectangles as there are data points in the array.
However, we need to find a way to place each of the rectangles.
The placement of a rectangle is handled by
x
andy
attributes. Earlier we set them to0
.Now, we want all the bars to be in the same vertical level (
y
stays0
), but as we iterate over array elements, thex
value should increase.Remember
attr()
in D3 accepts a callback function to dynamically set the attribute specfied? This callback takes two arguments (second one is optional).selection.attr('property', (d, i) => { /* * d is the data point value * i is the index of the data point in the array */ })
Helpful links
Challenge Instructions
Add a dynamic origin (
x
attribute) for each of the bars, by making sure the first<rect>
hasx = 0
, second<rect>
hasx = 30
, third<rect>
hasx = 60
, fourth<rect>
hasx = 90
, and so on.
Note
We picked 30 as the distance of one
<rect>
from the next one. Ideally, any value greater than25
, the width of each of the<rect>
would have worked.Try to relate the distance as
i
varies. For instance, ifi = 0 => x = 0
, ifi = 1, x = 30
, ifi = 2, x = 60
etc.Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar {
width: 25px;
height: 100px;
margin: 3px;
display: inline-block;
background-color: blue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
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 */
/* Add your code above */
})
.attr("y", 0)
.attr("width", 25)
.attr("height", 100);
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar {
width: 25px;
height: 100px;
margin: 3px;
display: inline-block;
background-color: blue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
const w = 500;
const h = 100;
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
/* Add your code below */
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", (d, i) => i * 30)
.attr("y", 0)
.attr("width", 25)
.attr("height", 100);
/* Add your code above */
</script>
</body>
</html>
Challenge Text
We only need to alter the height of each bar according to the value of the data point, as given in the array.
Just like we set the
x
attribute earlier dynamically, we need to set theheight
attribute of the<rect>
node.selection.attr('property', (d, i) => { /* * d is the data point value * i is the index of the data point in the array */ })
Helpful links
Challenge Instructions
Set the
height
of the bari
using the value ofd
in the callback ofattr()
. It should bed * 3
, instead of justd
(for better distinction).
Note
We have already described why
d * 3
is same asd
when it comes to data visualization. In fact, the former one helps discern it better.Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar {
width: 25px;
height: 100px;
margin: 3px;
display: inline-block;
background-color: blue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
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) => {
/* Add your code below */
/* Add your code above */
});
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar {
width: 25px;
height: 100px;
margin: 3px;
display: inline-block;
background-color: blue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
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)
/* Add your code below */
.attr("height", (d, i) => d * 3);
/* Add your code above */
</script>
</body>
</html>
Challenge Text
We are almost there, except our bar chart is inverted!
This is because of how SVG parses
(x, y)
coordinate information (not because a demogorgon took you into upside-down)In SVG, a
<rect>
shape has its origin at top-left corner.x
increases toward the right. So, if you increasex
, the rectangle moves toward the right.But if you increase
y
, it goes down, instead of going up.We have to keep the height propertional to the data point's value
d
. So, to fix this, we would have to decreasey
as the value increases.When
d=0
,y
should be the height of SVG node,h
. Whend
is greater than 0,y
is less thanh
.A relationship like
y = h - d
would work great!
Helpful links
Challenge Instructions
Set the
y
attribute of the bari
using the value ofd
in the callback ofattr("y")
. Don't returnh - d
; instead, take into account thatd
is being multplied by a factor of 3 to obtain the height.
Note
In general, the relationship is
y = h - m * d
, wherem
is a multiplying factorChallenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar {
width: 25px;
height: 100px;
margin: 3px;
display: inline-block;
background-color: blue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
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 code below this line */
/* Add code above this line */
})
.attr("width", 25)
.attr("height", (d, i) => d * 3);
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar {
width: 25px;
height: 100px;
margin: 3px;
display: inline-block;
background-color: blue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
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);
</script>
</body>
</html>
Challenge Text
We finally got the bars right, but they are all monochromatic, filled with black color.
At the very least, SVG should let us change the color of the bars.
In SVG, a
<rect>
shape has its color defined byfill
attribute. You can obviously do more complex, visually appealing stuff with gradient and transperancy.
Helpful links
Challenge Instructions
Set the
fill
attribute of all the bars to colornavy
.Note You can also set Hexadecimal colors.
Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar {
width: 25px;
height: 100px;
margin: 3px;
display: inline-block;
background-color: blue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
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)
/* Add code below this line */
/* Add code above this line */
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar {
width: 25px;
height: 100px;
margin: 3px;
display: inline-block;
background-color: blue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
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)
/* Add code below this line */
.attr("fill", "navy");
/* Add code above this line */
</script>
</body>
</html>
Challenge Text
We can label a graph element, such as a bar, in D3.
We will be using SVG element,
<text>
. Like<rect>
element, a<text>
element needs to havex
andy
attributes, for placing it on the SVG canvas.This exercise is to demonstrate the level of control D3 gives you, to label your bars.
We would add the value of each bar on top of each bar, with a 3-unit distance (we left pixel-land when we started with SVG) from corresponding bar.
Helpful links
Challenge Instructions
Create
<text>
node, exactly like we created<rect>
nodes.Pass the dataset into them, call
enter()
and then place them on top of each bar, with a 3 unit distance from each bar.You can use
text()
function from D3 to set the text. Note Theirx
andy
attribute would have same value as thebar
at locationi
. Only difference would be in the value ofy
.Decide if the value of
y
would be greater than the value ofy
, or less. Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar {
width: 25px;
height: 100px;
margin: 3px;
display: inline-block;
background-color: blue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
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");
/* Add code below this line */
/* Add code above this line */
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar {
width: 25px;
height: 100px;
margin: 3px;
display: inline-block;
background-color: blue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
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 - (d * 3 + 3));
</script>
</body>
</html>
Challenge Text
Just as we can label a bar, we can also style the label.
We will set the color and font-size of the text in this exercise
The color of the text, is dictated by
fill
attribute of the<text>
node. The font-size is governed by, you guessed it right,font-size
attribute.
Helpful links
Challenge Instructions
Set the
font-size
to25px
, and color of the text tored
Note
Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar {
width: 25px;
height: 100px;
margin: 3px;
display: inline-block;
background-color: blue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
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 - (d * 3 + 3))
/* Add code below this line */
/* Add code above this line */
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar {
width: 25px;
height: 100px;
margin: 3px;
display: inline-block;
background-color: blue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
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 - (d * 3 + 3))
/* Add code below this line */
.attr("font-size", "25px")
.attr("fill", "red");
/* Add code above this line */
</script>
</body>
</html>
Challenge Text
Just because we are using SVG, doesn't mean we cannot use CSS!
We can set a CSS class using
class
attribute on an SVG element.In this exercise, we will set a CSS class, that creates some color change effect on mouse hover.
Helpful links
Challenge Instructions
Set the CSS class of all
<rect>
nodes tobar
Note You might need to use
attr()
function from D3. Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar:hover {
fill: brown;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
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")
/* Add code below this line */
/* Add code above this line */
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) => d)
.attr("x", (d, i) => i * 30)
.attr("y", (d, i) => h - (d * 3 + 3))
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar:hover {
fill: brown;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
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")
/* Add code below this line */
.attr("class", "bar");
/* Add code above this line */
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) => d)
.attr("x", (d, i) => i * 30)
.attr("y", (d, i) => h - (d * 3 + 3))
.attr("font-size", "25px")
.attr("fill", "red");
</script>
</body>
</html>
Challenge Text
We can add a tooltip to each of the bars using
<title>
node under each<rect>
<title>
is another SVG element, commonly used for tool-tip, which can be set by callingtext()
on the<title>
node after creation.
Helpful links
Challenge Instructions
Create
<title>
element under each<rect>
node, and calltext()
function on it, to set the text to each data value.Note You might need to use callback function to return the data point value
d
. Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar:hover {
fill: brown;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
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")
attr("class", "bar")
/* Add code below this line */
/* Add code above this line */
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) => d)
.attr("x", (d, i) => i * 30)
.attr("y", (d, i) => h - (d * 3 + 3))
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar:hover {
fill: brown;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [ 5, 10, 15, 20, 25, 20, 15, 10, 5];
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")
/* Add code below this line */
.append('title')
.text((d) => d);
/* Add code above this line */
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) => d)
.attr("x", (d, i) => i * 30)
.attr("y", (d, i) => h - (d * 3 + 3))
.attr("font-size", "25px")
.attr("fill", "red");
</script>
</body>
</html>
Challenge Text
Scatter plots are consisted of small circles.
SVG lets you create
<circle>
shape, just like it supports<rect>
shape.To draw a circle in SVG, you need to pass it the position of its center (
cx
andcy
attributes), and radius (r
attribute).As in
<rect>
, the attributecy
is measured from the top boundary of SVG canvas, not bottom.
Helpful links
Challenge Instructions
Create
<circle>
elements that correspond to the data points provided in the array. Each data point contains value ofcx
,cy
(in that order).All circle should have radius of
5
.Note Don't forget to use
selectAll()
,data()
,enter()
. Also, remember to flip the scatter plot, by passing proper value inattr("cy")
You don't have to scale the value either, using some multiplicative factor; like we did for bar chart. Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar:hover {
fill: brown;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [
[ 34, 78 ],
[ 109, 280 ],
[ 310, 120 ],
[ 79, 411 ],
[ 420, 220 ],
[ 233, 145 ],
[ 333, 96 ],
[ 222, 333 ],
[ 78, 320 ],
[ 21, 123 ]
];
const w = 500;
const h = 500;
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
/* Add code below this line */
/* Add code above this line */
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar:hover {
fill: brown;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [
[ 34, 78 ],
[ 109, 280 ],
[ 310, 120 ],
[ 79, 411 ],
[ 420, 220 ],
[ 233, 145 ],
[ 333, 96 ],
[ 222, 333 ],
[ 78, 320 ],
[ 21, 123 ]
];
const w = 500;
const h = 500;
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
/* Add code below this line */
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx", (d, i) => d[0])
.attr("cy", (d, i) => h - d[1])
.attr("r", (d, i) => 5);
/* Add code above this line */
</script>
</body>
</html>
Challenge Text
Like bar charts, we would like to add text against all points as well.
You need to display comma separated value for
x
andy
field of each entry in the 2D array.We can keep the text at the same height as
cy
attribute of each point.But to display it to the right of the point on scatter plot, we should pass
x
attribute of the text to be greater thancx
attribute by some constant.
Helpful links
Challenge Instructions
Label each point on the scatter plot by adding text at
(cx + 5, cy)
position.Note A circle which is vertically below another height, should have lesser value in the
y
coordinate.
Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar:hover {
fill: brown;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [
[ 34, 78 ],
[ 109, 280 ],
[ 310, 120 ],
[ 79, 411 ],
[ 420, 220 ],
[ 233, 145 ],
[ 333, 96 ],
[ 222, 333 ],
[ 78, 320 ],
[ 21, 123 ]
];
const w = 500;
const h = 500;
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx", (d, i) => d[0])
.attr("cy", (d, i) => h - d[1])
.attr("r", (d, i) => 5);
/* Add code below this line */
/* Add code above this line */
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar:hover {
fill: brown;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [
[ 34, 78 ],
[ 109, 280 ],
[ 310, 120 ],
[ 79, 411 ],
[ 420, 220 ],
[ 233, 145 ],
[ 333, 96 ],
[ 222, 333 ],
[ 78, 320 ],
[ 21, 123 ]
];
const w = 500;
const h = 500;
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx", (d, i) => d[0])
.attr("cy", (d, i) => h - d[1])
.attr("r", (d, i) => 5);
/* Add code below this line */
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) => (d[0] + "," + d[1]))
.attr("x", (d) => (d[0] + 5))
.attr("y", (d) => (h - d[1]));
/* Add code above this line */
</script>
</body>
</html>
Challenge Text
We have seen how to create simple bar chart and scatter plots.
Now, we are going to take a look at something more fundamental; yet necessary for any plotting - Scale
Often, you are required to plot a set of values at a given scale. For instance, if you are plotting various countries' GDP using plot, you have to divide the absolute GDP by a few Billions, if not trillions; and keep only the relevant figures.
You would almost never plot raw data as-is. Which is why, before even plotting, you have to set the scale for your entire data set, so that the x and y values can fit your canvas width and height.
To create a simple linear scale, use D3 function
scaleLinear()
.const scale = d3.scaleLinear()`
This creates a simple scale.
Helpful links
Challenge Instructions
Create a scale and call it with input argument
50
.Note Guess the scaling factor
scaleLinear()
sets by default.
Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar:hover {
fill: brown;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
/* Add code below this line */
const scale = undefined // create scale here
const output = scale(); // invoke with argument 50
/* Add code above this line */
d3.select('body')
.append('h2')
.text(output)
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar:hover {
fill: brown;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
/* Add code below this line */
const scale = d3.scaleLinear() // create scale here
const output = scale(50); // invoke with argument 50
/* Add code above this line */
d3.select('body')
.append('h2')
.text(output)
</script>
</body>
</html>
Challenge Text
The previous scale was identity relationship - we want something more interesting.
Say the x-coordinate, or
domain
, might vary between 50 and 480. Meaning we have data available only for those points.The y-coordinate, or the
range
, varies between 10 and 500 within that interval of x-coordinates.We can express this using
domain()
andrange()
of the scale.We would want to set this, because it would help set axis later.
// Let's set a domain // The domain is the possible input values scale.domain([50, 480]); // And now a range // The range of possible output values scale.range([10, 500]); scale(50) //returns 10 scale(480) // returns 500 scale(325) // returns 323.37209302325584 scale(750) // returns 807.6744186046511
Helpful links
Challenge Instructions
Create a scale and set it with domain
[250, 500]
and range[10, 150]
.Note You can totally chain these functions!
Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar:hover {
fill: brown;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
/* Add code below this line */
const scale = d3.scaleLinear() // create scale here
/* Add code above this line */
const output = scale(50);
d3.select('body')
.append('h2')
.text(output)
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar:hover {
fill: brown;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
/* Add code below this line */
const scale = d3.scaleLinear() // create scale here
.domain([250, 500])
.range([10, 150])
/* Add code above this line */
const output = scale(50); // -102
d3.select('body')
.append('h2')
.text(output)
</script>
</body>
</html>
d3.max()
and d3.min()
Challenge Text
Now that we know how we can use D3 functions to set the domain and range of our data, it's time to look at some utilities that makes that easy for us.
To set domain and range, we need to know some minimum and maximum present within the data given. It's error prone to do that manually, especially if the dataset is large.
D3 gives you two functions -
d3.max()
andd3.min()
to extract these information.const exampleData = [34, 234, 73, 90, 6, 52]; d3.min(exampleData) // returns 6 d3.max(exampleData) // returns 234
But a dataset might have nested arrays, like [x,y] coordinate pair we used in scatter plot.
In that case, we need to tell D3 how we want our maxiumum and minimum to be computed.
This is achieved by passing a callback in
max()
ormin()
function.This callback's argument is current inner array. The callback needs to return the element from the inner array over which you want to compute the maximum or minimum.
const locationData = [[1,7],[6,3],[8,3]]; // This is how you make it work with an array of arrays // this returns the smallest number of the first element const minX = d3.min(locationData, (d) => d[0]);
Helpful links
Challenge Instructions
Compute the maximum of z-coordinate from the 3D array; where the 3rd value in coordinate is the z-index.
Note D3 can totally plot 3D arrays. Where do you think the 3 in D3 comes from!
Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar:hover {
fill: brown;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const positionData = [[1, 7, -4],[6, 3, 8],[2, 8,3]]
/* Add code below this line */
const output = undefined; // change this line
/* Add code above this line */
d3.select('body')
.append('h2')
.text(output)
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar:hover {
fill: brown;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const positionData = [[1, 7, -4],[6, 3, 8],[2, 8,3]]
/* Add code below this line */
const output = d3.max(positionData, (d) => d[2])
/* Add code above this line */
d3.select('body')
.append('h2')
.text(output)
</script>
</body>
</html>
Challenge Text
We can use the D3
min
andmax
utility to set the scale properly.Given a conplex data-set, we would want to first scale it to fit the SVG container's width and height.
We would even want to have some padding, so that the axes have some breathing room from the boundary of the SVG canvas.
Let's see an example of how to set the X-axis scale for a typical scatter plot.
const dataset = [ [ 34, 78 ], [ 109, 280 ], [ 310, 120 ], [ 79, 411 ], [ 420, 220 ], [ 233, 145 ], [ 333, 96 ], [ 222, 333 ], [ 78, 320 ], [ 21, 123 ] ]; const w = 500; const h = 500; // padding from SVG box boundary const padding = 30; const xScale = d3.scaleLinear() .domain([0, d3.max(dataset, (d)=> d[0])]) .range([padding, w - padding ]);
The last line of code requires some understanding. The domain setting is straightforward. It's setting the minimum of available values of x-coordinate to 0, and maximum is computed by D3
max()
utility.The
range()
of values the x-values should map to - to fit within the width of SVG container, is set to be betweenpadding
andw - padding
.If you have trouble understanding this part, you might want to take a piece of paper and a pen; draw a line starting at 0, ending at
w
.Now mark off padding from both ends and see the length available to place all the x-values.
The
0
in your X axis data would match topadding
mark; andxMax
would match tow - padding
mark.
Helpful links
Challenge Instructions
Compute the
yScale
using similar logic. Assume minimum possible value in y-domain is 0.Note We don't want to do flipping later. So, when setting the range for
Y
coordinates, you can use the higher value first, and lower value second. This would flip all Y-data by default. Essentially, scaling with a negative factor.To help you think, draw a line, this time vertically; and see where
yMin
andyMax
would match.
Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar:hover {
fill: brown;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [
[ 34, 78 ],
[ 109, 280 ],
[ 310, 120 ],
[ 79, 411 ],
[ 420, 220 ],
[ 233, 145 ],
[ 333, 96 ],
[ 222, 333 ],
[ 78, 320 ],
[ 21, 123 ]
];
const w = 500;
const h = 500;
// padding from SVG canvas borders
const padding = 30;
// create an x and y scale
const xScale = d3.scaleLinear()
.domain([0, d3.max(dataset, (d) => d[0])])
.range([padding, w - padding]);
/* Add code below this line */
const yScale = undefined;
/* Add code above this line */
const output = yScale(411); // returns 30
d3.select('body')
.append('h2')
.text(output)
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar:hover {
fill: brown;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [
[ 34, 78 ],
[ 109, 280 ],
[ 310, 120 ],
[ 79, 411 ],
[ 420, 220 ],
[ 233, 145 ],
[ 333, 96 ],
[ 222, 333 ],
[ 78, 320 ],
[ 21, 123 ]
];
const w = 500;
const h = 500;
// padding from SVG canvas borders
const padding = 30;
// create an x and y scale
const xScale = d3.scaleLinear()
.domain([0, d3.max(dataset, (d) => d[0])])
.range([padding, w - padding]);
/* Add code below this line */
const yScale = d3.scaleLinear()
.domain([0, d3.max(dataset, (d) => d[1])])
.range([h - padding, padding]);
/* Add code above this line */
const output = yScale(411); // returns 30
d3.select('body')
.append('h2')
.text(output)
</script>
</body>
</html>
Challenge Text
Now that we have set up our scale, we are ready to plot the scatter plot once again.
This time, we will use the scales we have set up.
This would keep our data within proper bounds. We can use our scale as a processing function that returns processed value for rendering.
shape .attr("x", (d) => xScale(d[0]))
To set any attribute value inside any shape (
<rect>
,<text>
, or<circle>
), we pass it via the scaling function.However, if it doesn't need to be geometrically rendered, but only displayed as text or tooltip; we can use the raw value without scaling.
Helpful links
Challenge Instructions
Use scaling to render values after converting them properly. In particular, render circles and text right to them.
All circle must have a radius of 5 units. The offset in x coordinate for text would be 10 units.
Text should display raw value. Note No flipping here!
Our scaling already took care of that.
Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar:hover {
fill: brown;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [
[ 34, 78 ],
[ 109, 280 ],
[ 310, 120 ],
[ 79, 411 ],
[ 420, 220 ],
[ 233, 145 ],
[ 333, 96 ],
[ 222, 333 ],
[ 78, 320 ],
[ 21, 123 ]
];
const w = 500;
const h = 500;
const padding = 60;
const xScale = d3.scaleLinear()
.domain([0, d3.max(dataset, (d) => d[0])])
.range([padding, w - padding]);
const yScale = d3.scaleLinear()
.domain([0, d3.max(dataset, (d) => d[1])])
.range([h - padding, padding]);
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
// update the code to use the scale
// Add code below
//
// Add code above
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar:hover {
fill: brown;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [
[ 34, 78 ],
[ 109, 280 ],
[ 310, 120 ],
[ 79, 411 ],
[ 420, 220 ],
[ 233, 145 ],
[ 333, 96 ],
[ 222, 333 ],
[ 78, 320 ],
[ 21, 123 ]
];
const w = 500;
const h = 500;
const padding = 60;
const xScale = d3.scaleLinear()
.domain([0, d3.max(dataset, (d) => d[0])])
.range([padding, w - padding]);
const yScale = d3.scaleLinear()
.domain([0, d3.max(dataset, (d) => d[1])])
.range([h - padding, padding]);
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
// update the code to use the scale
// Add code below
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx", (d) => xScale(d[0]))
.attr("cy",(d) => yScale(d[1]))
.attr("r", (d) => 5)
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) => (d[0] + "," + d[1]))
.attr("x", (d) => xScale(d[0] + 10))
.attr("y", (d) => yScale(d[1]))
// Add code above
</script>
</body>
</html>
Challenge Text
There's only one thing missing from our plot to make it look all professional - Axes
Axes is plural for Axis. In particular, we would want an x-axis, and an y-axis.
Let's use D3's utility functions
axisLeft
andaxisBottom
to render Y and X axis, respectively.const xAxis = d3.axisBottom(xScale);
This creates an xAxis. We still need to render this.
To render an axis, we shall use the most general SVG component, the
g
element.Unlike
rect
andcircle
andtext
; we are rendering just a stright line, when rendering an axis. So, usingg
suffices.However, this requires a little bit of
transform
offset, because otherwise the line would be rendered along the border of SVG canvas and won't be visible at all.svg.append("g") .attr("transform", "translate(0, y)") .call(xAxis);
The above renders an X-axis, which is passed as an argument to the
call()
function.Similarly, Y-axis can be rendered, except the translate argument is of the form
(x, 0)
Helpful links
- D3 Axis API
- The
<g>
element Challenge Instructions Add the x and y axis, then render them properly. The padding should be offset for both the axes - x-axis must be at a height (y translation) ofpadding
from bottom border of the SVG canvas.The y-axis must be at the right of leftmost border of SVG canvas by
padding
amount of x-axis translation.Text should display raw value.
Note The
translate
argument should be a string. So generate a string using concatenation and value ofpadding
.Focus on what would be the y-translation of the x-axis. This value is the final value on the coordinate axis; not the amount of movement or translation.
Challenge Seed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar:hover {
fill: brown;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [
[ 34, 78 ],
[ 109, 280 ],
[ 310, 120 ],
[ 79, 411 ],
[ 420, 220 ],
[ 233, 145 ],
[ 333, 96 ],
[ 222, 333 ],
[ 78, 320 ],
[ 21, 123 ]
];
const w = 500;
const h = 500;
const padding = 60;
const xScale = d3.scaleLinear()
.domain([0, d3.max(dataset, (d) => d[0])])
.range([padding, w - padding]);
const yScale = d3.scaleLinear()
.domain([0, d3.max(dataset, (d) => d[1])])
.range([h - padding, padding]);
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
// update the code to use the scale
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx", (d) => xScale(d[0]))
.attr("cy",(d) => yScale(d[1]))
.attr("r", (d) => 5)
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) => (d[0] + "," + d[1]))
.attr("x", (d) => xScale(d[0] + 10))
.attr("y", (d) => yScale(d[1]))
// Add code below
// Add code above
</script>
</body>
</html>
Challenge Tests
// TODO
// Check if body has 9 h1 tags
// Check if h1 has the text "New Title"
// Check if the code uses enter()
Challenge Solution
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>D3 </title>
<style>
.bar:hover {
fill: brown;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script type="text/javascript">
const dataset = [
[ 34, 78 ],
[ 109, 280 ],
[ 310, 120 ],
[ 79, 411 ],
[ 420, 220 ],
[ 233, 145 ],
[ 333, 96 ],
[ 222, 333 ],
[ 78, 320 ],
[ 21, 123 ]
];
const w = 500;
const h = 500;
const padding = 60;
const xScale = d3.scaleLinear()
.domain([0, d3.max(dataset, (d) => d[0])])
.range([padding, w - padding]);
const yScale = d3.scaleLinear()
.domain([0, d3.max(dataset, (d) => d[1])])
.range([h - padding, padding]);
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
// update the code to use the scale
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx", (d) => xScale(d[0]))
.attr("cy",(d) => yScale(d[1]))
.attr("r", (d) => 5)
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) => (d[0] + "," + d[1]))
.attr("x", (d) => xScale(d[0] + 10))
.attr("y", (d) => yScale(d[1]))
// Add code below
svg.append("g")
.attr("transform", "translate(0," + (h - padding) + ")")
.call(xAxis);
svg.append("g")
.attr("transform", "translate(" + padding + ",0)")
.call(yAxis);
// Add code above
</script>
</body>
</html>
@alayek this is some incredible progress!
Challenge Text
Presenting data in its visual form helps the viewers easily get insight into how the data has changed over time, and if there is any visible trend.
In this section, we will get familiar with D3.js, that lets you easily plot data in a webpage and present to your viewers.
But before that, one needs to understand basics of plotting and coordinate geometry.
Helpful links
Challenge Instructions
Go check up the links provided to familiarize yourself with what a plot looks like.
Note
Plots are ubiquitos, even if you are not from statistics or data analysis background. So chances are, you have already encountered them.
Challenge Seed
//TODO : nothing to add
Challenge Tests
// TODO: nothing to add
Challenge Solution
@alayek keep in mind that these helpful links will only be included in the wiki article. When you write the description, assume that the camper will never actually read them (because very few campers tend to navigate to our wiki).
@alayek there are only 5 D3 challenges left to be designed. I've gone ahead and imported them into seed file on https://github.com/FreeCodeCamp/FreeCodeCamp/pull/10473
Finishing this is a lower priority than finishing React.
@QuincyLarson I need some guidance with respect to what the initial section would look like - the part where the basic geometry concepts are introduced.
It's not, strictly speaking, JavaScript. And I don't want to go full on Coordinate Geometry either - because that would scare off beginners.
Any idea what we could submit for challenges and tests, for the first part?
@elibei @t3h2mas FYI.
@alayek you might introduce the notion of the three axes by giving them an existing graph and asking them to plot some additional points at specific coordinates. I would introduce these simply as: Y - up and down X - left and right Z - toward the screen and away from the screen
@alayek as for translations, these may be beyond the scope of what we need to teach. If we do want to cover them, here's a basic explanation we could look at for inspiration: https://people.richland.edu/james/lecture/m116/functions/translations.html
@alayek @elibei This section is almost done. Do either of you have time to finish these remaining challenges this week?
For each challenge, please reply to this GitHub issue with:
We still need to come up with a list of concepts to cover, where each topic can be taught interactively, then translate these concept into the names of the challenges.
Edit:
With inputs from @elibei, these are the topics we would like to cover under D3 [WIP]
d3.min()
andd3.max()