D3v6 拖动事件回调函数触发未定义参数
D3v6 drag event callback function fire with undefined parameters
根据 D3v6 文档,我无法在使用 d3.symbol 实用程序绘制的路径 SVG 元素上实现简单的拖动行为。打字稿 class 在这里显示为上下文。
事件在正确的元素上触发,但回调函数似乎没有收到 (event, datum) 参数。
任何帮助将不胜感激。
import * as d3 from "d3";
export default class Sliders {
svg: SVGSVGElement;
constructor(svg: SVGSVGElement){
this.svg = svg;
}
draw(){
const g = d3.select(this.svg).append('g').attr('class', 'symbol');
const circle = g.append('circle').attr('r', 200);
const D = d3.drag() // `event` and `d` are always undefined in 3 lines below
.on("start", (event, d) => circle.attr("stroke", "lime"))
.on("drag", (event, d: any) => (d.x = event.x, d.y = event.y))
.on("end", (event, d) => circle.attr("stroke", "black")) as any; // Could not fathom the proper type
circle.call(D);
}
}
为一些细节回答我自己。
剥离任何 webpack/typescript 业务,
在单个html文件中,定义了拖动事件回调参数
<!DOCTYPE html>
<meta charset="utf-8">
<div id="data"> </div>
<script src="https://d3js.org/d3.v6.min.js"></script>
<script>
const svg = d3.select('#data').append('svg').attr('width', 500).attr('height', 500);
console.log(svg);
const circle = svg.append('circle').attr('r', 5).attr('cy', 25).attr('cx', 25);
// `event` parameter is defined
const D = d3.drag()
.on("start", (event, d) => circle.attr("stroke", "lime"))
.on("drag", (event, d) => {
console.log(event);
})
.on("end", (event, d) => circle.attr("stroke", "black"));
circle.call(D);
</script>
虽然没有解决我最初的问题。
问题的可能原因是第一个示例中使用的 d3
版本不是 v6.0。从 v5.x 到 v6.0 where the event is no longer a global variable but passed as a parameter in callbacks.
发生了重大变化
您的代码采用 v6.0 风格,因此它在第二个示例中有效,它从 https://d3js.org/
显式导入 v6.0
您可以确认您的原始代码是否是 运行 d3 v6.0,其中一个回调中带有 console.log(d3.event)
:
.on("drag", () => {
console.log(d3.event);
})
如果上面的代码记录了事件,则表示您的 d3 版本为 v5.x。
如果它有效,但打字稿无论如何也会给出类型错误,这意味着您的打字(@types/d3
)适用于 v6.0,因此它们与安装的 d3 版本不一致。
无论如何,如果 d3.event
有效,那么最简单的解决方案是将您的 d3 更新到 v6.0,因为您已经拥有与最新版本兼容的代码。
回调的第二个参数是元素绑定的数据。在你的例子中,它应该是 undefined
因为没有与圆相关联的数据(即 .append()
之前没有 .selectAll(...).data(...)
)。如果有兴趣,您可以查看a d3-drag example in v.6.0 that uses data binding以更好地理解它。
因此,在没有数据绑定的情况下,v5.0 中的最小拖动行为示例为:
.on("drag", function() {
d3.select(this).attr("cx", d3.event.x).attr("cy", d3.event.y);
})
在 v6.0 中:
.on("drag", function(event) {
d3.select(this).attr("cx", event.x).attr("cy", event.y);
})
节点:记得使用function
关键字而不是箭头函数(() => ...
)if you want acess to the correct this
object inside it
根据 D3v6 文档,我无法在使用 d3.symbol 实用程序绘制的路径 SVG 元素上实现简单的拖动行为。打字稿 class 在这里显示为上下文。 事件在正确的元素上触发,但回调函数似乎没有收到 (event, datum) 参数。 任何帮助将不胜感激。
import * as d3 from "d3";
export default class Sliders {
svg: SVGSVGElement;
constructor(svg: SVGSVGElement){
this.svg = svg;
}
draw(){
const g = d3.select(this.svg).append('g').attr('class', 'symbol');
const circle = g.append('circle').attr('r', 200);
const D = d3.drag() // `event` and `d` are always undefined in 3 lines below
.on("start", (event, d) => circle.attr("stroke", "lime"))
.on("drag", (event, d: any) => (d.x = event.x, d.y = event.y))
.on("end", (event, d) => circle.attr("stroke", "black")) as any; // Could not fathom the proper type
circle.call(D);
}
}
为一些细节回答我自己。 剥离任何 webpack/typescript 业务, 在单个html文件中,定义了拖动事件回调参数
<!DOCTYPE html>
<meta charset="utf-8">
<div id="data"> </div>
<script src="https://d3js.org/d3.v6.min.js"></script>
<script>
const svg = d3.select('#data').append('svg').attr('width', 500).attr('height', 500);
console.log(svg);
const circle = svg.append('circle').attr('r', 5).attr('cy', 25).attr('cx', 25);
// `event` parameter is defined
const D = d3.drag()
.on("start", (event, d) => circle.attr("stroke", "lime"))
.on("drag", (event, d) => {
console.log(event);
})
.on("end", (event, d) => circle.attr("stroke", "black"));
circle.call(D);
</script>
虽然没有解决我最初的问题。
问题的可能原因是第一个示例中使用的 d3
版本不是 v6.0。从 v5.x 到 v6.0 where the event is no longer a global variable but passed as a parameter in callbacks.
您的代码采用 v6.0 风格,因此它在第二个示例中有效,它从 https://d3js.org/
显式导入 v6.0您可以确认您的原始代码是否是 运行 d3 v6.0,其中一个回调中带有 console.log(d3.event)
:
.on("drag", () => {
console.log(d3.event);
})
如果上面的代码记录了事件,则表示您的 d3 版本为 v5.x。
如果它有效,但打字稿无论如何也会给出类型错误,这意味着您的打字(@types/d3
)适用于 v6.0,因此它们与安装的 d3 版本不一致。
无论如何,如果 d3.event
有效,那么最简单的解决方案是将您的 d3 更新到 v6.0,因为您已经拥有与最新版本兼容的代码。
回调的第二个参数是元素绑定的数据。在你的例子中,它应该是 undefined
因为没有与圆相关联的数据(即 .append()
之前没有 .selectAll(...).data(...)
)。如果有兴趣,您可以查看a d3-drag example in v.6.0 that uses data binding以更好地理解它。
因此,在没有数据绑定的情况下,v5.0 中的最小拖动行为示例为:
.on("drag", function() {
d3.select(this).attr("cx", d3.event.x).attr("cy", d3.event.y);
})
在 v6.0 中:
.on("drag", function(event) {
d3.select(this).attr("cx", event.x).attr("cy", event.y);
})
节点:记得使用function
关键字而不是箭头函数(() => ...
)if you want acess to the correct this
object inside it