我正在尝试创建2个图表,一个条形和一个系列,该条形将显示每个商店的总收入,而系列将显示每年的多行收入。

这是jsfiddle https://jsfiddle.net/xc4bwgLj/

因此,当我单击条形图商店1时,我希望在系列表中看到该商店在新行中分别获得2017年和2016年的收入。当前,系列图以条形图的形式显示每个商店的总收入。

知道如何更改系列表以显示2016年和2017年每家商店的收入吗?

JsFiddle代码:

// generate data
var data = [];
var n = 1000.;

for (var i = 0; i < n; i++) {
console.log(Math.floor(Math.random() * (1 - 0 + 1)) + 0);
  data.push({
    id: (Math.floor(Math.random() * (1 - 0 + 1)) + 0),
    "i": i,
    x: Math.random(),
    "store_name": "Store"+(Math.floor(Math.random() * (1 - 0 + 1)) + 0),
    "2017_earnings": Math.random()*110,
    "2016_earnings": Math.random()*80
  });
}

// do some crossfilter stuff
var cf = crossfilter(data),
  series = cf.dimension(function(d) {
    return [d.store_name, d.i];
  }),
  series_grouped = series
  .group(function(d) {
  console.log(d)
    return [d[0], Math.floor(d[1] / 100.) * 100.];
  })
  .reduceSum(function(d) {
    return d.x;
  }),
  id = cf.dimension(function(d) {
    return d.store_name;
  }),
  id_grouped = id.group().reduceSum(function(d) {
    return d.x;
  });

// generate charts
var chart_width = 960,
  chart_height = 200;
console.log(dc);
dc.seriesChart("#chart_a").height(chart_height).width(.74 * chart_width)
  .chart(function(c) {
    return dc.lineChart(c).renderArea(true)
        .filterHandler(function(dimension, filter) {
        if(filter[0]) {
            dimension.filterFunction(function(d) {
            return d[1] > filter[0][0] && d[1] < filter[0][1];
          });
        } else {
            dimension.filterAll();
        }
        setTimeout(dc.redrawAll,0);
        return filter;
        });
  })
  .x(d3.scale.linear().domain([0, n]))
  .dimension(series)
  .group(series_grouped)
  .seriesAccessor(function(d) {
    return d.key[0];
  })
  .keyAccessor(function(d) {
    return d.key[1];
  })
  .valueAccessor(function(d) {
    return d.value;
  }).legend(dc.legend().x(350).y(350).itemHeight(13).gap(5).horizontal(1).legendWidth(140).itemWidth(70));
dc.barChart("#chart_b").height(chart_height).width(.24 * chart_width)
  .dimension(id)
  .group(id_grouped)
  .x(d3.scale.ordinal())
  .xUnits(dc.units.ordinal)
  .xAxis();

dc.renderAll();

最佳答案

这是使用不同数据形状的解决方案。我的另一个示例使用假组在聚合后更改形状。

使用不同的数据形状。

在这种情况下,我认为数据的形状不利于您要做的事情,因此在此答案中,我将更改形状。我将在第二个答案中尝试使用伪造的组。

序列图采用带有多键的单个组,并按行对组进行筛选。由于每一行都包含2016年和2017年的收入,因此无法使用交叉过滤器分别汇总它们。

因此,针对此尝试,我按收入年份划分了记录:

for (var i = 0; i < n; i++) {
  var id = Math.round(Math.random()),
    x = Math.random(),
      store = "Store"+Math.round(Math.random());
  data.push({
    id: id,
    i: i,
    x: x,
    store_name: store,
    earnings_year: 2016,
    earnings: Math.random()*80
  });
  data.push({
    id: id,
    i: i,
    x: x,
    store_name: store,
    earnings_year: 2017,
    earnings: Math.random()*110,
  });
}

我认为这会保留原始数据的所有质量,但是会按收入年份对记录进行拆分。我还简化了随机数的生成。 ;-)

现在,我们可以轻松创建使用earnings_year的多键维度。

我不认为在组键功能中进行四舍五入是可行的,因为the dimension and group key functions need to have the same ordering,所以我将其向上移动了:
  series = cf.dimension(function(d) {
    return [d.earnings_year, Math.floor(d.i / 100.) * 100.];
  }),

现在,我们简单地将相同的键分组,并减少earnings的总和而不是x(这是我认为的目的)。
  series_grouped = series.group()
  .reduceSum(function(d) {
    return d.earnings;
  }),

fiddle 的 fork ,通过商店https://jsfiddle.net/gordonwoodhull/urxLwh81/进行过滤

关于d3.js - dc.js系列图表多折线,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43764962/

10-12 00:20
查看更多