dc.js 复合图表切换图例在过滤后失去半透明性

dc.js composite chart toggle legend loses its translucence upon filtering

我已使用此 获得复合折线图的切换图例,并且效果非常好。 然而,在我向这个复合图表添加范围图表后,取消选择的图例失去了半透明性并变得正常。

如何在过滤时使取消选择的图例对象保持淡化状态?

以下截图供参考:

过滤前: 过滤后:

这是我用于图表的代码:

multiLineChart
                .width(1000)
                .height(300)
                .transitionDuration(1000)
                .margins({top: 30, right: 50, bottom: 40, left: 40})
                .x(d3.time.scale().domain([startDate,endDate]))
                .yAxisLabel("Data (Scaled)")
                .xAxisLabel("Date And Time")
                .rangeChart(timeSlider)
                .legend(dc.legend().x(800).y(20).itemHeight(13).gap(5))
                .renderHorizontalGridLines(true)
                //.dimension(DateDim)
                .compose([
                    dc.lineChart(multiLineChart)
                        .dimension(DateDim)
                        .colors('red')
                        .group(Line1Grp, 'Line1'),

                    dc.lineChart(multiLineChart)
                        .dimension(DateDim)
                        .colors('blue')
                        .group(Line2Grp, 'Line2')
                    ])
                .brushOn(false)

                .on('pretransition.hideshow', function(chart) {
                      chart.selectAll('g.dc-legend .dc-legend-item')
                        .on('click.hideshow', function(d, i) {
                          var subchart = chart.select('g.sub._' + i);
                          var visible = subchart.style('visibility') !== 'hidden';
                          subchart.style('visibility', function() {
                            return visible ? 'hidden' : 'visible';
                          });
                          d3.select(this).style('opacity', visible ? 0.2 : 1);
                        });
                    });
                //.xAxis().tickFormat(d3.time.format("%b %d %H:%M"));

            timeSlider  
                .width(1000) 
                .height(50)
                .margins({top: 0, right: 50, bottom: 20, left: 40})
                .dimension(DateDim)
                .group(Line1Grp)
                .x(d3.time.scale().domain([startDate, endDate]))
                .on("filtered", function (chart) {
                    dc.events.trigger(function () {
                        multiLineChart.focus(chart.filter());
                        dc.redrawAll(chart.chartGroup());
                    });
                })
                .xAxis().tickFormat(d3.time.format("%b %d"));

这是相同的 fiddle。 感谢任何帮助。

感谢您指出这一点 - 我之前的回答中有一个错误的做法,我回去更正了它。

将事件处理和绘制分开,并始终根据数据绘制所有内容,而不是一些正在运行的事件,这总是更好的风格,也更健壮。

如果您遵循这些做法,那么代码看起来更像这样:

function drawLegendToggles(chart) {
  chart.selectAll('g.dc-legend .dc-legend-item')
    .style('opacity', function(d, i) {
      var subchart = chart.select('g.sub._' + i);
      var visible = subchart.style('visibility') !== 'hidden';
        return visible ? 1 : 0.2;
    });
}

function legendToggle(chart) {
  chart.selectAll('g.dc-legend .dc-legend-item')
    .on('click.hideshow', function(d, i) {
      var subchart = chart.select('g.sub._' + i);
      var visible = subchart.style('visibility') !== 'hidden';
      subchart.style('visibility', function() {
        return visible ? 'hidden' : 'visible';
      });
      drawLegendToggles(chart);
    })
  drawLegendToggles(chart);
}

multiLineChart
  .on('pretransition.hideshow', legendToggle);

现在,每当我们重新绘制复合图表及其图例时 - 无论是什么原因 - 图例中的所有项目都将根据相应的子图表是否已被隐藏来更新。

并且事件处理程序只关心隐藏和显示图表,而不关心绘图。

Fork of your fiddle.