D3:.transition() 不适用于事件
Posted
技术标签:
【中文标题】D3:.transition() 不适用于事件【英文标题】:D3: .transition() not working with events 【发布时间】:2017-11-13 16:46:20 【问题描述】:我正忙着在 Angular4 中使用 D3 绘制条形图。
// Enter Phase
this.chart.selectAll('.bar')
.data(this.barData)
.enter()
.append('rect')
.attr('class', 'bar');
// Update Phase
let bars = this.chart.selectAll('.bar').transition()
.attr('x', (d) => return this.x(this.parseTime(d.date.toUpperCase()));)
.attr('y', (d) => return this.y(d.point))
.attr('width', 15)
.attr('height', (d) => return this.charDimensions.height - this.y(d.point);)
.on("mouseover", function (d) D3.select(this).style('opacity', 0.5);)
.on("mouseout", function (d) D3.select(this).style('opacity', 1);)
.on("click", (d) => this.barClicked.emit(d););
// Exit phase
this.chart.selectAll('.bar')
.data(this.barData)
.exit().remove();
在我的绘图方法中,当我调用 animate()
时出现错误:Error: unknown type: mouseover
。这是有道理的,因为我可能试图在 D3 返回的转换上调用on("<event>")
,所以转换效果就在那里,但是,转换中断后的所有内容,即:动画有效,但绘图被破坏了.
但是当我尝试执行以下操作时:
// Update Phase
let bars = this.chart.selectAll('.bar');
bars.transition();
bars.attr('x', (d) => return this.x(this.parseTime(d.date.toUpperCase()));)
.attr('y', (d) => return this.y(d.point))
.attr('width', 15)
.attr('height', (d) => return this.charDimensions.height - this.y(d.point);)
.on("mouseover", function (d) D3.select(this).style('opacity', 0.5);)
.on("mouseout", function (d) D3.select(this).style('opacity', 1);)
.on("click", (d) => this.barClicked.emit(d););
没有发生错误,但什么也没发生,没有到新数据集的过渡效果。
【问题讨论】:
增加持续时间有帮助吗?let bars = this.chart.selectAll('.bar').transition().duration(3000).attr(...
.
试过了,没有运气@wazz
@wazz 你不需要设置持续时间:如果没有,D3 会创建一个默认的 250 毫秒持续时间。
【参考方案1】:
这里的问题是两个使用相同名称的不同方法之间的混淆:
selection.on(typenames[, listener]) transition.on(typenames[, listener])既然你有一个过渡选择,当你写...
.on(...
该方法期望看到三个东西(或类型名):
“开始” “结束” “中断”但是,“mouseover”、“mouseout”或“click”都不是。然后你得到你的错误......
> Uncaught Error: unknown type: mouseover
解决方案:
将事件侦听器绑定到常规选择。然后,在此之后,创建您的过渡选择。
因此,在您的情况下,将所有 on
侦听器绑定到“输入”选择(顺便说一句,这更有意义),将它们从更新选择中删除。
看看这个小演示。首先,我创建一个常规的输入选择,并在其中添加事件侦听器:
var bars = svg.selectAll(null)
.data(data)
.enter()
.append("rect")
//some attr here
.on("mouseover", function(d)
console.log(d)
);
然后,我添加过渡:
bars.transition()
.duration(1000)
etc...
将鼠标悬停在栏上以查看“鼠标悬停”的工作情况:
var svg = d3.select("svg");
var data = [30, 280, 40, 140, 210, 110];
var bars = svg.selectAll(null)
.data(data)
.enter()
.append("rect")
.attr("x", 0)
.attr("width", 0)
.attr("y", function(d, i)
return i * 20
)
.attr("height", 18)
.attr("fill", "teal")
.on("mouseover", function(d)
console.log(d)
);
bars.transition()
.duration(1000)
.attr("width", function(d)
return d
)
.as-console-wrapper max-height: 25% !important;
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
【讨论】:
以上是关于D3:.transition() 不适用于事件的主要内容,如果未能解决你的问题,请参考以下文章
Vue:使用 scoped 时 CSS 不适用于 D3 的 svg
v-leave-active 动画工作,但 v-enter-active 动画不适用于 <transition-group>