首页 文章

如何使用dc.js创建堆积条形图?

提问于
浏览
2

我想用DC.JS创建一个堆积条形图 .

我试图利用DC.JS(graphsource code)的文档无济于事 - 下面是我的尝试(here is my attempt in jsfiddle)和我最近在CodePen的尝试 .

我希望'Name'作为X轴,'Type'作为堆栈 .

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>
<script src="https://rawgithub.com/NickQiZhu/dc.js/master/web/js/crossfilter.js"></script>
<script src="https://cdnjs.site44.com/dc2.js"></script>
<div id="chart"></div>

使用Javascript

var data = [ {"Name":"Abby","Type":"Apple"}, {"Name":"Abby","Type":"Banana"}, {"Name":"Bob","Type":"Apple"} ]

data.forEach(function(x) {
  x.Speed = +x.Type;
});

var ndx = crossfilter(data)

var xdim = ndx.dimension(function (d) {return d.Name;});

function root_function(dim,stack_name) {
    return dim.group().reduce(
  function(p, v) {
    p[v[stack_name]] = (p[v[stack_name]] || 0) + v.Speed;
    return p;}, 
  function(p, v) {
    p[v[stack_name]] = (p[v[stack_name]] || 0) - v.Speed;
    return p;}, 
  function() {
    return {};
  });}

var ydim = root_function(xdim,'Type')

function sel_stack(i) {
return function(d) {
  return d.value[i];
};}

var chart = dc.barChart("#chart");

chart
  .x(d3.scale.ordinal().domain(xdim))
  .dimension(xdim)
  .group(ydim, "1", sel_stack('1'))
  .xUnits(dc.units.ordinal);

for(var i = 2; i<6; ++i)
  chart.stack(ydim, ''+i, sel_stack(i));

chart.render();

我已经习惯了一段时间了,我还有一些额外的发现:

  • 当我用以下内容替换数据数组时,它可以工作

data = [{“Name”:“Abby”,“Type”:“1”},{“Name”:“Abby”,“Type”:“2”},{“Name”:“Bob”,“Type” “:”1“}]

data = [{“Name”:“Abby”,“Type”:“3”},{“Name”:“Abby”,“Type”:“4”},{“Name”:“Bob”,“Type” “:”2“}]

我认为根本问题在于root_function .

1 回答

  • 5

    v.Speed在您当前的示例中始终为 NaN . 因为 +x.Type 尝试将类似"Apple"的字符串转换为数字而失败 . 如果您只想计算,则在减速器中添加或减去 1 ,而不是 v.Speed . 然后,您需要更新 sel_stack 代码和图表代码以处理此更改 .

    这里's a working example for the 2 types in your data. You' ll必须更新它以处理任意数量的类型,可能是通过预先构建所有类型的数组,然后循环遍历它以向图表添加堆栈:http://codepen.io/anon/pen/GjjyOv?editors=1010

    var data = [ {"Name":"Abby","Type":"Apple"}, {"Name":"Abby","Type":"Banana"}, {"Name":"Bob","Type":"Apple"} ]
    
    var ndx = crossfilter(data)
    
    var xdim = ndx.dimension(function (d) {return d.Name;});
    

    在reducer中,只需加1和减1即可:

    var ydim = xdim.group().reduce(
      function(p, v) {
        p[v.Type] = (p[v.Type] || 0) + 1;
        return p;}, 
      function(p, v) {
        p[v.Type] = (p[v.Type] || 0) - 1;
        return p;}, 
      function() {
        return {};
      });
    

    sel_stack不再需要一个数字,而是一个关键:

    function sel_stack(valueKey) {
    return function(d) {
      return d.value[valueKey];
    };}
    
    var chart = dc.barChart("#chart");
    

    为了示例的目的,我们在这里硬编码堆栈密钥:

    chart
      .x(d3.scale.ordinal().domain(xdim))
      .dimension(xdim)
      .group(ydim, "Apple", sel_stack('Apple'))
      .xUnits(dc.units.ordinal);
    

    同样,另一个硬编码的堆栈密钥 . 在创建包含所有堆栈值的某种数据结构之后,您需要重新创建循环 .

    //for(var i = 2; i<6; ++i)
      chart.stack(ydim, 'Banana', sel_stack('Banana'));
    
    chart.render();
    

相关问题