Creating customized line chart using d3.js
D3 (Data-Driven Documents) is a JavaScript library to create custom visualizations. It combines powerful visualization and interaction techniques with a data-driven approach to DOM manipulation, giving you the full capabilities of modern browsers and the freedom to design the right visual interface for your data.
D3.js graphs are for those who want to create complex, customized graphs.
Installing :
If you are using NPM, then you can install d3 by using the following command
[java]npm install d3[/java]
or,
you can simply download the latest version and include it in your page.
Drawing a Line Chart :
Step 1 : First, we’ll need some data to plot. We’re going to use the following data.
[java] var lineData = [{a: 1, y: 5}, {a: 20, b: 20}, …… , {a: 100, b: 60}]; [/java]
Step 2 : Create an empty div which will enclose the chart
[java]
<div id="chartArea"></div>
[/java]
Step 3 : Creating SVG element
[java]
var margin = {top: 30, left:30, right:30, bottom:30}, width = 800, height = 500;
var svg = d3.select("#chartArea").append("svg")
.attr(‘id’, ‘mychart’)
.attr("width", width)
.attr("height", height)
.style(‘border’, ‘1px solid #ccc’);
[/java]
Step 4 : Define scale and axes
[java]
var xScale = d3.scale.linear().range([margin.left, width – margin.right])
.domain([0, 100]),
yScale = d3.scale.linear().range([height – margin.top, margin.bottom])
.domain([0, 100]);
var xAxis = d3.svg.axis().scale(xScale),
yAxis = d3.svg.axis().scale(yScale).orient(‘left’);
// y-axis it needs to be oriented to the left
[/java]
Here, domain defines the minimum and maximum values displayed on the graph. Range is the area of the SVG we’ll be covering.
Scales are functions that map from an input domain to an output range.
Step 5 : Append both the axis to the SVG and apply the transformation
[java]
var mySVG = d3.select(‘#mychart’) //selects element with id equals to mychart, currently pointing to the above created SVG element.
mySVG.append("g") //g element is used to group SVG shapes together
.attr("class", "x-axis")
.attr("transform", "translate(0," + (height – margin.bottom) + ")") //The transforms are SVG transforms
.call(xAxis)
.append("text")
.attr("y", ‘3em’)
.attr("x", "30em")
.text("Quantity");
mySVG.append("g") //We create an SVG Group Element to hold all the elements that the axis function produces.
.attr("class", "y-axis")
.attr("transform", "translate(" + (margin.left) + ",0)")
.call(yAxis)
.append("text")
.attr("y", "16em")
.attr("x", "-5.5em")
.text("Price ($)");
[/java]
Here, the translate() function takes one or two values which specify the horizontal and vertical translation values, respectively.
tx represents the translation value along the x-axis and ty represents the translation value along the y-axis.
We have transformed both the axes, keeping the defined margins in view so that the axes don’t touch the SVG margins.
Step 6 : Next we are going to plot coordinates and draw a line.
[java]
var lineFunc = d3.svg.line().x(function(obj) {return xScale(obj.quantity)})
.y(function(obj) {return yScale(obj.price);});
var path = svg.append("path")
.attr("d", lineFunc(lineData))
.attr("stroke", ‘#87CEEB’)
.attr("stroke-width", 3)
.attr("fill", "none");
[/java]
d3.svg.line() constructs a new line generator with the default x and y accessor functions. The
returned function generates path data for an open piece-wise linear curve.
Now, we have successfully created a line chart, its time to add some customization.
Highlighting the path on hover
Let’s change the color of the line, when user hovers it.
[java]
path.on(‘mouseover’, function(obj) {
d3.select(this).attr(‘stroke’, ‘#00688B’);
}).on(‘mouseout’, function(obj) {
d3.select(this).attr(‘stroke’, ‘#87CEEB’);
});
[/java]
Adding tooltips
Step 1 : Create a empty div
[java]
var tooltipDiv = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0)
.style("position", "absolute")
.style("text-align", "center")
.style("width", "90px")
.style("height", "45px")
.style("padding", "2px")
.style("background", "beige")
.style("pointer-events", "none");
[/java]
Step 2 : Plot circles.
[java]
var circles = svg.selectAll("circle")
.data(lineData)
.enter().append("circle")
.style("fill", ‘#00688B’)
.attr("r", 5)
.attr("cx", function(obj) {
return xScale(obj.quantity);
})
.attr("cy", function(obj) {
return yScale(obj.price);
});
[/java]
Step 3. Finally, show tooltip on hover
[java]
circles.on("mouseover", function(obj) {
tooltipDiv.transition().duration(200)style("opacity", .9);
tooltipDiv.html("Quantity : " + obj.quantity + "<br/>Price : " + obj.price)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY – 28) + "px");
}).on("mouseout", function(obj) {
tooltipDiv.transition().duration(500).style("opacity", 0);
});
[/java]
And we’re done. I’ve also created a JsFiddle for the same.