繁体   English   中英

d3.js 堆叠条形图-修改堆叠顺序逻辑

[英]d3.js stacked bar chart - modify stack order logic

我想创建一个堆叠条形图,其中 rects 的顺序由数据值(即最大到最小、最高到最矮、最富有到最贫穷等)确定。 据我所知,在堆叠数据之后,初始顺序似乎得以保留。 这可以在我的代码片段中看到,硬编码数据让我们可以看到d3.stack()之前和之后发生的事情。 请注意,第三个 rect fmc3t1中的第三大变为t3中所有 rect 中最大的,尽管它在堆栈中的 position 保持不变:

 var margins = {top:100, bottom:300, left:100, right:100}; var height = 600; var width = 900; var totalWidth = width+margins.left+margins.right; var totalHeight = height+margins.top+margins.bottom; var svg = d3.select('body').append('svg').attr('width', totalWidth).attr('height', totalHeight); var graphGroup = svg.append('g').attr('transform', "translate("+margins.left+","+margins.top+")"); var data = [ {period:'t1', fmc1:2, fmc2:5, fmc3:6, fmc4:9, fmc5:10}, {period:'t2', fmc1:3, fmc2:4, fmc3:9, fmc4:8, fmc5:11}, {period:'t3', fmc1:3, fmc2:5, fmc3:15, fmc4:12, fmc5:10}, ]; var groups = d3.map(data, function(d){return(d.period)}).keys(); var subgroups = Object.keys(data[0]).slice(1); var stackedData = d3.stack().keys(subgroups) (data); //console.log(stackedData); var yScale = d3.scaleLinear().domain([0,80]).range([height,0]); var xScale = d3.scaleBand().domain(['t1','t2','t3']).range([0,width]).padding([.5]); var colorScale = d3.scaleOrdinal().domain(subgroups).range(["#003366","#366092","#4f81b9","#95b3d7","#b8cce4","#e7eef8","#a6a6a6","#d9d9d9","#ffffcc","#f6d18b","#e4a733","#b29866","#a6a6a6","#d9d9d9","#e7eef8","#b8cce4","#95b3d7","#4f81b9","#366092","#003366"].reverse()); graphGroup.append("g").selectAll("g").data(stackedData).enter().append("g").attr("fill", function(d) { return colorScale(d.key); }).selectAll("rect").data(function(d) { return d; }).enter().append("rect").attr("x", function(d) { return xScale(d.data.period); }).attr("y", function(d) { return yScale(d[1]); }).attr("height", function(d) { return yScale(d[0]) - yScale(d[1]); }).attr("width",xScale.bandwidth());
 <script src="https://d3js.org/d3.v5.min.js"></script>

我怀疑保留初始顺序对于计算堆栈中的相邻矩形可能有些必要。 然而,另一方面,在可视化之前对数据进行排序是可视化领域中非常普遍甚至是首选的做法,如果还没有人找到解决这个问题的方法,我会感到惊讶。

鉴于没有内置功能来指定堆栈中 rect 的顺序,我应该如何处理排序逻辑以实现从大到小的排序?

好吧,一个内置功能可以指定顺序,它是stack.order() 但是,它指定了计算整个系列的顺序,而不是堆栈中的每个值(我相信这就是你想要的......在这种情况下,你必须创建自己的函数)。

因此,例如,使用stack.order(d3.stackOrderDescending)

 var margins = { top: 0, bottom: 0, left: 0, right: 0 }; var height = 300; var width = 500; var totalWidth = width + margins.left + margins.right; var totalHeight = height + margins.top + margins.bottom; var svg = d3.select('body').append('svg').attr('width', totalWidth).attr('height', totalHeight); var graphGroup = svg.append('g').attr('transform', "translate(" + margins.left + "," + margins.top + ")"); var data = [{ period: 't1', fmc1: 2, fmc2: 5, fmc3: 6, fmc4: 9, fmc5: 10 }, { period: 't2', fmc1: 3, fmc2: 4, fmc3: 9, fmc4: 8, fmc5: 11 }, { period: 't3', fmc1: 3, fmc2: 5, fmc3: 15, fmc4: 12, fmc5: 10 }, ]; var groups = d3.map(data, function(d) { return (d.period) }).keys(); var subgroups = Object.keys(data[0]).slice(1); var stackedData = d3.stack().keys(subgroups).order(d3.stackOrderDescending) (data); //console.log(stackedData); var yScale = d3.scaleLinear().domain([0, 60]).range([height, 0]); var xScale = d3.scaleBand().domain(['t1', 't2', 't3']).range([0, width]).padding([.5]); var colorScale = d3.scaleOrdinal().domain(subgroups).range(["#003366", "#366092", "#4f81b9", "#95b3d7", "#b8cce4", "#e7eef8", "#a6a6a6", "#d9d9d9", "#ffffcc", "#f6d18b", "#e4a733", "#b29866", "#a6a6a6", "#d9d9d9", "#e7eef8", "#b8cce4", "#95b3d7", "#4f81b9", "#366092", "#003366"].reverse()); graphGroup.append("g").selectAll("g").data(stackedData).enter().append("g").attr("fill", function(d) { return colorScale(d.key); }).selectAll("rect").data(function(d) { return d; }).enter().append("rect").attr("x", function(d) { return xScale(d.data.period); }).attr("y", function(d) { return yScale(d[1]); }).attr("height", function(d) { return yScale(d[0]) - yScale(d[1]); }).attr("width", xScale.bandwidth());
 <script src="https://d3js.org/d3.v5.min.js"></script>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM