Want to fix the label crowding? Check out the version by Ziggy that dynamically positions the labels. Mike Bostock suggested constraint relaxation, which works very well.
This line chart is constructed from a CSV in the "Multi-Series Format" from Bureau of Labor Statistics Consumer Price Index data. The chart employs conventional margins and a number of D3 features:
The chart also uses a couple functions from Underscore.js:
xxxxxxxxxx
<title>Average Price Histories</title>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
.line {
fill: none;
stroke: steelblue;
stroke-width: 1.5px;
-webkit-transition: opacity 0.3s;
-moz-transition: opacity 0.3s;
-o-transition: opacity 0.3s;
transition: opacity 0.3s;
}
path.invisible {
fill: none;
stroke: rgba(0,0,0,0);
stroke-width: 8px;
}
text.label {
font-size: 12px;
font-weight: bold;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/d3@2.10.3/d3.v2.js"></script>
<script src="https://cdn.jsdelivr.net/npm/underscore@1.12.1/underscore-min.js"></script>
<body></body>
<script type="text/javascript">
var margin = {top: 20, right: 220, bottom: 30, left: 50},
width = 1000 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var format = d3.time.format("%b %Y");
var start = format.parse("Jan 1984");
var end = format.parse("Aug 2012");
var range = d3.time.months(start,end);
var x = d3.time.scale()
.range([0,width])
.domain([start,end]);
var y = d3.scale.linear()
.range([height, 0]);
var color = function(i) {
return d3.hcl(48*i,95,45).toString();
};
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
.interpolate("basis")
.defined(function(d) { return d != null; })
.x(function(d,i) { return x(range[i]); })
.y(function(d) { return y(d); });
var svg = d3.select("body").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 + ")");
d3.csv("average-prices.csv", function(raw) {
var data = [];
var goods = _(raw).pluck("Name");
_(raw).each(function(series) {
var value = {};
data.push({
id: series["Series ID"],
name: series["Name"],
values: _(range).map(function(month) {
return parseFloat(series[format(month)]) || null;
})
});
});
var values = _(data).chain().pluck('values').flatten().value();
y.domain([
0,
d3.max(values)
]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.style("font-weight", "bold")
.text("Average Price");
var series = svg.selectAll(".series")
.data(data)
.enter().append("g")
.attr("class", "series");
series.append("path")
.attr("class", "line")
.attr("d", function(d) { return line(d.values); })
.style("stroke", function(d,i) { return color(i); });
series.append("path")
.attr("class", "invisible hover")
.attr("d", function(d) { return line(d.values); });
series.append("text")
.attr("class", "label hover")
.datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; })
.attr("transform", function(d) { return "translate(" + x(end) + "," + y(d.value) + ")"; })
.attr("x", 3)
.attr("dy", ".35em")
.style("fill", function(d,i) { return color(i); })
.text(function(d) { return d.name; });
series.selectAll(".hover")
.on("mouseover", function(d,i) {
d3.selectAll(".line")
.style("opacity", 0.12)
.filter(function(p) { return p.name == d.name; })
.style("opacity", 1)
.style("stroke-width", 2.5);
d3.selectAll(".series text")
.style("opacity", 0)
.filter(function(p) { return p.name == d.name; })
.style("opacity", 1);
})
.on("mouseout", function(d,i) {
d3.selectAll(".line")
.style("opacity", 1)
.style("stroke-width", null);
d3.selectAll(".series text")
.style("opacity", 1);
});
});
</script>
Modified http://mbostock.github.com/d3/d3.v2.js to a secure url
Modified http://documentcloud.github.com/underscore/underscore.js to a secure url
https://mbostock.github.com/d3/d3.v2.js
https://documentcloud.github.com/underscore/underscore.js