Skip to content

Instantly share code, notes, and snippets.

@robnewman
Created May 11, 2012 22:24
Show Gist options
  • Save robnewman/2662793 to your computer and use it in GitHub Desktop.
Save robnewman/2662793 to your computer and use it in GitHub Desktop.
d3.js multiple lines
// Set up margins
var m = [20, 50, 50, 20],
w = 1000 - m[1] - m[3],
h = 700 - m[0] - m[2],
parse = d3.time.format("%Y-%m-%d").parse,
format = d3.time.format("%Y");
// Scales
var x = d3.time.scale().range([0, w]),
y = d3.scale.linear().range([h, 0]),
xAxis = d3.svg.axis().scale(x).orient("bottom").tickSize(-h, 0).tickPadding(6),
yAxis = d3.svg.axis().scale(y).orient("right").tickSize(-w).tickPadding(6);
// An area generator
var area = d3.svg.area()
.interpolate("step-after")
.x(function(d) { return x(d.date); })
.y0(y(0))
.y1(function(d) { return y(d.value); });
// A line generator
var line = d3.svg.line()
.interpolate("step-after")
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.value); });
// Build the graph
var svg = d3.select("#graphbody").append("svg:svg")
.attr('width', w + m[1] + m[3])
.attr('height', h + m[0] + m[2])
.append("svg:g")
.attr("transform", "translate(" + m[3] + "," + m[0] + ")");
var gradient = svg.append("svg:defs").append("svg:linearGradient")
.attr("id", "gradient")
.attr("x2", "0%")
.attr("y2", "100%");
gradient.append("svg:stop")
.attr("offset", "0%")
.attr("stop-color", "#00F")
.attr("stop-opacity", .3);
gradient.append("svg:stop")
.attr("offset", "100%")
.attr("stop-color", '#006')
.attr("stop-opacity", 1);
svg.append("svg:clipPath")
.attr("id", "clip")
.append("svg:rect")
.attr("x", x(0))
.attr("y", y(1))
.attr("width", x(1) - x(0))
.attr("height", y(0) - y(1));
svg.append("svg:g")
.attr("class", "y axis")
.attr("transform", "translate(" + w + ",0)");
svg.append("svg:path")
.attr("class", "area")
.attr("clip-path", "url(#clip)")
.style("fill", "url(#gradient)");
svg.append("svg:g")
.attr("class", "x axis")
.attr("transform", "translate(0," + h + ")");
svg.append("svg:path")
.attr("class", "line")
.attr("clip-path", "url(#clip)");
svg.append("svg:rect")
.attr("class", "pane")
.attr("width", w)
.attr("height", h)
.call(d3.behavior.zoom().on("zoom", zoom));
var rect = svg.append("svg:rect")
.attr("class", "pane")
.attr("width", w)
.attr("height", h);
function loadr(snet, filename, gradient) {
// This is where the magic happens....
d3.json(filename, function(mydata) {
var stops = gradient.selectAll("stop");
stops.attr("stop-color", "#"+mydata.color);
d3.select("#graphtitle").text(mydata.snetmeta.abbrev);
var data = mydata.data;
data.forEach(function(d) {
d.date = parse(d.readable_time);
d.value = +d.value;
});
// Compute the minimum and maximum time values for x-scale
x.domain([
d3.min(data, function(d) { return parse(d.readable_time); }),
d3.max(data, function(d) { return parse(d.readable_time); })
]);
// Percentage range between 0 and 100!
y.domain([0, 100]);
// Bind the data to our path elements
svg.select("path.area").data([data]);
// Comment out adding the line here - added later
// svg.select("path.line").data([data]);
rect.call(d3.behavior.zoom().x(x).on("zoom", zoom));
// Create the minimum data return dataset
// using the min and max times from the dataset selected
var min_data_return = [
{
"readable_time": d3.min(data, function(d) { return d.readable_time; }),
"value": 85
},
{
"readable_time": d3.max(data, function(d) { return d.readable_time; }),
"value": 85
}
]
min_data_return.forEach(function(d) {
d.date = parse(d.readable_time);
d.value = +d.value;
});
// OPTION 1: This adds the data as a line and works just fine
svg.select("path.line").data([data]);
// OPTION 2: But shouldn't this add two lines of data?
// * one for the dataset to the be plotted, and
// * one for the minimum data return (two points defining a line)
// The following doesn't work?
// svg.select("path.line").data([data, min_data_return]);
draw();
});
}
function draw() {
svg.select("g.x.axis").call(xAxis);
svg.select("g.y.axis").call(yAxis);
svg.select("path.area").attr("d", area);
svg.select("path.line").attr("d", line);
d3.select("#graphfooter p span").text("Percentage daily network data return rates, " + x.domain().map(format).join("-"));
}
function zoom() {
draw();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment