Skip to content

Instantly share code, notes, and snippets.

@jadiehm
Last active November 3, 2015 18:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jadiehm/311fcceab8425ddf1944 to your computer and use it in GitHub Desktop.
Save jadiehm/311fcceab8425ddf1944 to your computer and use it in GitHub Desktop.
Responsive line chart with tooltips
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<style type="text/css">
/*css to go here*/
body {
font-family: 'Proxima-Nova', sans-serif;
font-size: 12px;
}
.g-hed {
text-align: left;
text-transform: uppercase;
font-weight: bold;
font-size:22px;
margin: 3px 0;
}
.g-source-bold {
text-align: left;
font-size:10px;
font-weight: bold;
}
.g-source {
margin: 10px 0;
}
.g-source-bold {
text-align: left;
font-size:10px;
}
.g-intro {
font-size: 16px;
margin: 0px 0px 10px 0px;
}
.g-labels {
font-family: 'Proxima-Nova', sans-serif;
fill: white;
font-weight: bold;
font-size: 14px;
}
.axis line {
fill: none;
stroke: #ccc;
stroke-dasharray: 2px 3px;
shape-rendering: crispEdges;
stroke-width: 1px;
}
.axis text {
font-family: 'Proxima-Nova', sans-serif;
font-size: 13px;
pointer-events: none;
fill: #7e7e7e;
}
.y.axis text {
text-anchor: end !important;
font-size:14px;
fill: #7e7e7e;
}
.domain {
display: none;
}
.line {
stroke: #2f5491;
stroke-width: 3px;
fill: none;
}
.overlay {
fill: none;
pointer-events: all;
}
.focus {
font-size: 14px;
}
.focus circle {
fill: #5e8dc9;
}
</style>
<body>
<h5 class="g-hed"></h5>
<p class="g-intro"></p>
<div class="g-chart"></div>
<div class="g-source"><span class="g-source-bold"></span><span class="g-source-reg"></span></div>
</div>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script>
<script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
<script>
//Margin conventions
var margin = {top: 20, right: 70, bottom: 40, left: 35};
var widther = window.outerWidth;
var width = widther - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
//Parses date for correct time format
var parseDate = d3.time.format("%Y-%m").parse;
//Divides date for tooltip placement
var bisectDate = d3.bisector(function(d) { return d.date; }).left;
//Appends the svg to the chart-container div
var svg = d3.select(".g-chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
//Creates the xScale
var xScale = d3.time.scale()
.range([0, width]);
//Creates the yScale
var yScale = d3.scale.linear()
.range([height, 0]);
//Defines the y axis styles
var yAxis = d3.svg.axis()
.scale(yScale)
.tickSize(-width)
.tickPadding(8)
.orient("left");
//Defines the y axis styles
var xAxis = d3.svg.axis()
.scale(xScale)
.tickPadding(8)
.orient("bottom")
.tickSize(height)
.ticks(numTicks(width))
.tickFormat(d3.time.format("%m/%Y"));
//line function convention (feeds an array)
var line = d3.svg.line()
.x(function(d) { return xScale(d.date); })
.y(function(d) { return yScale(d.num); });
//Loads the data
d3.csv("linetemplate.csv", ready);
function ready(err, data) {
if (err) throw "error loading data";
console.log("hello");
//FORMAT data
data.forEach(function(d) {
d.num = +d.num;
d.date = parseDate(d.date);
});
console.log(data);
//Appends chart headline
d3.select(".g-hed").text("Chart headline goes here");
//Appends chart intro text
d3.select(".g-intro").text("Chart intro text goes here. Write a short sentence describing the chart here.");
data.sort(function(a,b) { return a.date - b.date; });
//Defines the xScale max
xScale.domain(d3.extent(data, function(d) { return d.date; }));
//Defines the yScale max
yScale.domain(d3.extent(data, function(d) { return d.num; }));
//Appends the y axis
var yAxisGroup = svg.append("g")
.attr("class", "y axis")
.call(yAxis);
//Appends the x axis
var xAxisGroup = svg.append("g")
.attr("class", "x axis")
.call(xAxis);
//Binds the data to the line
var drawline = svg.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line);
//Tooltips
var focus = svg.append("g")
.attr("class", "focus")
.style("display", "none");
//Adds circle to focus point on line
focus.append("circle")
.attr("r", 4);
//Adds text to focus point on line
focus.append("text")
.attr("x", 9)
.attr("dy", ".35em");
//Creates larger area for tooltip
var overlay = svg.append("rect")
.attr("class", "overlay")
.attr("width", width)
.attr("height", height)
.on("mouseover", function() { focus.style("display", null); })
.on("mouseout", function() { focus.style("display", "none"); })
.on("mousemove", mousemove);
//Tooltip mouseovers
function mousemove() {
var x0 = xScale.invert(d3.mouse(this)[0]),
i = bisectDate(data, x0, 1),
d0 = data[i - 1],
d1 = data[i],
d = x0 - d0.date > d1.date - x0 ? d1 : d0;
focus.attr("transform", "translate(" + xScale(d.date) + "," + yScale(d.num) + ")");
focus.select("text").text(d.num);
};
//Appends chart source
d3.select(".g-source-bold")
.text("SOURCE: ")
.attr("class", "g-source-bold");
d3.select(".g-source-reg")
.text("Chart source info goes here")
.attr("class", "g-source-reg");
//RESPONSIVENESS
d3.select(window).on("resize", resized);
function resized() {
//new margin
var newMargin = {top: 10, right: 80, bottom: 20, left: 50};
//Get the width of the window
var w = d3.select(".g-chart").node().clientWidth;
console.log("resized", w);
//Change the width of the svg
d3.select("svg")
.attr("width", w);
//Change the xScale
xScale
.range([0, w - newMargin.right]);
//Update the line
line = d3.svg.line()
.x(function(d) { return xScale(d.date); })
.y(function(d) { return yScale(d.num); });
d3.selectAll('.line')
.attr("d", line);
//Updates xAxis
xAxisGroup
.call(xAxis);
//Updates ticks
xAxis
.scale(xScale)
.ticks(numTicks(w));
//Updates yAxis
yAxis
.tickSize(-w - newMargin.right)
};
}
//Determines number of ticks base on width
function numTicks(widther) {
if (widther <= 900) {
return 4
console.log("return 4")
}
else {
return 12
console.log("return 5")
}
}
</script>
date num
2008-11 7.8
2008-12 8.3
2009-01 8.7
2009-02 8.9
2009-03 9.4
2009-04 9.5
2009-05 9.5
2009-06 9.6
2009-07 9.8
2009-08 10
2009-09 9.9
2009-10 9.9
2009-11 9.7
2009-12 9.8
2010-01 9.8
2010-02 9.9
2010-03 9.6
2010-04 9.4
2010-05 9.5
2010-06 9.6
2010-07 9.5
2010-08 9.5
2010-09 9.8
2010-10 9.4
2010-11 9.1
2010-12 9
2011-01 8.9
2011-02 9
2011-03 9
2011-04 9.1
2011-05 9.1
2011-06 9.1
2011-07 9
2011-08 8.9
2011-09 8.7
2011-10 8.5
2011-11 8.3
2011-12 8.3
2012-01 8.2
2012-02 8.1
2012-03 8.2
2012-04 8.2
2012-05 8.3
2012-06 8.1
2012-07 7.8
2012-08 7.2
2012-09 7
2012-10 6.9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment