首页 文章

dc.js将一些但不是所有图表选择应用于numberDisplay,同时保持图表之间的交互

提问于
浏览
2

我有一个具有以下行/列结构的数据集(数据):

Date        Category1      Category2       Revenue
30/12/2014  a              x               10    
30/12/2014  b              x               15
31/12/2014  a              x               11
1/1/2015    a              x               13
2/1/2015    a              x               14
2/1/2015    b              x                9
2/1/2015    c              z                4
...

基于数据,我创建了几个维度和组:

var ndx                 = crossfilter(data);
var cat1Dim             = ndx.dimension(function(d) {return d.Category1;});
var revenuePerCat1      = cat1Dim.group().reduceSum(function(d) { return d.Revenue; });
var cat2Dim             = ndx.dimension(function(d) {return d.Category2;});
var revenuePerCat2      = cat2Dim.group().reduceSum(function(d) { return d.Revenue; });
var dateDim             = ndx.dimension(function(d) { return d.Date; });
var revenuePerDate      = dateDim.group().reduceSum(function(d) { return d.Revenue; });

接下来,我创建以下图表:

  • 折线图; dimension = dateDim,group = revenuePerDate

  • 一个饼图; dimension = cat1Dim,group = revenuePerCat1

  • 一个饼图; dimension = cat2Dim,group = revenuePerCat2

除了图表,我还想通过数字显示来显示收入的年初至今 Value . 最初我想通过在reduceSum函数中添加一个简单的if条件来实现这一点,其中我将数据减少为仅包含当前年份的项目,如下所示:

var ytdRev = ndx.groupAll().reduceSum(function(d) { if(d.Date.getFullYear() == curYear) {return d.Revenue;} else{return 0;}});

然后通过以下方式调用包含numberDisplay项的框:

box_ytd
    .formatNumber("$,.4s")
    .valueAccessor(function(d) {return Math.round(d * 1000) / 1000; })
    .group(ytdRev);

如果选择饼图中显示的某个类别,则此工作完全正常,但如果还开始在折线图中过滤日期范围,则此方法不正确 . 也就是说,实际上将返回特定选择的“日期 - 迄今”值,而不是年初至今的值 . 虽然从技术角度来看这种行为是正确的,但我想知道如何指示dc.js,以便在呈现numberDisplay时只考虑某组图表中的图表选择 . 但是,在饼图中所做的选择应该更新折线图中显示的选择和numberDisplay . 理想情况下,我只想使用一个crossfilter实例,但我对任何涉及第二个crossfilter的建议持开放态度 .

EDIT:

基于戈登的评论,我玩了一个自定义缩减功能 . 而不是ndx.groupAll()我在维度级别上使用.groupAll()应用了以下reduce函数:

function reduceAdd(p,v) {
    if(v.Date.getFullYear() == curYear)
    p.revenue += +v.Revenue;
    return p;}
function reduceRemove(p,v) {
    if v.Date.getFullYear() == curYear)
    p.revenue -= +v.Revenue;
    return p;}
function reduceInitial() {
    return {revenue:0 };}

var ytdRev = dateDim.groupAll().reduce(reduceAdd, reduceRemove, reduceInitial);

numberDisplay中的.valueAccessor从d.value.revenue更改为d.revenue:

box_ytd
    .formatNumber("$,.4s")
    .valueAccessor(function(d) {return Math.round(d.revenue * 1000) / 1000; })
    .group(ytdRev);

numberDisplay现在将反映饼图中每个选择的当前年份的总值 . 日期选择只会影响饼图的值; numberDisplay与折线图共享相同的尺寸,因此numberDisplay不受该尺寸上任何选择的影响 .

1 回答

  • 1

    基于戈登的评论,我玩了一个自定义缩减功能 . 而不是ndx.groupAll()我在维度级别上使用.groupAll()应用了以下reduce函数:

    function reduceAdd(p,v) {
        if(v.Date.getFullYear() == curYear)
        p.revenue += +v.Revenue;
        return p;}
    function reduceRemove(p,v) {
        if v.Date.getFullYear() == curYear)
        p.revenue -= +v.Revenue;
        return p;}
    function reduceInitial() {
        return {revenue:0 };}
    
    var ytdRev = dateDim.groupAll().reduce(reduceAdd, reduceRemove, reduceInitial);
    

    numberDisplay中的.valueAccessor从d.value.revenue更改为d.revenue:

    box_ytd
        .formatNumber("$,.4s")
        .valueAccessor(function(d) {return Math.round(d.revenue * 1000) / 1000; })
        .group(ytdRev);
    

    numberDisplay现在将反映饼图中每个选择的当前年份的总值 . 日期选择只会影响饼图的值; numberDisplay与折线图共享相同的尺寸,因此numberDisplay不受该尺寸上任何选择的影响 .

相关问题