【问题标题】:DC.JS/Crossfilter: Percentage on y-axis of a bar chart with linear x-axis?DC.JS/Crossfilter:具有线性 x 轴的条形图的 y 轴百分比?
【发布时间】:2019-05-14 07:10:05
【问题描述】:

我想在 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() 会被计算出来,不包括过滤指定图表的影响?

谢谢!

【问题讨论】:

    标签: dc.js crossfilter


    【解决方案1】:

    由于您希望 groupAll 不观察此图表上的过滤器,因此您应该使用 the chart dimension's groupAll 而不是 crossfilter 对象上的那个。来自文档:

    注意:分组与交叉过滤器的当前过滤器相交,除了 用于关联维度的过滤器。因此,组方法考虑 仅满足除此维度的过滤器之外的所有过滤器的记录。 所以,如果支付的交叉过滤器是按类型和总计过滤的,那么 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 中的默认返回值。

    【讨论】:

    • 非常感谢!这个笔记实际上很清楚......尽管我之前遇到过这个笔记,但我的理解并不完整。也非常感谢您始终如一地回答所有这些问题,这非常有帮助,尤其是对于非程序员。
    猜你喜欢
    • 2020-04-20
    • 1970-01-01
    • 2018-12-15
    • 1970-01-01
    • 1970-01-01
    • 2014-07-07
    • 2013-12-27
    • 2018-11-25
    • 2017-08-27
    相关资源
    最近更新 更多