forked from DimsumPanda's block: Stacked Bar Charts D3 v4
forked from me1er's block: Stacked Bar Charts D3 v4
xxxxxxxxxx
<meta charset="utf-8">
<style>
</style>
<body>
<div id="stackedbars">
<svg id="stacked" width="600" height="200"></svg>
</div>
<script src="//d3js.org/d3.v4.min.js"></script>
<script>
var data = [
{
"category": "Residential",
"quantile":[250,400,700,850,1235],
"market": [450, 850, 1150], // min, eff, max
"current": [400, 1100, 1180] // min, eff, max
},
{
"category": "Retail",
"quantile":[275,470,630,750,1080],
"market": [450, 650, 950], // min, eff, max
"current": [400, 690, 860] // min, eff, max
},
{
"category": "Office",
"quantile":[294,550,730,850,1180],
"market": [450, 650, 1150], // min, eff, max
"current": [400, 760, 1160] // min, eff, max
}
];
var svg = d3.select("#stacked"),
margin = {top: 20, right: 180, bottom: 30, left: 80},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom;
var g = svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var y = d3.scaleBand()
.rangeRound([height, 0])
.padding(0.3)
.align(0.3);
var x = d3.scaleLinear()
.rangeRound([0, width]);
var z = d3.scaleOrdinal().range(["#cdedfd", "#50c2fa", "#95dafd", "#cdedfd"]);
var stack = d3.stack();
var keys = data.map(d => d.category);
var stackData = stack.keys(keys)(data);
y.domain(data.map(function(d) { return d.category; }));
var xData = data
.reduce((a,d) => a.concat(d.quantile).concat(d.market).concat(d.current), []);
x.domain([d3.min(xData), d3.max(xData)]).nice();
z.domain(d3.range([0,4]));
g.selectAll(".serie")
.data(data)
.enter().append("g")
.attr("class", "serie")
.selectAll("rect")
.data(function(d) {
var a = new Array(d.quantile.length-1);
for (var i = 1; i < d.quantile.length; ++i) {
a[i-1] = {
"category": d.category,
"x0": d.quantile[i-1],
"x1": d.quantile[i]
};
}
return a;
})
.enter().append("rect")
.attr("fill", function(d,i) { return z(i) })
.attr("y", function(d) { return y(d.category) + 2 })
.attr("x", function(d) { return x(d.x0) })
.attr("width", function(d) { return x(d.x1) - x(d.x0) + 1 }) // +1 to prevent gaps between rects
.attr("height", y.bandwidth()-4);
g.selectAll(".marketMarker")
.data(data.filter(function(d){ return d.market[0] && d.market[2]; }))
.enter().append("line")
.attr("class","marketMarker")
.attr("y1", function(d) { return y(d.category) + y.bandwidth()/2 })
.attr("x1", function(d) { return x(d.market[0]); })
.attr("x2", function(d) { return x(d.market[2]); })
.attr("y2", function(d) { return y(d.category) + y.bandwidth()/2 })
.attr("stroke-width", 10)
.attr("stroke", "#ddd")
;
/*
g.selectAll(".marketMiddleMarker")
.data(data.filter(function(d){ return d.eff; }))
.enter().append("line")
.attr("class","marketMiddleMarker")
.attr("y1", function(d) { return y(d.ethnicity) + y.bandwidth()/2-4 })
.attr("x1", function(d) { return x(d.meff); })
.attr("x2", function(d) { return x(d.meff); })
.attr("y2", function(d) { return y(d.ethnicity) + y.bandwidth()/2+4})
.attr("stroke-width", 8)
.attr("stroke", "#ceeddf")
;
*/
g.selectAll(".marketMiddleMarker")
.data(data.filter(function(d){ return d.market[1]; }))
.enter().append("path")
.attr('transform',function(d) { return 'translate('+(x(d.market[1]))+','+(y(d.category) + y.bandwidth()/2)+')';})
.attr("class","marketMiddleMarker")
.attr('d', d3.symbol().type( function(d) { return d3.symbolCircle;}).size(y.bandwidth()))
.attr('fill', "#eee")
.style("fill-opacity", 0.9)
;
g.selectAll(".minMarker")
.data(data.filter(function(d){ return d.current[0]; }))
.enter().append("path")
.attr('transform',function(d) { return 'translate('+(x(d.current[0]))+','+(y(d.category) + y.bandwidth()/2)+') rotate(90)';})
.attr("class","minMarker")
.attr('d', d3.symbol().type( function(d) { return d3.symbolTriangle;}).size(y.bandwidth()*2))
.attr('fill', "#d13313")
.style("fill-opacity", 0.9)
;
g.selectAll(".maxMarker")
.data(data.filter(function(d){ return d.current[2]; }))
.enter().append("path")
.attr('transform',function(d) { return 'translate('+(x(d.current[2]))+','+(y(d.category) + y.bandwidth()/2)+') rotate(-90)';})
.attr("class","minMarker")
.attr('d', d3.symbol().type( function(d) { return d3.symbolTriangle;}).size(y.bandwidth()*2))
.attr('fill', "#d13313")
.style("fill-opacity", 0.9)
;
/*
g.selectAll(".middleMarker")
.data(data.filter(function(d){ return d.eff; }))
.enter().append("path")
.attr('transform',function(d) { return 'translate('+(x(d.eff))+','+(y(d.ethnicity) + y.bandwidth()/2)+')';})
.attr("class","minMarker")
.attr('d', d3.symbol().type( function(d) { return d3.symbolCircle;}).size(y.bandwidth()*3))
.attr('fill', "#d13313")
.style("fill-opacity", 0.9)
;
*/
g.selectAll(".middleMarker")
.data(data.filter(function(d){ return d.current[1]; }))
.enter().append("line")
.attr("class","marketMiddleMarker")
.attr("y1", function(d) { return y(d.category) })
.attr("x1", function(d) { return x(d.current[1]); })
.attr("x2", function(d) { return x(d.current[1]); })
.attr("y2", function(d) { return y(d.category) + y.bandwidth()})
.attr("stroke-width", 4)
.attr("stroke", "#d13313")
;
var xAxis = d3.axisBottom(x)
.ticks(6)
.tickSize(height)
;
g.append("g")
.attr("class", "axis axis--x")
// .attr("transform", "translate(0," + height + ")")
.call(customXAxis);
function customXAxis(g) {
g.call(xAxis);
g.select(".domain").remove();
// .append("text")
// .attr("x", 2)
// .attr("y", x.ticks(6).pop())
// .attr("dy", "0.35em")
// .attr("text-anchor", "start")
// .attr("fill", "#000");
g.selectAll(".tick line")
.attr("stroke-width", "1")
.style("stroke-opacity", 0.2)
.attr("stroke", "#666");
}
var yAxis = d3.axisLeft(y);
g.append("g")
.attr("class", "axis axis--y")
.call(customYAxis);
function customYAxis(g) {
g.call(yAxis);
g.select(".domain").remove()
.append("text")
.attr("x", 2)
.attr("y", y(x.ticks(10).pop()))
.attr("dy", "0.35em")
.attr("text-anchor", "start")
.attr("fill", "#000");
g.selectAll(".tick line").attr("stroke-width", "0");
}
/*
var legend = g.selectAll(".legend")
.data(keys)
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; })
.style("font", "10px sans-serif");
legend.append("rect")
.attr("x", width + 50)
.attr("width", 18)
.attr("height", 18)
.attr("fill", z);
legend.append("text")
.attr("x", width + 75)
.attr("y", 9)
.attr("dy", ".35em")
.attr("text-anchor", "start")
.text(function(d) { return d; });
*/
</script>
</body>
https://d3js.org/d3.v4.min.js