到目前为止我遇到的所有示例中(例如this,this或this)我看到d3中的堆积图表具有序数比例。我认为这是因为堆积图表被认为是条形图的扩展,这些条形图通常是轴上的顺序尺度。
就我而言,使用样本数据
{"a":[20,10],"b":[50,0],"c":[45,60],"d":[10,40]}
我需要生成一个带有线性刻度x轴的堆积图表,如下所示。
(每列的宽度是数组中2个元素之和的比例,每列中的2个单元格表示数组元素的值作为高度的百分比。列从左到右排序总结desc)
我尝试使用d3.stack
使用下面的代码生成这样的图表,但这对我来说似乎有点混乱,因为我正在访问堆栈数组的data
对象。
var body = d3.select('body');
var svg = body.append('svg').attr('height',200).attr('width',500);
var maing = svg.append('g');
var inputData = JSON.parse('{"a":[20,10],"b":[50,0],"c":[45,60],"d":[10,40]}')
// generate class
var colors = d3.schemeCategory10
var mysheet = document.styleSheets[0];
Object.keys(inputData).forEach(function(d,i){
mysheet.insertRule(`.${d}{fill:${colors[i]}; opacity:0.8}`);
mysheet.insertRule(`.${d}_h{fill:${colors[i]}; opacity:0.6}`);
});
// convert to flattened array
var vals = Array("p", "h");
var cumT = +0
var transformedData = Object.keys(inputData).map(function(d,i){
let o = {}; o.mp = d;
inputData[d].forEach(function(d,i){o[vals[i]]=d})
o.t=o.p+o.h;
return o;
}).sort(function(a,b){
return b.t - a.t
}).map(function(d,i){
let o = d; o.cumT = cumT += d.t
return o;
})
var stack = d3.stack().keys(vals);
var stackData = stack(transformedData);
var g = maing.selectAll('g')
.data(stackData).enter().append('g')
var x = d3.scaleLinear().domain([0,230]).range([0,100]) // TODO: use d3.max here
var y = d3.scaleLinear().domain([0,1]).range([0,140]) // some predefined height
g.selectAll('rect').data(function(d){return d})
.enter().append('rect')
.attr('x', function(d,i){return x(d.data.cumT-d.data.t)})
.attr('y', function(d,i){return y(d[0]/d.data.t)})
.attr('width', function(d,i){return x(d.data.t)})
.attr('height', function(d,i){return y((d[1]-d[0])/d.data.t) })
//.style('stroke-width', 1).style('stroke', 'black')
.attr('class', function(d){
return d3.select(this.parentNode).datum().key === "p" ? d.data.mp : d.data.mp+"_h";
})
;

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Stack Dev</title>
<style media="screen">
</style>
</head>
<body>
<script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script>
</body>
</html>
&#13;
生成这样的东西会有什么更好的方法?特别是如果我必须在一个页面上生成许多这样的小图表?