dc.js - 动态更改折线图中堆叠层的 valueAccessor 并重新绘制它

dc.js - dynamically change valueAccessor of a stacked layer in a lineChart and redraw it

我正在尝试实现一个显示基本数据的仪表板。

我实际上完全陷入了一个问题。奇怪的是,我在网上找不到任何类似的东西,所以我没有太多关于如何前进的线索。

我主要有两个图表:

我使用单选按钮 select 是按总和还是按平均值聚合分组数据(使用与此 example 相同的方法),然后我只使用:

stackChart.valueAccessor(/*function with new value (avg or sum)*/);
dc.redrawAll();

刷新基础层(消耗)。

我没能做到的是通过更新其 valueAccessor 来刷新 "stacked layer"!我找不到任何方法来访问它的 valueAccessor(或者,最坏的情况,只是完全删除堆叠层,然后仅使用“.stack(...)”添加一个新的刷新堆叠层)。

这是我的代码中构建图表的相应部分:

// Charts customization #js
        stackChart
            .renderArea(true)
            .height(350)
            .transitionDuration(1500)
            .dimension(dateDim)
            .group(powByTime, "Consumption")
            // BASE LAYER valueAccessor HERE
            .valueAccessor(function(d) { return d.value.conSum; })
            .x(d3.time.scale().domain([minDate, maxDate]))
            .xUnits(d3.time.days)
            .elasticY(true)
            .renderHorizontalGridLines(true)
            .legend(dc.legend().x(80).y(0).itemHeight(13).gap(5))
            .brushOn(false)
            // STACKED LAYER HERE
            .stack(powByTime, "Production", function(d) { return d.value.prodSum; })
            .rangeChart(volumeChart)
            .controlsUseVisibility(true)
        ;

我在这里寻找单选按钮的变化并重新绘制图层:

// Listen for changes
d3.selectAll('#select-operation input')
    .on('click', function() {
        var aggrMode = this.value;  // fetch "avg" or "sum" from buttons
        // UPDATE BASE LAYER HERE:
        stackChart.valueAccessor(function(d) { var sel = accessors[aggrMode]['consPow']; return d.value[sel]; });
        // ???HOW TO UPDATE STACKED LAYER valueAccessor function???
        //stackChart.stack.valueAccessor(function(d) { var sel = accessors[aggrMode]['prodPow']; return d.value[sel]; });
        dc.redrawAll();
    });

如果您需要有关我正在尝试做的事情的更多详细信息和完整代码,您可以查看

作为参考,它看起来像这样:

我真的不知道 dc.js,但是访问器一旦设置就可能无法更改。尝试为您的访问器编写一个函数,该函数将 return 总和或平均值,具体取决于您可以设置的某些变量的状态。

@Ryan 的解决方案可能会很好地工作(并且可能是更好的设计),但这里是 dc.js API 关于堆叠的内幕,以备不时之需。

this issue 中所述,组和堆栈 API 非常奇怪。它以 backward-compatible 的方式有机地增长,因此堆栈和堆栈顶部的值访问器都在一个美丽的分形中分支出来......好吧,不,它非常混乱。

但是这个问题也为您的问题提供了解决方案。由于 chart.group() 重置了堆栈集,只需继续在您的事件处理程序中从头开始构建它们:

    stackChart.group(powByTime, "Consumption") // this resets the stacks
        .valueAccessor(function(d) { var sel = accessors[aggrMode]['consPow']; return d.value[sel]; })
        .stack(powByTime, "Production", function(d) { var sel = accessors[aggrMode]['prodPow']; return d.value[sel]; });

在内部,它只是清空 layers/stacks 的数组,然后用一些引用填充它。

这是非常有效的,因为 dc.js 不会存储您的数据,除非它绑定到 DOM 元素。因此,使用旧组和值访问器重绘的工作量与使用新组和值访问器重绘的工作量相同。