D3.js DC.JS使用多列创建系列绘图

D3.js DC.JS使用多列创建系列绘图,d3.js,dc.js,crossfilter,D3.js,Dc.js,Crossfilter,我有下面的代码,我想在x轴和y轴上绘制日期,在两个单独的系列上应该有total和tip的值。从华盛顿可以吗 我找不到一种使用单独的列来确定序列的方法,而不是使用列来确定序列 多谢各位 var data = [ {date: "2011-11-14T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab"}, {date: "2011-11-14T16:20:19Z", quantity: 2, total: 190, tip

我有下面的代码,我想在x轴和y轴上绘制日期,在两个单独的系列上应该有total和tip的值。从华盛顿可以吗

我找不到一种使用单独的列来确定序列的方法,而不是使用列来确定序列

多谢各位

  var data = [
  {date: "2011-11-14T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-14T16:20:19Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-14T16:28:54Z", quantity: 1, total: 300, tip: 200, type: "visa"},
  {date: "2011-11-14T16:30:43Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T16:48:46Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T16:53:41Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0, type: "cash"},
  {date: "2011-11-14T16:58:03Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T17:07:21Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T17:22:59Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T17:25:45Z", quantity: 2, total: 200, tip: 0, type: "cash"},
  {date: "2011-11-14T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "visa"}
];

data.forEach(function(d){
  var tempDate = new Date(d.date);
  d.date = tempDate;

})

var facts = crossfilter(data);

var dateDimension = facts.dimension(function(d){ return d.date; });
var dateGroup = dateDimension.group().reduceSum(function(d){ return d.total; });

var minDate = dateDimension.bottom(1)[0].date;
var maxDate = dateDimension.top(1)[0].date;



var runDimension = facts.dimension(function(d){ return [d.quantity, d.total, d.type]; });
var runGroup = runDimension.group().reduceSum(function(d) { return d.tip; });

var series = dc.seriesChart("#chart")
    .width(1360)
    .height(300)
    .margins({top:40,bottom:60,right:80, left:60})
    .chart(function(cht){ return dc.lineChart(cht).renderArea(true).interpolate('basis'); }) //change how it looks here 
    .dimension(dateDimension)
    .group(runGroup)
    .keyAccessor(function(d){ return d.key[1];}) //x axis
    .valueAccessor(function(d){ return d.value;}) //y axis
    .seriesAccessor(function(d){ return d.key[2];}) //group
    .legend(dc.legend().x(100).y(200).itemHeight(13).gap(5).horizontal(2).legendWidth(1360).itemWidth(70))
    .x(d3.time.scale().domain([minDate,maxDate]));


    dc.renderAll();

您是对的,crossfilter不提供将行扩展到多个组箱的方法

当您想将数据转换为不同的形状以便dc.js读取时,通常的方法是使用

在这种情况下,我们可以创建两个组,一个用于提示,另一个用于总计,然后使用假组将它们组合起来

我们的主要维度是时间,因此没有必要用数量、总数或类型来混淆键

var totalGroup = dateDimension.group().reduceSum(function(d){ return d.total; });
var tipGroup = dateDimension.group().reduceSum(function(d){ return d.tip; });
这是一个假组的生成器:

function combine_groups(groups) {
    return {
        all: function() {
            var parts = Object.keys(groups).map(function(gk) {
                return groups[gk].all().map(function(kv) {
                    return {key: [gk, kv.key], value: kv.value};
                })
            });
            return Array.prototype.concat.apply([], parts);
        }
    };
}
所有伪组都是遵循对象的交叉筛选组约定的对象,使用单个方法
.All()
返回数据。方便地说,这意味着每次绘制图表时都会检索和聚合数据,以便它能够对其他图表中的过滤器做出反应

这里我们迭代提供给函数的组的名称。对于每个组,我们调用
group.all()
,然后映射键/值对,以便新键将组名作为第一个组件,旧键(本例中的日期)作为第二个组件

像这样构造假组:

var seriesGroup = combine_groups({
    total: totalGroup,
    tip: tipGroup
});
向系列图表提供假组,并告诉图表如何读取结果的系列和关键(X值)组件:

series
    .keyAccessor(function(d){ return d.key[1];}) //x axis
    .seriesAccessor(function(d){ return d.key[0];}) //group
不需要提供值访问器,因为默认情况下查找
kv.value

这是结果。(您可能需要重新考虑在序列图中使用面积图,因为面积将重叠。)

注:另一种等效的方法是使用合成图;系列图表所做的大部分工作是分离每个系列的数据,然后为复合图表实例化一组子图表


或者,您可能只想使用堆叠图表。但您询问了有关系列图表的问题,这很有趣,所以给您。

如果我使用此方法绘制状态图。我可以通过点击图例来添加过滤器吗?嗨@Pygirl,图例功能对于复合图表和系列图表是相同的-都高亮显示悬停的项目,并淡出其余的项目。我不确定你在这里是否真的是指“过滤”,比如“仅显示此数据并隐藏其余数据”。这是可能的,但它不是内置的。