Skip to content

Instantly share code, notes, and snippets.

@mrtriangle
Last active August 29, 2015 14:00
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 mrtriangle/11221760 to your computer and use it in GitHub Desktop.
Save mrtriangle/11221760 to your computer and use it in GitHub Desktop.
Layered Chart
<!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