添加预转换会干扰图例悬停/单击

Adding pretransition interferes with legend hover / click

我想修改多系列图表上的默认转换并设法使用“转换前”事件侦听器实现它,但这样做似乎会禁用您通过 DC“免费”获得的突出显示传奇。假设 Michelson–Morley 实验数据以通常的方式加载,我的代码如下所示:

// MULTI-SERIES LINE CHART
const runDimension = morley.dimension(d => [d.Expt, d.Run]);
const runGroup = runDimension.group().reduceSum(d => d.Speed);

const multiSeries = new dc.SeriesChart("#multi-series");

multiSeries
  .width(500)
  .height(300)
  .chart(cht => dc.lineChart(cht).curve(d3.curveBasis))
  .dimension(runDimension)
  .group(runGroup)
  .keyAccessor(d => d.key[1])
  .valueAccessor(d => d.value)
  .seriesAccessor(d => d.key[0])
  .legend(dc.legend().x(50).y(250).itemHeight(15).gap(5).horizontal(2).legendWidth(500))
  .x(d3.scaleLinear().domain([1, 20]));


multiSeries.on("pretransition", function(chart) {

  const path = chart.selectAll("path.line");
  const totalLength = path.node().getTotalLength();

  path
    .attr("stroke-dasharray", totalLength + " " + totalLength)
    .attr("stroke-dashoffset", totalLength)
    .transition()
      .duration(1000)
      .attr("stroke-dashoffset", 0);

});

有没有办法同时保留自定义过渡和图例功能?

:下面有3个答案。第一个是转移话题,第二个是笨拙的解决方案,最后的答案是正确的!我保留了错误的线索,因为它们包含一些有用的信息。

命名空间事件侦听器

为避免冲突,您可以添加 D3 dispatch.on:

中记录的名称

The type may be optionally followed by a period (.) and a name; the optional name allows multiple callbacks to be registered to receive events of the same type, such as start.foo and start.bar.

在你的例子中:

multiSeries.on("pretransition.foo", function(chart) {

使用任何你想要的名字,只要它是唯一的。

在内部,dc.js should do this as well,主动防止冲突。

图例匹配

深入研究您的示例,冲突的实际根源是图例与基于颜色 和破折号样式 的关联图表相匹配。 (是的,图例根据属性而不是 ID 匹配项目很奇怪。)

我能够通过更改图例项获得一个基本示例,但我认为这只是因为 totalLength 不正确 (0)。

let leg = chart.legendables;
chart.legendables = function() {
  return leg.apply(chart).map(l => ({...l, dashstyle: [0,0]}));
}

它还将图例从正方形更改为线条:

Fiddle.

无论如何,这就是它不起作用的原因 - 与事件无关,只是传说的怪异方式。如果 totalLength 和 dashstyle 正确,则此解决方案可能不起作用。我没有看到你的转换的影响,所以可能有问题。

覆盖折线图

很容易覆盖折线图中的逻辑,使其只查看颜色,而不查看虚线样式。

一种方法是从中派生出 ES6 class:

class LineChartNoDashMapping extends dc.LineChart {
    _colorFilter (color, dashstyle, inv) {
        return function () {
            const item = d3.select(this);
            const match = item.attr('stroke') === color || item.attr('fill') === color;
            return inv ? !match : match;
        };
    }
}

_colorFilter 直接从 dc.LineChart (source) 复制而来,我们只是删除了与破折号样式有关的子句。 (我们还得排位赛d3.select。)

将我们的新 class 插入系列图表:

.chart(function(c) { return new LineChartNoDashMapping(c).curve(d3.curveCardinal); })

现在不需要 legendables 覆盖,并且图例按预期工作。好多了!

New fiddle.