forked from DimsumPanda's block: Stacked Bar Charts D3 v4
forked from me1er's block: Stacked Bar Charts D3 v4
forked from me1er's block: Quantile stacked
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 NBR_TICKS = 6;
var data = [
{
"category": "Residential",
"quantile":[199,400,700,850,1399],
"topTriangle": [450, 1150], // min, max
"topDiamond": [850], // eff
"bottomTriangle": [400, 1390], // min, max
"bottomDiamond": [1401] // eff
}
,
{
"category": "Office",
"quantile":[275,470,630,750,1080],
"topTriangle": [450, 950], // min, eff, max
"topDiamond": [650], // eff
// "bottomTriangle": [400, 1400], // min, eff, max
"bottomTriangle": [400, 1150], // min, eff, max
"bottomDiamond": [850] // eff
},
{
"category": "Retail",
"quantile":[294,550,730,850,1180],
"topTriangle": [450, 1150], // min, eff, max
"topDiamond": [650], // eff
"bottomTriangle": [400, 1160], // min, eff, max
"bottomDiamond": [760] // eff
},
{
"category": "Craft / Industry",
"quantile":[294,550,730,850,1180],
"topTriangle": [450, 1150], // min, eff, max
"topDiamond": [650], // eff
"bottomTriangle": [400, 1160], // min, eff, max
"bottomDiamond": [760] // eff
}
];
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.5)
.align(0.3);
var x = d3.scaleLinear()
.rangeRound([0, width]);
var z = d3.scaleOrdinal().range(["#CBE7FF", "#8FCCFF", "#56b8fe", "#CBE7FF"]);
// var z = d3.scaleOrdinal().range(["#CBE7FF", "#8FCCFF", "#179DFF", "#CBE7FF"]);
var topMarkerColor = "#FF7C03";
var topMarkerColor = "#EA4424";
// var topMarkerColor = "#99250e";
// var bottomMarkerColor = "#7CDB45";
var bottomMarkerColor = "#2E8000";
// var bottomMarkerColor = "#00A859";
var keys = data.map(d => d.category).reverse();
y.domain(keys);
var xData = data
.reduce((a,d) => a.concat(d.quantile).concat(d.topDiamond).concat(d.topTriangle).concat(d.bottomDiamond).concat(d.bottomTriangle), []);
x.domain([d3.min(xData), d3.max(xData)]).nice(NBR_TICKS);
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) })
.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());
g.selectAll(".topTriangle")
.data(data)
.enter().append("g")
.attr("class", "topTriangle")
.selectAll("path")
.data(function(d) {return d.topTriangle.map(e => [d.category, e])})
.enter().append("path")
.attr('transform',function(d,i) {
return 'translate('+(x(d[1]))+','+(y(d[0]) + y.bandwidth()*0)+') rotate(180)'
})
.attr('d', d3.symbol().type( function(d) { return d3.symbolTriangle;}).size(y.bandwidth()*2))
.attr('fill', topMarkerColor)
.style("fill-opacity", 1)
;
g.selectAll(".bottomTriangle")
.data(data)
.enter().append("g")
.attr("class", "bottomTriangle")
.selectAll("path")
.data(function(d) {return d.bottomTriangle.map(e => [d.category, e])})
.enter().append("path")
.attr('transform',function(d,i) {
return 'translate('+(x(d[1]))+','+(y(d[0]) + y.bandwidth()*1)+') rotate(0)'
})
.attr('d', d3.symbol().type( function(d) { return d3.symbolTriangle;}).size(y.bandwidth()*2))
.attr('fill', bottomMarkerColor)
.style("fill-opacity", 1)
;
g.selectAll(".topDiamond")
.data(data)
.enter().append("g")
.attr("class", "topDiamond")
.selectAll("path")
.data(function(d) {return d.topDiamond.map(e => [d.category, e])})
.enter().append("path")
.attr('transform',function(d,i) {
return 'translate('+(x(d[1]))+','+(y(d[0]) + y.bandwidth()*0)+') rotate(90)'
})
.attr("class","topDiamond")
.attr('d', d3.symbol().type( function(d) { return d3.symbolDiamond;}).size(y.bandwidth()*3))
.attr('fill', topMarkerColor)
.style("fill-opacity", 1)
;
g.selectAll(".bottomDiamond")
.data(data)
.enter().append("g")
.attr("class", "bottomDiamond")
.selectAll("path")
.data(function(d) {return d.bottomDiamond.map(e => [d.category, e])})
.enter().append("path")
.attr('transform',function(d,i) {
return 'translate('+(x(d[1]))+','+(y(d[0]) + y.bandwidth()*1)+') rotate(90)'
})
.attr("class","topDiamond")
.attr('d', d3.symbol().type( function(d) { return d3.symbolDiamond;}).size(y.bandwidth()*3))
.attr('fill', bottomMarkerColor)
.style("fill-opacity", 1)
;
/*
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(180)';})
.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()*0+4)+') rotate(180)';})
.attr("class","minMarker")
.attr('d', d3.symbol().type( function(d) { return d3.symbolTriangle;}).size(y.bandwidth()*2))
// .attr('fill', "#fff")
// .attr('fill', "#d13313")
.attr('fill', "#99250e")
.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(NBR_TICKS)
.tickSize(height)
.tickFormat(d3.format(""))
;
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