如何使用 dc.js 创建堆积条形图?
How to create a stacked bar chart using dc.js?
我想使用 DC.JS 创建堆积条形图。
我尝试使用来自 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。
我想要 '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();
我已经研究了一段时间,并且有一些额外的发现:
当我用以下内容替换数据数组时,它起作用了
数据= [{"Name":"Abby","Type":"1"}, {"Name":"Abby","Type" :"2"}, {"Name":"Bob","Type":"1"} ]
但只有当我换出 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)
时它才有效
但是,当我用以下内容替换数据数组时,它不起作用:
数据 = [ {"Name":"Abby","Type":"3"}, {"Name":"Abby","Type" :"4"}, {"Name":"Bob","Type":"2"} ]
我认为根本问题在于 root_function。
在您当前的示例中,v.Speed 始终是 NaN
。因为 +x.Type
尝试将 "Apple" 之类的字符串转换为数字但失败了。如果你只是想计数,那么在你的 reducer 中添加或减去 1
,而不是 v.Speed
。然后你需要更新你的 sel_stack
代码和图表代码来处理这个变化,当然。
这是您数据中两种类型的工作示例。您必须更新它以处理任意数量的类型,可能是通过预先构建所有类型的数组,然后遍历它以将堆栈添加到图表: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即可计数:
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();
我想使用 DC.JS 创建堆积条形图。
我尝试使用来自 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。
我想要 '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();
我已经研究了一段时间,并且有一些额外的发现:
当我用以下内容替换数据数组时,它起作用了
数据= [{"Name":"Abby","Type":"1"}, {"Name":"Abby","Type" :"2"}, {"Name":"Bob","Type":"1"} ]
但只有当我换出 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)
时它才有效
但是,当我用以下内容替换数据数组时,它不起作用:
数据 = [ {"Name":"Abby","Type":"3"}, {"Name":"Abby","Type" :"4"}, {"Name":"Bob","Type":"2"} ]
我认为根本问题在于 root_function。
v.Speed 始终是 NaN
。因为 +x.Type
尝试将 "Apple" 之类的字符串转换为数字但失败了。如果你只是想计数,那么在你的 reducer 中添加或减去 1
,而不是 v.Speed
。然后你需要更新你的 sel_stack
代码和图表代码来处理这个变化,当然。
这是您数据中两种类型的工作示例。您必须更新它以处理任意数量的类型,可能是通过预先构建所有类型的数组,然后遍历它以将堆栈添加到图表: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即可计数:
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();