D3.js 我是否错误地映射或嵌套了此数据?

D3.js 我是否错误地映射或嵌套了此数据?,d3.js,D3.js,我正在寻找一些关于如何修复如何将数据可视化为条形图的指针。我已经创建了一个小倍数的可视化数据,随着时间的推移出现。由于数据收集方式的性质,数据共享某些属性。举例来说,您可以在下面看到.csv的摘录,其中重复了组和日期: group,date,totals acid,1641,8438 acid,1641,0 acid,1641,0 beef,1641,977.85 beef,1641,0 beef,1641,0 beef,1641,164 beef,1641,5.25 bird,1641,121

我正在寻找一些关于如何修复如何将数据可视化为条形图的指针。我已经创建了一个小倍数的可视化数据,随着时间的推移出现。由于数据收集方式的性质,数据共享某些属性。举例来说,您可以在下面看到.csv的摘录,其中重复了
日期

group,date,totals
acid,1641,8438
acid,1641,0
acid,1641,0
beef,1641,977.85
beef,1641,0
beef,1641,0
beef,1641,164
beef,1641,5.25
bird,1641,121
bird,1641,0
bird,1641,12
bird,1641,1558
bird,1641,729
bird,1641,1680
bird,1641,0
bird,1641,343
bird,1641,3
bird,1641,2092
bird,1641,0
bird,1641,0
bird,1641,107
bird,1641,2679
bird,1641,167
bird,1641,649
boar,1641,41
boar,1641,13
cheese,1641,13
cheese,1641,22
cheese,1641,1071
cheese,1641,17195
(您可以看到。)

我遇到的问题是,无论何时共享
日期
,而不是将
总计
列相加,而是将数据堆叠在另一列之上。例如,请参见:

我所要做的是将数据显示为一个条形图。(我有一个y轴未正确缩放的第二个问题)。我曾试图用它来解决多年来的问题(这对
),但似乎无法用
日期
来解决

到目前为止,我的代码如下:

var margin = {top: 20, right: 30, bottom: 30, left: 50},
    width = 400 - margin.right - margin.left,
    height = 150 - margin.top - margin.bottom,
    parse = d3.time.format("%Y").parse;

// scales
var x = d3.time.scale().range([0, width]),
    y = d3.scale.linear().range([0, height]),
    yscaled = d3.scale.linear().range([height, 0]);

// load data
d3.csv("revised.csv", function(error, data) {

  // nest values by group
  var groups = d3.nest()
      .key(function(d) { return d.group; })
      .entries(data);

  // parse dates and numbers, assume values are sorted by date
  // compute the maximum totals per group
  groups.forEach(function(s) {
    s.values.forEach(function(d) { d.date = parse(d.date); d.totals = +d.totals; });
    s.maxtotals = d3.max(s.values, function(d) { return d.totals; });
  });

  // compute the minimum and maximum date across groups
  x.domain([
    d3.min(groups, function(s) { return s.values[0].date; }),
    d3.max(groups, function(s) { return s.values[s.values.length - 1].date; })
  ]);
  // y.domain([0, d3.max(data, function(d) { return d.totals; })]);

  // add an SVG element for each group
  var svg = d3.select("body").selectAll("g")
      .data(groups)
    .enter().append("svg")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom);

  var canvas_g = svg.append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
      .each(function(d) {
          var g = d3.select(this);
          g.append("g");
        // .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        y.domain([0, d3.max(d.values, function(r) { return r.totals; })]);
        yscaled.domain([0, d3.max(d.values, function(r) { return r.totals; })]);

      // Draw the charts.

        g.selectAll("rect.aevents")
          .data(d.values)
        .enter().append("rect")
          .attr("height", function(p) {return y(p.totals)})
          .attr("width", 5)
          .attr("x", function(p, q) {return x(p.date)})
          .attr("y", function(p) {return height - y(p.totals)})
          // .on("click", function(p) {console.log(p.date)})
          .attr("class", "bar");
      });

  // draw x axis
  canvas_g.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(d3.svg.axis().scale(x).orient("bottom"));

  // draw y axis
  canvas_g.append("g")
      .attr("class", "y axis")
      .call(d3.svg.axis().scale(yscaled).orient("left"));

  // add a small label for the group name
  svg.append("text")
      .attr("x", width + 40)
      .attr("y", height + 15)
      .attr("text-anchor", "end")
      .text(function(d) { return d.key; });

});
是否有其他方法可以循环浏览数据?或者,我是否需要以某种方式重新构造数据?提前谢谢你

首先,如果您想了解更多关于
d3.nest()
,您可以阅读答案

对于您的问题,一个好方法是首先使用
d3.nest()
嵌套元素,然后将组映射到它们所需的形式。其中:

function formatData(inputData){ 
    var array = d3.nest()
        .key(function(d){return d.group})
        .key(function(d){return d.date})
        .entries(inputData)
        .map(function(d){
            var group = d.key
            var values = d.values.map(function(dd){
                var date = dd.key
                var total = 0
                dd.values.forEach(function(ddd){
                    total = total + ddd.totals        
                })
                return {date:date, totals:total}
            })
            return {'group':group, 'values':values}
        })
    obj = {}
    array.forEach(function(d){
        obj[d.group] = d.values
    })
    return obj
}
使用
d3.csv()
加载的数据为
inputData
。这样,您就可以充分利用
nest()
和`map()``

如果您只想为牛肉绘制条形图,现在可以执行以下操作:

var beefData=formatData(myInput).beef


jsFIDLE:

当条形图在某个日期发生碰撞时,您希望如何表示它们?您是希望它们的大小都相同,并向右移动,冒着翻阅未来日期数据的风险,还是希望做其他事情?这种可视化的问题是,使用x坐标作为时间以外的另一个比例。对于这种用法,可能有更好的可视化方法。当数据在某个日期发生冲突时,我希望将数据汇总在一起。因此,在上面的例子中,对于
牛肉
,它将返回
1147.1
,而不是1641年的三条堆叠在一起?这将使它更容易…谢谢你的建议!我想我越来越接近了,但我得到了奇怪的数据返回。它或多或少是准确的,但是我在
总计中添加了零,就像这样:{“acid”:[{“date”:“1641”,“totals”:“0843800”},{“date”:“1644”,“totals”:“0435200”},{“date”:“1645”,“totals”:“0551800”},{“date”:“1648”,“totals”:“0700”},{“date”:“1656”,“totals”:“0000”},{“date 1657”,“totals”:“0000”},{“date 1659”,“totals”:“04800”},{“日期”:“1662”,“总计”:“0000”},{“日期”:“1663”,“总计”:“01205300”},{“日期”:“1664”,“总计”:“0192000”},{“日期”:“1665”,“总计”:“0000”}我访问CSV的方式是否存在问题?当我使用示例数据集运行所有内容时,它似乎工作正常:。问题是您没有将字符串转换为整数。只需将计算总计的行替换为:
total=total+parseFloat(ddd.totals)
。下面是相应的