Last active
August 29, 2015 14:00
-
-
Save mrtriangle/11221760 to your computer and use it in GitHub Desktop.
Layered Chart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>Layers!</title> | |
<style> | |
body { | |
font-family: "helvetica"; | |
} | |
button { | |
margin: 0 7px 0 0; | |
background-color: #f5f5f5; | |
border: 1px solid #dedede; | |
border-top: 1px solid #eee; | |
border-left: 1px solid #eee; | |
font-size: 12px; | |
line-height: 130%; | |
text-decoration: none; | |
font-weight: bold; | |
color: #565656; | |
cursor: pointer; | |
} | |
.single-bar { | |
min-height: 1px; | |
min-width: 30px; | |
background-color: #4682b4; | |
margin-right: 1px; | |
font-size: 10px; | |
color: #f0f8ff; | |
text-align: center; | |
width: 15px; | |
display: inline-block; | |
} | |
.baseline { | |
height: 1px; | |
background-color: black; | |
} | |
.axis path, .axis line { | |
fill: none; | |
stroke: #000; | |
shape-rendering: crispEdges; | |
} | |
.axis text { | |
font: 10px sans-serif; | |
} | |
.axis .grid-line{ | |
stroke: black; | |
shape-rendering: crispEdges; | |
stroke-opacity: .2; | |
} | |
.line{ | |
fill: none; | |
stroke: #000; | |
stroke-width: 2; | |
} | |
.dot { | |
fill: #fff; | |
stroke: #000; | |
} | |
.area { | |
stroke: none; | |
fill: steelblue; | |
fill-opacity: .2; | |
} | |
.pie text{ | |
fill: white; | |
font-weight: bold; | |
} | |
.bubble{ | |
fill-opacity: .3; | |
} | |
.bar{ | |
stroke: none; | |
fill: steelblue; | |
} | |
text { | |
font-size: 11px; | |
pointer-events: none; | |
} | |
text.parent { | |
fill: steelblue; | |
} | |
circle { | |
fill: #ccc; | |
stroke: #999; | |
pointer-events: all; | |
} | |
circle.parent { | |
fill: steelblue; | |
fill-opacity: .1; | |
stroke: steelblue; | |
} | |
circle.parent:hover { | |
stroke-width: .5px; | |
} | |
circle.child { | |
pointer-events: none; | |
} | |
</style> | |
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
</head> | |
<body> | |
<script type="text/javascript"> | |
function areaChart() { | |
var _chart = {}; | |
var _width = 700, _height = 400, | |
_margins = {top: 30, left: 30, right: 30, bottom: 30}, | |
_x, _y, | |
_data = [], | |
_colors = d3.scale.ordinal(), | |
_svg, | |
_bodyG, | |
_line; | |
_chart.render = function () { | |
if (!_svg) { | |
_svg = d3.select("body").append("svg") | |
.attr("height", _height) | |
.attr("width", _width); | |
renderAxes(_svg); | |
defineBodyClip(_svg); | |
} | |
renderBody(_svg); | |
}; | |
function renderAxes(svg) { | |
var axesG = svg.append("g") | |
.attr("class", "axes"); | |
renderXAxis(axesG); | |
renderYAxis(axesG); | |
} | |
function renderXAxis(axesG){ | |
var xAxis = d3.svg.axis() | |
.scale(_x.range([0, quadrantWidth()])) | |
.orient("bottom"); | |
axesG.append("g") | |
.attr("class", "x axis") | |
.attr("transform", function () { | |
return "translate(" + xStart() + "," + yStart() + ")"; | |
}) | |
.call(xAxis); | |
d3.selectAll("g.x g.tick") | |
.append("line") | |
.classed("grid-line", true) | |
.attr("x1", 0) | |
.attr("y1", 0) | |
.attr("x2", 0) | |
.attr("y2", - quadrantHeight()); | |
} | |
function renderYAxis(axesG){ | |
var yAxis = d3.svg.axis() | |
.scale(_y.range([quadrantHeight(), 0])) | |
.orient("left"); | |
axesG.append("g") | |
.attr("class", "y axis") | |
.attr("transform", function () { | |
return "translate(" + xStart() + "," + yEnd() + ")"; | |
}) | |
.call(yAxis); | |
d3.selectAll("g.y g.tick") | |
.append("line") | |
.classed("grid-line", true) | |
.attr("x1", 0) | |
.attr("y1", 0) | |
.attr("x2", quadrantWidth()) | |
.attr("y2", 0); | |
} | |
function defineBodyClip(svg) { | |
var padding = 5; | |
svg.append("defs") | |
.append("clipPath") | |
.attr("id", "body-clip") | |
.append("rect") | |
.attr("x", 0 - padding) | |
.attr("y", 0) | |
.attr("width", quadrantWidth() + 2 * padding) | |
.attr("height", quadrantHeight()); | |
} | |
function renderBody(svg) { | |
if (!_bodyG) | |
_bodyG = svg.append("g") | |
.attr("class", "body") | |
.attr("transform", "translate(" | |
+ xStart() + "," | |
+ yEnd() + ")") | |
.attr("clip-path", "url(#body-clip)"); | |
renderLines(); | |
renderAreas(); | |
renderDots(); | |
} | |
function renderLines() { | |
_line = d3.svg.line() | |
.x(function (d) { return _x(d.x); }) | |
.y(function (d) { return _y(d.y); }); | |
_bodyG.selectAll("path.line") | |
.data(_data) | |
.enter() | |
.append("path") | |
.style("stroke", function (d, i) { | |
return _colors(i); | |
}) | |
.attr("class", "line"); | |
_bodyG.selectAll("path.line") | |
.data(_data) | |
.transition() | |
.attr("d", function (d) { return _line(d); }); | |
} | |
function renderDots() { | |
_data.forEach(function (list, i) { | |
_bodyG.selectAll("circle._" + i) | |
.data(list) | |
.enter().append("circle") | |
.attr("class", "dot _" + i); | |
_bodyG.selectAll("circle._" + i) | |
.data(list) | |
.style("stroke", function (d) { | |
return _colors(i); | |
}) | |
.transition() | |
.attr("cx", function (d) { return _x(d.x); }) | |
.attr("cy", function (d) { return _y(d.y); }) | |
.attr("r", 4.5); | |
}); | |
} | |
function renderAreas() { | |
var area = d3.svg.area() // <-A | |
.x(function(d) { return _x(d.x); }) | |
.y0(yStart()) | |
.y1(function(d) { return _y(d.y); }); | |
_bodyG.selectAll("path.area") | |
.data(_data) | |
.enter() // <-B | |
.append("path") | |
.style("fill", function (d, i) { | |
return _colors(i); | |
}) | |
.attr("class", "area"); | |
_bodyG.selectAll("path.area") | |
.data(_data) | |
.transition() // <-D | |
.attr("d", function (d) { | |
return area(d); // <-E | |
}); | |
} | |
function xStart() { | |
return _margins.left; | |
} | |
function yStart() { | |
return _height - _margins.bottom; | |
} | |
function xEnd() { | |
return _width - _margins.right; | |
} | |
function yEnd() { | |
return _margins.top; | |
} | |
function quadrantWidth() { | |
return _width - _margins.left - _margins.right; | |
} | |
function quadrantHeight() { | |
return _height - _margins.top - _margins.bottom; | |
} | |
_chart.width = function (w) { | |
if (!arguments.length) return _width; | |
_width = w; | |
return _chart; | |
}; | |
_chart.height = function (h) { | |
if (!arguments.length) return _height; | |
_height = h; | |
return _chart; | |
}; | |
_chart.margins = function (m) { | |
if (!arguments.length) return _margins; | |
_margins = m; | |
return _chart; | |
}; | |
_chart.colors = function (c) { | |
if (!arguments.length) return _colors; | |
_colors = c; | |
return _chart; | |
}; | |
_chart.x = function (x) { | |
if (!arguments.length) return _x; | |
_x = x; | |
return _chart; | |
}; | |
_chart.y = function (y) { | |
if (!arguments.length) return _y; | |
_y = y; | |
return _chart; | |
}; | |
_chart.addSeries = function (series) { | |
_data.push(series); | |
return _chart; | |
}; | |
return _chart; | |
} | |
function randomData() { | |
return Math.random() * 9; | |
} | |
function update() { | |
for (var i = 0; i < data.length; ++i) { | |
var series = data[i]; | |
series.length = 0; | |
for (var j = 0; j < numberOfDataPoint; ++j) | |
series.push({x: j, y: randomData()}); | |
} | |
chart.render(); | |
} | |
var numberOfSeries = 3, | |
numberOfDataPoint = 20, | |
data = []; | |
for (var i = 0; i < numberOfSeries; ++i) | |
data.push(d3.range(numberOfDataPoint).map(function (i) { | |
return {x: i, y: randomData()}; | |
})); | |
var chart = areaChart() | |
.x(d3.scale.linear().domain([0, 10])) | |
.y(d3.scale.linear().domain([0, 10])); | |
data.forEach(function (series) { | |
chart.addSeries(series); | |
}); | |
chart.render(); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment