Skip to content

Instantly share code, notes, and snippets.

@serra
Created July 13, 2012 07:54
Show Gist options
  • Save serra/3103475 to your computer and use it in GitHub Desktop.
Save serra/3103475 to your computer and use it in GitHub Desktop.
Example for StackOverflow question: Map custom value field to x value when using a stacked layout.
<!DOCTYPE html>
<html>
<head>
<title>Map custom value field to x value when using a stacked layout</title>
</head>
<body>
<p>
Example for StackOverflow question <a href="http://stackoverflow.com/questions/11467196">Map custom value field to x value when using a stacked layout</a>.
</p>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js?2.5.0"></script>
<pre>
// This works:
var st = d3.layout.stack()
.values(function (d) { return d.values; })
.y(function (v, i) { return v.yInit; })
.out(function (d, y0, y) { d.x = d.xInit; d.y0 = y0; d.y = y; });
</pre>
<div id="chart2">
</div>
<script type="text/javascript">
var margin = 20,
width = 240,
height = 125 - .5 - margin;
var n, // number of layers
m, // number of samples per layer
mx, my, mz;
var x = function (d) { return d.x * width / mx; },
y0 = function (d) { return height - d.y0 * height / my; },
y1 = function (d) { return height - (d.y + d.y0) * height / my; },
y2 = function (d) { return d.y * height / mz; }; // or `my` to not rescale
var initialData;
var data;
initGraph();
function initGraph() {
initialData = [
{
"name": "apples",
"values": [
{ "xInit": 0, "yInit": 91 },
{ "xInit": 1, "yInit": 290 },
{ "xInit": 2, "yInit": 120 }
]
},
{
"name": "oranges",
"values": [
{ "xInit": 0, "yInit": 9 },
{ "xInit": 1, "yInit": 49 },
{ "xInit": 2, "yInit": 37 }
]
}
];
var st = d3.layout.stack()
.values(function (d) { return d.values; })
.y(function (v, i) { return v.yInit; })
.out(function (d, y0, y) { d.x = d.xInit; d.y0 = y0; d.y = y; });
data = st(initialData);
var color = d3.interpolateRgb("#aad", "#556");
n = data.length;
m = data[0].values.length;
mx = m;
my = d3.max(data, function(d) {
return d3.max(d.values, function(d2) {
return d2.y + d2.y0;
});
});
mz = d3.max(data, function(d) {
return d3.max(d.values, function (d2) {
return d2.y;
});
});
var vis = d3.select("#chart2")
.append("svg")
.attr("width", width)
.attr("height", height + margin);
var layers = vis.selectAll("g.layer")
.data(data)
.enter().append("g")
.style("fill", function(d, i) { return color(i / (n - 1)); })
.attr("class", "layer");
var bars = layers.selectAll("g.bar")
.data(function (d) { return d.values; }) // ! let a bar enter for each entry
.enter().append("g")
.attr("class", "bar")
.attr("transform", function(d) { return "translate(" + x(d) + ",0)"; });
bars.append("rect")
.attr("width", x({ x: .9 }))
.attr("x", 0)
.attr("y", height)
.attr("height", 0)
.transition()
.delay(function(d, i) { return i * 10; })
.attr("y", y1)
.attr("height", function (d) { return y0(d) - y1(d); })
.attr("title", function (v) { return "" + v.x + ":" + v.y; });
var labels = vis.selectAll("text.label")
.data(data[0].values)
.enter()
.append("text")
.attr("class", "label")
.attr("x", x)
.attr("y", height + 6)
.attr("dx", x({ x: .45 }))
.attr("dy", ".71em")
.attr("text-anchor", "middle")
.text(function (d, i) { return i; });
}
</script>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js?2.5.0"></script>
<pre>
// But this does not:
var st = d3.layout.stack()
.values(function (d) { return d.values; })
.y(function (v, i) { return v.yInit; })
.x(function (v, i) { return v.xInit; });
</pre>
<div id="chart1">
</div>
<script type="text/javascript">
var margin = 20,
width = 240,
height = 125 - .5 - margin;
var n, // number of layers
m, // number of samples per layer
mx, my, mz;
var x = function (d) { return d.x * width / mx; },
y0 = function (d) { return height - d.y0 * height / my; },
y1 = function (d) { return height - (d.y + d.y0) * height / my; },
y2 = function (d) { return d.y * height / mz; }; // or `my` to not rescale
var initialData;
var data;
initGraph();
function initGraph() {
initialData = [
{
"name": "apples",
"values": [
{ "xInit": 0, "yInit": 91 },
{ "xInit": 1, "yInit": 290 },
{ "xInit": 2, "yInit": 120 }
]
},
{
"name": "oranges",
"values": [
{ "xInit": 0, "yInit": 9 },
{ "xInit": 1, "yInit": 49 },
{ "xInit": 2, "yInit": 37 }
]
}
];
var st = d3.layout.stack()
.values(function (d) { return d.values; })
.y(function (v, i) { return v.yInit; })
.x(function (v, i) { return v.xInit; });
data = st(initialData);
var color = d3.interpolateRgb("#aad", "#556");
n = data.length;
m = data[0].values.length;
mx = m;
my = d3.max(data, function (d) {
return d3.max(d.values, function (d2) {
return d2.y + d2.y0;
});
});
mz = d3.max(data, function (d) {
return d3.max(d.values, function (d2) {
return d2.y;
});
});
var vis = d3.select("#chart1")
.append("svg")
.attr("width", width)
.attr("height", height + margin);
var layers = vis.selectAll("g.layer")
.data(data)
.enter().append("g")
.style("fill", function (d, i) { return color(i / (n - 1)); })
.attr("class", "layer");
var bars = layers.selectAll("g.bar")
.data(function (d) { return d.values; }) // ! let a bar enter for each entry
.enter().append("g")
.attr("class", "bar")
.attr("transform", function (d) { return "translate(" + x(d) + ",0)"; });
bars.append("rect")
.attr("width", x({ x: .9 }))
.attr("x", 0)
.attr("y", height)
.attr("height", 0)
.transition()
.delay(function (d, i) { return i * 10; })
.attr("y", y1)
.attr("height", function (d) { return y0(d) - y1(d); })
.attr("title", function (v) { return "" + v.x + ":" + v.y; });
var labels = vis.selectAll("text.label")
.data(data[0].values)
.enter()
.append("text")
.attr("class", "label")
.attr("x", x)
.attr("y", height + 6)
.attr("dx", x({ x: .45 }))
.attr("dy", ".71em")
.attr("text-anchor", "middle")
.text(function (d, i) { return i; });
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment