创建具有包容性值的 D3 堆栈图

Create D3 Stack Chart with inclusive values

我想将 basic side bar chart 修改为堆叠条形图,这将反映部分金额:总计关系。我已经使用以下内容创建了一个 matrix

[{y:0, x0:221, x1:1670},
 {y:1, x0:581, x1:1473},
 {y:2, x0:2485, x1:2643},
 {y:3, x0:135, x1:8714},
 {y:4, x0:31, x1:211}]

供参考,在每种情况下,真实总数为 x0 + x1

我有一个普通的总计条形图,但我不明白如何将其转换为堆积图。此外,如果有一种方法可以在不改变数据的情况下实现这一点(从真实总数中减去 x0 得到 x1),那也是理想的。

现有条形图

// Constants
var width = 450,
    barHeight = 20,
    height = 300,
    padding = 10,
    leftMargin = 10;

var typeBarChart = d3.select('.typeBarChart')
  .attr('width', width)
  .attr('height', barHeight*dataGroupByType.length); // dataGroupByType is a D3 nest data series with length is 5

// X-axis; 
var x = d3.scale.linear()
    .domain([0, maxCrime]) // maxCrime determine elsewhere, approx. 8850
    .range([0, width]);

var chart = d3.select(".typeBarChart")
    .attr("width", width)
    .attr("height", barHeight * dataGroupByType.length);

var bar = chart.selectAll("g")
    .data(dataGroupByType)
    .enter()
    .append("g")
    .attr("transform", function(d, i) { return "translate(0," + i * barHeight + ")"; });

bar.append("rect")
    .attr("width", function(d) { return x(d.values); })
    .attr("height", barHeight - 1);

bar.append("text")
    .attr("x", function(d) {
      if (d.values < 1000) {
        return x(d.values) + 20;
      } else {
        return x(d.values) - 3;
      }
    })
    .attr("y", barHeight / 2)
    .attr("dy", ".35em")
    .text(function(d) { return d.values; });

代码模板存在一些问题.... 我提炼了一些以创建一个最简单的堆叠条形图。这将帮助您入门...

工作 fiddle: https://jsfiddle.net/egmf47ne/

代码:

HTML

<div class ="typeBarChart"></div>

JS

var _data = [{y:0, x0:221, x1:1670},
 {y:1, x0:581, x1:1473},
 {y:2, x0:2485, x1:2643},
 {y:3, x0:135, x1:8714},
 {y:4, x0:31, x1:211}]

// Constants
var width = 450,
    barHeight = 20,
    height = 300,
    padding = 10,
    leftMargin = 10;

var typeBarChart = d3.select('.typeBarChart')
  .append('svg')
  .attr('width', width)
  .attr('height', barHeight*_data.length); 

var x = d3.scale.linear()
    .domain([0, 8850]) // maxCrime
    .range([0, width]);

var bar = typeBarChart.selectAll("g")
    .data(_data)
    .enter()
    .append("g")
    .attr("transform", function(d, i) { return "translate(0," + i * barHeight + ")"; });

bar.append("rect")
        .attr("fill","blue") // blue bars of x0 + x1
    .attr("width", function(d) { return x(d.x0 + d.x1); })
    .attr("height", barHeight - 1);

bar.append("rect")
        .attr("fill","red")  // red bars of x0 only
    .attr("width", function(d) { return x(d.x0); })
    .attr("height", barHeight - 1);