Суммирование столбцов гистограммы с накоплением D3

У меня есть сгруппированная столбчатая диаграмма, как показано на этом изображении,http://pasteboard.co/1BKMicBq.jpg Я хочу сложить сумму соответствующих баров, как на изображении. У меня есть набор данных с суммированными значениями, готовыми к отображению, который выглядит так:

var months= [
{  "key": "Jan",
  "values[0]": 25000,
  "values[1]": 25000,
  "values[3]": 25000
       },  {  "key": "Feb",
  "values[0]": 25000,
  "values[1]": 25000,
  "values[3]": 25000
       },
         {  "key": "March",
  "values[0]": 25000,
  "values[1]": 25000,
  "values[3]": 25000
       }
 ]

Я пробовал это со следующим кодом, но я не могу получить данные по каждому бару.

var project_stackedbar = svg.selectAll(".project_stackedbar")
    .data(data)
  .enter().append("g")
    .attr("class", "g")
    .attr("transform", function (d) { return "translate(" + x0(d.Month) + ",0)"; });

project_stackedbar.selectAll("rect")
    .data(function (d) { return d.columnDetails; })
    .enter()
    .append("rect")
    .attr("width", x1.rangeBand())
    .attr("x", function (d) {
        return x1(d.column);
    })
    .attr("y", function (d) {
        return y(d.yEnd);
    })
    .attr("height", function (d) {
        return y(d.yBegin) - y(d.yEnd);
    })
    .style("fill", function (d) { return color(d.name); });
var sum = 0;

project_stackedbar.selectAll("text")
    .data(function (d) { return d.columnDetails; })
    .enter()
    .append("text")
    .attr("x", function (d) { return x1(d.column) })
    .attr("y", function (d) {
    return y(d.yEnd) + 15;})
    .text(function (d) {if (d.yEnd - d.yBegin !== 0) return "$" + (d.yEnd - d.yBegin);});

columns = svg.append("g")
      .selectAll("text")
    .data(months)
      .enter().append("text")
      .attr("x", function (d) {
          return (x1(d.column));
      })
      .attr("y", function (d, i) {
          return y(d.values[i]) - 60;
      })
      .attr("dy", "1.35em")
      .attr('style', 'font-size:13px')
      .text(function (d, i) {
          if (d.values !== 0) return d3.format("$")(d.values[i]);
      })
      .style({ fill: 'black', "text-anchor": "middle" });

Здесь я могу получить только 3 значения, которые будут напечатаны в первой группе столбцов. Я не могу получить правильное положение оси x на графике. может ли кто-нибудь направить меня сюда, я ошибаюсь?


person Nagendra Somayaji    schedule 30.06.2015    source источник


Ответы (1)


Я предполагаю, что часть кода, на которую вы ссылаетесь, это...

  columns = svg.append("g")
    .selectAll("text")
    .data(months)
    .enter().append("text")
    .attr("x", function (d) {
      return (x1(d.column));
    })
    .attr("y", function (d, i) {
      return y(d.values[i]) - 60;
    })
    .attr("dy", "1.35em")
    .attr('style', 'font-size:13px')
    .text(function (d, i) {
      if (d.values !== 0) return d3.format("$")(d.values[i]);
    })
    .style({ fill: 'black', "text-anchor": "middle" });

Это та часть, которую вы пытались повторно использовать из примера, на который я ссылался, и в этом примере она выполняет итоговые значения. Отсюда мое предположение...

  1. Вы привязываете переменную months из своего сообщения к текстовым элементам, которые вы создаете на g на svg
  2. В этих данных вы ссылаетесь на участника с именем column, который не существует. Вы не включили код, в котором вы определяете шкалу x1, но, предполагая, что она принимает даты, вы можете попробовать x1(d3.time.format("%b").parse(d.key)) вместо x1(d.column).
  3. В связанных данных у вас есть строковые ссылки на массивы, такие как «значения [0]», но в вашем коде вы ссылаетесь на d.values[i], которого нет в предоставленных вами данных. Вам нужно суммировать числовые значения элемента следующим образом: d3.sum(d3.values(d)).
  4. Вы вычитаете 60 из ваших значений y, что, вероятно, вытолкнет их за пределы области просмотра, итоги уже расположены с помощью .attr("dy", "1.35em"), поэтому, если вам нужно настроить, сделайте это там.

Учитывая все это, я предполагаю, что вам нужно что-то вроде этого:

  var months= [
    {  "key": "Jan",
      "values[0]": 25000,
      "values[1]": 25000,
      "values[3]": 25000
    },  {  "key": "Feb",
      "values[0]": 15000,
      "values[1]": 25000,
      "values[3]": 25000
    },
    {  "key": "March",
      "values[0]": 5000,
      "values[1]": 25000,
      "values[3]": 25000
    }
  ];
  var margin = {top: 20, right: 50, bottom: 35, left: 50};

  var width = 760 - margin.left - margin.right,
    height = 400 - margin.top - margin.bottom;



  var svg = d3.select("body")
    .append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

  var x1 = d3.scale.ordinal()
    .domain(months.map(function(d) { return d.key; }))
    .rangeRoundBands([10, width-10], 0.35);
  var y = d3.scale.linear()
    .domain([0, d3.max(months, function(d) {  return d3.sum(d3.values(d)); })])
    .range([height, 0]);

  columns = svg.append("g")
    .selectAll("text")
    .data(months)
    .enter().append("text")
    .attr("x", function (d) {
      return (x1(d.key));
    })
    .attr("y", function (d, i) {
      return y(d3.sum(d3.values(d)));
    })
    .attr("dy", "1.35em")
    .attr('style', 'font-size:13px')
    .text(function (d, i) {
      return d3.format("$")(d3.sum(d3.values(d)));
    })
    .style({ fill: 'black', "text-anchor": "middle" });
svg { outline: 1px solid black;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

person Cool Blue    schedule 01.07.2015