添加预转换会干扰图例悬停/单击
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]}));
}
它还将图例从正方形更改为线条:
无论如何,这就是它不起作用的原因 - 与事件无关,只是传说的怪异方式。如果 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 覆盖,并且图例按预期工作。好多了!
我想修改多系列图表上的默认转换并设法使用“转换前”事件侦听器实现它,但这样做似乎会禁用您通过 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 asstart.foo
andstart.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]}));
}
它还将图例从正方形更改为线条:
无论如何,这就是它不起作用的原因 - 与事件无关,只是传说的怪异方式。如果 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 覆盖,并且图例按预期工作。好多了!