D3 Tutorial
In this post, I outline-solid the ways in which d3 library works with the <svg> elements.
D3 Tutorial
Working with Javascript
We have the following data of cars
List of Cars
[ { "make": "Nissan", "model": "Leaf", "year": 2012, "price": 1800 }, { "make": "Ford", "model": "F150", "year": 2009, "price": 1950 }, { "make": "Chevrolet", "model": "Trailblazer", "year": 2009, "price": 2100 }, { "make": "Tesla", "model": "ModelX", "year": 2012, "price": 100000 } ]
We can use functional programming to make it look nicer. The code below use a functional paradigm. By making a reduce function we can easily format json formatted data.
data.reduce((acc, d) => { acc += formatCar(d) + "\n"; return acc; }, ""); export const formatCar = car => `${car.year} ${car.make} ${car.model}: ${car.price}`;
Output:
/* 2012 Nissan Leaf: 1800 2009 Ford F150: 1950 2009 Chevrolet Trailblazer: 2100 2012 Tesla ModelX: 100000 */
This is done by mapping over the data with a custom function that formats each object (i.e. each car description). Look at components/car.js file for the formatting function.
We can also filter by a specific price. In the following example we filter by car prices less than $2000.
export const filterByPrice = (cars, price) => cars.filter(car => car.price < price);
Result of applying the filter method used here
[ { "make": "Nissan", "model": "Leaf", "year": 2012, "price": 1800 }, { "make": "Ford", "model": "F150", "year": 2009, "price": 1950 } ]
HTML CSS and SVG
We can write scalable vector graphics (SVG) using the svg tag. Learn the follwoing:
- height and width of the svg tag (defined it here as
height="520"andwidth="100%"(of its parent); - circle tag which takes in
cx,cyandrall self explanitory; - same goes for the
recttag which takes inx,y,width, andheight; - the group element which applies a tranformation, fill, stroke, etc. to all its children element. These children elements can be any tag (circle, rectangle, or path);
- lastly the path where the
dattribute is the most important.- It can any polygon you desire.
- It requires a start point
M x,y. Then a line to a desired point:L x2,y2. - These
Lpoints can be grouped as many times as necessary.
Using d3
The above svg elemtns can be replicated with d3.js.
Making a face
Will demostrate how to make more complex shapes with animations. For a demo click the “Start Animation” button.
Making a Bar Chart
Got the data from here: UN Data
Drawing a Scatterplot
Here we will draw a scatterplot
Lineplots
Let us do line plots now
Here are some options you can play with:
Draw a function
Lets draw a function to see how it turns out.
Area Plot
Let us do area plot now
General Update Pattern: Enter, Update, Remove
This section will demonstrate how the enter, update, and remove work with a bowl of fruit example.
If the bowl is empty then add 5 apples. If you eat one remove it from the bowl.
Nested Elements with the General Update Pattern
You can add only one element (like the bowl) by using the: selection.selectAll('rect').data([null]).enter().append('rect')
Making a Map with d3
Lets make a map.
- Loading and parsing TOPJSON;
- Rendering geopraphic features;
- Using different map projections;
- Rendering projected shpere outline.
Here are some references used here:
- world-atlas npm
- CDN for topjson or I used
- d3 geo
- Block builder website to search for ideas for maps
Loaded topo json format and d3 requires geo json format. Thus use topojson library for conversion. Got the topojson library from here: TopoJSON Library.
Use the topojson.feature(data) function for conversion.
If the path type is sphere then you will get the thick borders around the map.
export const createMapBeg = () => { const svg = d3.select("#id"); const projection = d3.geoMercator(); const pathGenerator = d3.geoPath().projection(projection); d3.json("https://unpkg.com/world-atlas@1.1.4/world/110m.json") .then(data => { const countries = topojson .feature(data, data.objects.countries); const paths = svg.selectAll("path").data(countries.features); paths.enter() .append("path") .attr("d", d => pathGenerator(d)); }); };
Making some tweaks to the map
You will find the types of projections here: Projections, another link .
Here is a list of some projections
d3.geoOrthographic();This is used below.-
d3.geoStereographic(); -
d3.geoEqualEarth(); -
d3.geoGnomonic();
Need to figure out how to resize maps properly, and also how to rotate them.
Tree Visualization
We will create a tree. Uses the d3.hierarchy library. It is there by default.
You can also have vertical trees with the following code:
const treeRoot = d3.hierarchy(data); const links = treeLayout(treeRoot).links(); const linkPathGenerator = d3 .linkVertical() .x(d => d.x) .y(d => d.y);
You could use treeLayout = d3.cluster() if the leaft nodes are unlevel to have them appear on the same level.
Color and Size Legend
In this module we will make a legend component.
Lets also make a size scale next to the legend. Size scale is proportional to area and we are going to use circle to represent size. Therefore, r = sqrt(A/pi)