D3:.transition()无法处理事件 [英] D3: .transition() not working with events
问题描述
我正忙于在Angular4中使用D3绘制条形图.
I'm busy plotting a bar chart using D3 in Angular4.
// 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>")
,所以过渡效果在那里,但是过渡后的所有内容都中断了,即:动画有效,但是绘图被打破了c
In my plotting method, when I call animate()
I get an error: Error: unknown type: mouseover
. Which makes sense, since I'm probably trying to call the on("<event>")
on a the transition returned by D3, the transition effect is there, however, everything after the transition breaks, i.e: The animation works, but the plotting is broken ofc.
但是,当我尝试执行以下操作时:
However when I attempt to do the following:
// 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);});
没有错误发生,但没有任何反应,对新数据集没有过渡效果.
No errors occur, but nothing happens, there is no transition effect to the new data set.
推荐答案
这里的问题是使用相同名称的两个不同方法之间的混淆:
The problem here is a confusion between two different methods that use the same name:
- selection.on(typenames[, listener])
- transition.on(typenames[, listener])
由于您具有转换选择,因此在编写时...
Since you have a transition selection, when you write...
.on(...
该方法希望看到三样东西(或类型名):
The method expects to see three things (or typenames):
- 开始"
- 结束"
- 中断"
但是,"mouseover","mouseout"或"click"都不是它们.然后你得到你的错误...
However, "mouseover", "mouseout" or "click" are none of them. And then you get your error...
> Uncaught Error: unknown type: mouseover
解决方案:
将事件侦听器绑定到常规选择.然后,在那之后,创建您的过渡选择.
Bind the event listeners to a regular selection. Then, after that, create your transition selection.
因此,在您的情况下,请将所有on
侦听器绑定到输入"选择(顺便说一句,这更有意义),将其从更新选择中删除.
Therefore, in your case, bind all the on
listeners to the "enter" selection (which, by the way, makes more sense), removing them from the update selection.
看一下这个小演示.首先,我创建一个常规的输入选择,并在其中添加事件侦听器:
Have a look at this little demo. First, I create a regular, enter selection, to which I add the event listener:
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...
将鼠标悬停在栏上以查看鼠标悬停"的工作原理:
Hover over the bars to see the "mouseover" working:
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()无法处理事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!