DC.JS /交叉过滤器:具有线性x轴的条形图的y轴百分比?

时间:2019-05-14 07:10:05

标签: dc.js crossfilter

我想在dc.js条形图的y轴上显示百分比,该百分比在过滤图表本身或某些其他图表时可以动态更改。

这是我的情况:

var ndx = crossfilter(dataCsvInitial);
var all = ndx.groupAll();
var accCredLimDim = ndx.dimension(function(d) { return d.acct_curr_crlimit;});

然后,我按垃圾箱分组:

var value_range_credlim = maxCredLim - minCredLim;  // defined earlier...
var nb_of_bins_credlim = 50,
    bin_width_credlim = value_range_credlim/nb_of_bins_credlim;
var accCredLimGrp = accCredLimDim.group(function(d) {return Math.floor(d/bin_width_credlim)*bin_width_credlim;});

并绘制我的条形图:

 var creditBar = dc.barChart("#creditDistrib");
        creditBar
            .width(600)
            .height(250)
            .margins({top: 10, right: 50, bottom: 30, left: 50})
            .dimension(accCredLimDim)
            .group(accCredLimGrp)
            .transitionDuration(500)
            .x(d3.scaleLinear().domain([minCredLim, maxCredLim]))
            .xUnits(function(){return nb_of_bins_credlim;})
            .elasticY(true)
            .brushOn(true)
            .xAxisLabel("Credit Limit")

仅通过自定义条形图的yAxis().tickFormat()属性,即用刻度值除以当前要过滤的总行数,我就成功地完成了我想要做的事情:

    creditBarChart.yAxis().tickFormat(function (d) {
            return 100*d/all.value() + '%';
        });

由于我的y轴是有弹性的,所以每次转换时我都会重新计算这些滴答声:

        creditBar
            .on("pretransition", function(){

            creditBar.yAxis().tickFormat(function (d) {
                if (!creditBar.hasFilter()){
                    return Math.trunc(100*d/all.value()) + '%';
                }
            });
        });

如您所见,条形图被过滤时,我不会更新刻度线。确实,当它被过滤后,我希望刻度线保持不变,因为y轴不应改变。但是,由于我将滴答值除以all.value(),因此在过滤条形图本身时此规则不起作用。显示的百分比显然是错误的。

这个问题非常接近解决我的问题:link,但仅适用于分类条形图...

如何在y轴刻度上显示百分比,这些百分比在过滤其他图表以及过滤图表本身时会发生变化? 除了过滤指定图表的影响之外,是否会计算出某种all.value()

谢谢!

1 个答案:

答案 0 :(得分:1)

由于您希望groupAll不遵守此图表上的过滤器,因此应使用the chart dimension's groupAll而不是交叉过滤器对象上的过滤器。从文档中:

  

注意:分组与交叉过滤器的当前过滤器相交,除外   关联维度的过滤器。因此,分组方法考虑   仅满足除此维度的过滤器之外的每个过滤器的记录。   因此,如果付款的交叉过滤器按类型和总数过滤,则   groupAll by total仅观察按类型的过滤器。

那是一个大嘴巴,但我希望意图清楚。

var accCredLimDim = ndx.dimension(function(d) { return d.acct_curr_crlimit;});
var all = accCredLimDim.groupAll();

一旦这样做,您就不必在tickFormat定义中加入if语句:

creditBar
    .on("pretransition", function(){
        creditBar.yAxis().tickFormat(function (d) {
            return Math.trunc(100*d/all.value()) + '%';
        });
    });

if语句有两个原因是错误的。首先,此图表上可能有一个过滤器,其他图表上也有一个过滤器。其次,您调用的任何访问器,例如tickFormat,每次调用时都需要返回一个值。但是,如果此图表上有任何过滤器,它将返回undefined,因为这是JS中的默认返回值。