D3 Stack Layout Experiments
by ramnathv
HTML
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//rawgit.com/jrideout/melt.js/master/melt.js"></script>
<svg></svg>
<button id="update">Dodge</button>
<button id="update2">Stack</button>
CoffeeScript
dataset = [
{ apples: 5, oranges: 10, grapes: 22, id: 1 },
{ apples: 4, oranges: 12, grapes: 28, id: 2 },
{ apples: 2, oranges: 19, grapes: 32, id: 3 },
{ apples: 7, oranges: 23, grapes: 35, id: 4 },
{ apples: 23, oranges: 17, grapes: 43, id: 5}
];
data_m = melt(dataset, ["id"], varName = "x", valName = "y")
data_2 = d3.nest()
.key((d) -> d.x)
.map(data_m)
data_2 = d3.values(data_2)
stack = d3.layout.stack()
data_3 = stack(data_2)
console.log JSON.stringify(d3.merge(data_2))
width = 600
height = 400
margin = {left: 20, right: 20, bottom: 20, top: 20}
svg = d3.select("svg")
.attr("width", width + margin.left + margin.bottom)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(#{margin.left}, #{margin.top})")
S =
x: d3.scale.ordinal().rangeRoundBands([0, width], 0)
y: d3.scale.linear().range([height, 0])
# FIXME: make domains data dependent
# S.x.domain(d3.range(5))
S.x.domain(d3.range(5))
S.y.domain([0, 90])
S.c = d3.scale.category20()
.domain(["apples", "oranges", "grapes"])
A =
x: (d) -> d._id
rectAttrs =
x: (d) -> S.x A.x d
y: (d) -> S.y(d.y + d.y0)
width: (d) -> S.x.rangeBand()
height: (d) -> S.y(d.y0) - S.y(d.y + d.y0)
stroke: "black"
fill: (d) -> S.c(d.x)
data_4 = d3.merge(data_2)
data_4.sort((a, b) ->
d3.ascending(a._id, b._id) or
d3.ascending(a.x, b.x)
)
rect = svg.selectAll("rect")
.data(data_4).enter()
.append("rect")
.attr(rectAttrs)
rectAttrs2 =
x: (d, i) -> S.x i
y: (d) -> S.y(d.y)
width: S.x.rangeBand()
height: (d) -> S.y(0) - S.y(d.y)
fill: (d) -> S.c(d.x)
d3.select("#update").on "click", ->
S.x.domain(d3.range(15))
rectAttrs2.width = S.x.rangeBand()
rect.data(data_4)
.transition()
.delay((d, i) -> Math.floor(i/3)/5*750)
.attr
x: (d, i) -> S.x i
width: S.x.rangeBand()
#.transition().duration(750)
.attr
height: (d) -> S.y(0) - S.y(d.y)
y: (d) ->...