简体   繁体   English

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

[英]How to create a stacked bar chart using dc.js?

I'd like to create a stacked bar chart using DC.JS. 我想使用DC.JS创建堆积的条形图。

I've tried to utilize the documentation from DC.JS ( graph , source code ) to no avail - Below is my attempt ( here is my attempt in jsfiddle ) and my most recent attempt in CodePen . 我试图利用DC.JS的文档( 图形源代码 )毫无用处-以下是我的尝试( 这是我在jsfiddle中的尝试 )和我最近在CodePen中的尝试。

I'd like the 'Name' as the X axis and 'Type' as the stacks. 我想将“名称”作为X轴并将“类型”作为堆栈。

HTML 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 使用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();

I've been fiddling with this for some time and I have some additional findings: 我已经对此摆弄了一段时间,还有一些其他发现:

  • When I replace the data array with the following it works 当我用以下内容替换数据数组时,它可以工作

    data = [ {"Name":"Abby","Type":"1"}, {"Name":"Abby","Type":"2"}, {"Name":"Bob","Type":"1"} ] 数据= [{“名称”:“ Abby”,“类型”:“ 1”},{“名称”:“ Abby”,“类型”:“ 2”},{“名称”:“鲍勃”,“类型“:” 1“}]

  • But it only works when I swapped out dc 1.7.5 ( https://cdnjs.cloudflare.com/ajax/libs/dc/1.7.5/dc.min.js ) with dc 2.1.0-dev ( https://github.com/dc-js/dc.js/blob/develop/web/js/dc.js ) 但是它仅在我将dc 1.7.5( https://cdnjs.cloudflare.com/ajax/libs/dc/1.7.5/dc.min.js )与dc 2.1.0-dev( https:/ /github.com/dc-js/dc.js/blob/develop/web/js/dc.js

  • However when I replace the data array with the following it doesn't work: 但是,当我用以下内容替换数据数组时,它不起作用:

    data = [ {"Name":"Abby","Type":"3"}, {"Name":"Abby","Type":"4"}, {"Name":"Bob","Type":"2"} ] 数据= [{“名称”:“ Abby”,“类型”:“ 3”},{“名称”:“ Abby”,“类型”:“ 4”},{“名称”:“鲍勃”,“类型“:” 2“}]

I believe the root issue lies in the root_function. 我相信根本问题在于root_function。

v.Speed is always NaN in your current example. v.Speed在您当前的示例中始终为NaN Because +x.Type attempts to convert a string like "Apple" into a number and fails. 因为+x.Type尝试将“ Apple”之类的字符串转换为数字,但失败。 If you just want to count, then add or subtract 1 in your reducer, rather than v.Speed . 如果只想计数,则在减速器中加减1而不是v.Speed Then you need to update your sel_stack code and chart code to handle this change, of course. 当然,您需要更新sel_stack代码和图表代码以处理此更改。

Here's a working example for the 2 types in your data. 这是数据中两种类型的工作示例。 You'll have to update it to handle arbitrary numbers of types, probably by building an array of all your types up front and then looping through it to add stacks to the chart: http://codepen.io/anon/pen/GjjyOv?editors=1010 您可能必须更新它以处理任意数量的类型,可能是通过预先构建所有类型的数组,然后循环遍历以将堆栈添加到图表中: http : //codepen.io/anon/pen/GjjyOv ?编辑= 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;});

In the reducer, just add and subtract 1 to count: 在减速器中,只需加减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 no longer takes a number, but a key: sel_stack不再使用数字,而是一个密钥:

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

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

Here we hard-code the stack key, for the purpose of the example: 出于示例的目的,在此我们对堆栈键进行硬编码:

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

Again, the other hard-coded stack key. 同样,另一个硬编码的堆栈键。 You'll need to recreate the loop after creating some sort of data structure that holds all of your stack values. 创建包含所有堆栈值的某种数据结构后,您需要重新创建循环。

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

chart.render();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM