применить функцию суммы для анализа суммы столбца из csv в d3.js-диаграмму - PullRequest
0 голосов
/ 11 апреля 2019

У меня есть следующий набор данных в формате CSV:

Month,S40201,S40202,S40203
JAN,79,0,70
FEB,58,26,70
MAR,48,47,46
APR,64,98,77
MAY,79,71,64
JUN,86,103,116
JUL,95,75,95
AUG,0,40,3,5
SEP,60,82,79
OCT,98,101,79
NOV,60,81,75
DEC,7,30,46

Гистограмма D3.js должна отображать сумму каждого столбца «S40201», «S40202», «S40203» в виде столбца с соответствующей меткой на оси X. Метка должна быть именем столбца (первая строка).

<script>
// Set the margins
var margin = {top: 60, right: 100, bottom: 20, left: 80},
  width = 850 - margin.left - margin.right,
  height = 370 - margin.top - margin.bottom;

// Parse the month variable
var parseMonth = d3.timeParse("%b");
var formatMonth = d3.timeFormat("%b");

// Set the ranges
var x = d3.scaleBand().rangeRound([0, width]).padding(0.1)
var y = d3.scaleLinear().range([height, 0]);


// Create the svg canvas in the "graph" div
var svg = d3.select("#graph")
        .append("svg")
        .style("width", width + margin.left + margin.right + "px")
        .style("height", height + margin.top + margin.bottom + "px")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform","translate(" + margin.left + "," + margin.top + ")")
        .attr("class", "svg");

// Import the CSV data
d3.csv("data.csv", function(error, data) {
  if (error) throw error;

   // Format the data
  data.forEach(function(d) {
      d.Month = parseMonth(d.Month);
      d.S40201 = +d.S40201;
      d.S40202 = +d.S40202;
      d.S40203 = +d.S40203;
  });

    var nest = d3.nest()
      .key(function(d){
        return d.S40201,d.S40202,d.S40203;
      })
      .sortKeys(d3.ascending)
      .rollup(function(leaves){
            return d3.sum(leaves, function(d) {return (d.S40201,d.S40203,d.S40203)});
        })
      .entries(data)

console.log(nest)
  // Scale the range of the data
  x.domain(nest.map(function(d) { return d.key; }));
  y.domain([0, d3.max(nest, function(d) { return d.value; })]);

  // Set up the x axis
  var xaxis = svg.append("g")
       .attr("transform", "translate(0," + height + ")")
       .attr("class", "x axis")
       .call(d3.axisBottom(x)
          //.ticks(d3.timeMonth)
          .tickSize(0, 0)
          //.tickFormat(d3.timeFormat("%B"))
          .tickSizeInner(0)
          .tickPadding(10));

  // Add the Y Axis
   var yaxis = svg.append("g")
       .attr("class", "y axis")
       .call(d3.axisLeft(y)
          .ticks(5)
          .tickSizeInner(0)
          .tickPadding(6)
          .tickSize(0, 0));

 // yaxis.select(".domain").style("display","none")

  // Add a label to the y axis
  svg.append("text")
        .attr("transform", "rotate(-90)")
        .attr("y", 0 - 60)
        .attr("x", 0 - (height / 2))
        .attr("dy", "1em")
        .style("text-anchor", "middle")
        .text("Annual Sales")
        .attr("class", "y axis label");

  // Draw the bars
  svg.selectAll(".rect")
      .data(nest)
      .enter()
      .append("rect")
          .attr("class", "bar")
          .attr("x", function(d) { return x(d.key); })
          .attr("y", function(d) { return y(d.value); })
          .attr("width", x.bandwidth())
          .attr("height", function(d) { return height - y(d.value); });



})
</script>

С одним столбцом он работает нормально, но если я хочу добавить более одного столбца, он работает неправильно.

1 Ответ

0 голосов
/ 11 апреля 2019

Добро пожаловать в StackOverflow. Проблема, с которой вы сталкиваетесь, заключается в том, что ваши вложенные данные не так, как вам нравится. Если вы консольно регистрируете свои вложенные данные так, как у вас, ключ и значение одинаковы, а не заголовки.

Вместо этого, если вы вручную суммируете данные, вам будет проще. Например:

var nest = [];//create empty array
var keys = Object.keys(data[0]); //get the headers for your data
//for each header push the sum as an object
keys.forEach(function (d, i) {
  if (i == 0) return;//ignore first column as that is month
  //get the sumfrom your data for all the values of this key i.e. d
  var sum = d3.sum (data, function(e){ return e[d] }); 
  //create an object with this key value pair
  var obj = {
    key: d, //column name
    value: sum //sum for the column
  }
  nest.push(obj); //push this as an object in the nest array
})

Вот блок с правильным кодом, показывающий заголовки в виде меток на оси x и значения суммы. https://bl.ocks.org/akulmehta/724d63f0108304ede84a14fc145aad28

Пожалуйста, не стесняйтесь комментировать, если вам нужно больше объяснений / указаний, и, пожалуйста, не забудьте пометить его как ответ, если он отвечает на ваш вопрос.

Обновление 1 - только для выбранных столбцов

Основываясь на комментариях ниже, если вы хотите, чтобы выбранные столбцы просто заменили var keys = Object.keys(data[0]); на массив заголовков, таких как var keys = ['S40201','S40202','S40203'], а также удалите строку if (i == 0) return;//ignore first column as that is month, так как у нас больше нет столбца месяца. Окончательный код для этой части должен выглядеть следующим образом:

var nest = [];//create empty array
var keys = ['S40201','S40202','S40203']; //the headers for your data
//for each header push the sum as an object
keys.forEach(function (d, i) {
  //get the sumfrom your data for all the values of this key i.e. d
  var sum = d3.sum (data, function(e){ return e[d] }); 
  //create an object with this key value pair
  var obj = {
    key: d, //column name
    value: sum //sum for the column
  }
  nest.push(obj); //push this as an object in the nest array
})

А вот блок для демонстрации того, как он работает. Обратите внимание, что в файле CSV есть дополнительный столбец, но в графике это игнорируется. https://bl.ocks.org/akulmehta/724d63f0108304ede84a14fc145aad28

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...