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

D3.js dc.js-动态更改折线图中堆叠层的valueAccessor并重新绘制,d3.js,dc.js,crossfilter,D3.js,Dc.js,Crossfilter,我正在尝试实现一个仪表板来显示基本数据 事实上,我完全陷入了一个问题。奇怪的是,我在网上找不到任何类似的东西,所以我没有多少前进的线索 我主要有两个图表: 一个叫做“stackChart”的折线图 使用valueAccessor功能将消耗显示为基本图层 将产品显示为具有值存取器功能的堆叠层 一个称为“volumeChart”的条形图,它只是折线图的范围图 我使用单选按钮选择是按总和还是按平均值(使用与此相同的方法)聚合分组数据,然后我只使用: stackChart.valueAccess

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

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

我主要有两个图表:

  • 一个叫做“stackChart”的折线图
    • 使用valueAccessor功能将消耗显示为基本图层
    • 将产品显示为具有值存取器功能的堆叠层
  • 一个称为“volumeChart”的条形图,它只是折线图的范围图
我使用单选按钮选择是按总和还是按平均值(使用与此相同的方法)聚合分组数据,然后我只使用:

stackChart.valueAccessor(/*function with new value (avg or sum)*/);
dc.redrawAll();
刷新基础层(消耗)

我不想做的是通过更新其valueAccessor来刷新“堆叠层”!我找不到访问其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,但一旦设置了访问器,就可能无法更改它。尝试为您的访问器编写一个函数,该函数将返回总和或平均值,具体取决于您可以设置的某个变量的状态。

@Ryan的解决方案可能会很好(并且可能是一个更好的设计),但这里是dc.js API在堆叠方面的一些细节,以备您需要

正如在group and stack API中所描述的,API非常奇怪。它以向后兼容的方式有机地增长,因此堆栈和堆栈顶部的值访问器都以一种美丽的分形形式分支出来。。。嗯,不,它很乱

但这个问题也为你的问题提出了解决方案。由于
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]; });
在内部,它只是清空一个层/堆栈数组,然后用一些引用填充它

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