使用来自 Mike Bostocks oberservablehq 示例的工具提示代码进行独立 d3v5 缩放后出现类型错误
Type error after making standalone d3v5 zoom with tooltip code from Mike Bostocks oberservablehq example
我正在尝试使用从 Mike 的 awesome https://observablehq.com/@d3/zoom-with-tooltip 下载的代码创建一个 html+js 文件
下面的代码显示数据和鼠标悬停有效,但尝试缩放失败:
index3.html:70 Uncaught TypeError: Cannot destructure property 'transform' of 'undefined' as it is undefined.
at SVGSVGElement.zoomed (index3.html:70)
at H.apply (d3.v5.min.js:2)
at kt (d3.v5.min.js:2)
at w.emit (d3.v5.min.js:2)
at w.zoom (d3.v5.min.js:2)
at d3.v5.min.js:2
at d3.v5.min.js:2
<!DOCTYPE html>
<meta charset="utf-8">
<title>Zoom with Tooltip from https://observablehq.com/@d3/zoom-with-tooltip</title>
<body>
<svg width="960" height="350"></svg>
</body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
var radius = 6;
var theta = Math.PI * (3 - Math.sqrt(5));
var step = 12;
var width = 800;
var height = 350;
function data() { //(radius,step,theta,width,height){
return (
Array.from({
length: 2000
}, (_, i) => {
const radius = step * Math.sqrt(i += 0.5),
a = theta * i;
return [
width / 2 + radius * Math.cos(a),
height / 2 + radius * Math.sin(a)
];
})
)
};
// Replaced by select below
// const svg = d3.create("svg")
// .attr("viewBox", [0, 0, width, height]);
const svg = d3.select('svg');
// all code below unchanged
const g = svg.append("g")
.attr("class", "circles");
g.append("style").text(`
.circles {
stroke: transparent;
stroke-width: 1.5px;
}
.circles circle:hover {
stroke: black;
}
`);
g.selectAll("circle")
.data(data)
.join("circle")
.datum(([x, y], i) => [x, y, i])
.attr("cx", ([x]) => x)
.attr("cy", ([, y]) => y)
.attr("r", radius)
.attr("fill", ([, , i]) => d3.interpolateRainbow(i / 360))
.on("mousedown", mousedowned)
.append("title")
.text((d, i) => `circle ${i}`);
svg.call(d3.zoom()
.extent([
[0, 0],
[width, height]
])
.scaleExtent([1, 8])
.on("zoom", zoomed));
function mousedowned(event, [, , i]) {
d3.select(this).transition()
.attr("fill", "black")
.attr("r", radius * 2)
.transition()
.attr("fill", d3.interpolateRainbow(i / 360))
.attr("r", radius);
}
function zoomed({
transform
}) {
g.attr("transform", transform);
}
</script>
我只是看不出问题所在,感谢任何帮助。
我认为您对 d3.event
将是传递给事件处理程序的第一个参数感到困惑,而相反 - 至少对于 d3 v5 - 它是一个你可以访问的全局变量。更改 zoomed
和 mousedowned
的签名为我修复了它。
<!DOCTYPE html>
<meta charset="utf-8">
<title>Zoom with Tooltip from https://observablehq.com/@d3/zoom-with-tooltip</title>
<body>
<svg width="960" height="350"></svg>
</body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
var radius = 6;
var theta = Math.PI * (3 - Math.sqrt(5));
var step = 12;
var width = 800;
var height = 350;
function data() { //(radius,step,theta,width,height){
return (
Array.from({
length: 2000
}, (_, i) => {
const radius = step * Math.sqrt(i += 0.5),
a = theta * i;
return [
width / 2 + radius * Math.cos(a),
height / 2 + radius * Math.sin(a)
];
})
)
};
// Replaced by select below
// const svg = d3.create("svg")
// .attr("viewBox", [0, 0, width, height]);
const svg = d3.select('svg');
// all code below unchanged
const g = svg.append("g")
.attr("class", "circles");
g.append("style").text(`
.circles {
stroke: transparent;
stroke-width: 1.5px;
}
.circles circle:hover {
stroke: black;
}
`);
g.selectAll("circle")
.data(data)
.join("circle")
.datum(([x, y], i) => [x, y, i])
.attr("cx", ([x]) => x)
.attr("cy", ([, y]) => y)
.attr("r", radius)
.attr("fill", ([, , i]) => d3.interpolateRainbow(i / 360))
.on("mousedown", mousedowned)
.append("title")
.text((d, i) => `circle ${i}`);
svg.call(d3.zoom()
.extent([
[0, 0],
[width, height]
])
.scaleExtent([1, 8])
.on("zoom", zoomed));
function mousedowned([, , i]) {
d3.select(this).transition()
.attr("fill", "black")
.attr("r", radius * 2)
.transition()
.attr("fill", d3.interpolateRainbow(i / 360))
.attr("r", radius);
}
function zoomed() {
g.attr("transform", d3.event.transform);
}
</script>
我正在尝试使用从 Mike 的 awesome https://observablehq.com/@d3/zoom-with-tooltip 下载的代码创建一个 html+js 文件 下面的代码显示数据和鼠标悬停有效,但尝试缩放失败:
index3.html:70 Uncaught TypeError: Cannot destructure property 'transform' of 'undefined' as it is undefined.
at SVGSVGElement.zoomed (index3.html:70)
at H.apply (d3.v5.min.js:2)
at kt (d3.v5.min.js:2)
at w.emit (d3.v5.min.js:2)
at w.zoom (d3.v5.min.js:2)
at d3.v5.min.js:2
at d3.v5.min.js:2
<!DOCTYPE html>
<meta charset="utf-8">
<title>Zoom with Tooltip from https://observablehq.com/@d3/zoom-with-tooltip</title>
<body>
<svg width="960" height="350"></svg>
</body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
var radius = 6;
var theta = Math.PI * (3 - Math.sqrt(5));
var step = 12;
var width = 800;
var height = 350;
function data() { //(radius,step,theta,width,height){
return (
Array.from({
length: 2000
}, (_, i) => {
const radius = step * Math.sqrt(i += 0.5),
a = theta * i;
return [
width / 2 + radius * Math.cos(a),
height / 2 + radius * Math.sin(a)
];
})
)
};
// Replaced by select below
// const svg = d3.create("svg")
// .attr("viewBox", [0, 0, width, height]);
const svg = d3.select('svg');
// all code below unchanged
const g = svg.append("g")
.attr("class", "circles");
g.append("style").text(`
.circles {
stroke: transparent;
stroke-width: 1.5px;
}
.circles circle:hover {
stroke: black;
}
`);
g.selectAll("circle")
.data(data)
.join("circle")
.datum(([x, y], i) => [x, y, i])
.attr("cx", ([x]) => x)
.attr("cy", ([, y]) => y)
.attr("r", radius)
.attr("fill", ([, , i]) => d3.interpolateRainbow(i / 360))
.on("mousedown", mousedowned)
.append("title")
.text((d, i) => `circle ${i}`);
svg.call(d3.zoom()
.extent([
[0, 0],
[width, height]
])
.scaleExtent([1, 8])
.on("zoom", zoomed));
function mousedowned(event, [, , i]) {
d3.select(this).transition()
.attr("fill", "black")
.attr("r", radius * 2)
.transition()
.attr("fill", d3.interpolateRainbow(i / 360))
.attr("r", radius);
}
function zoomed({
transform
}) {
g.attr("transform", transform);
}
</script>
我只是看不出问题所在,感谢任何帮助。
我认为您对 d3.event
将是传递给事件处理程序的第一个参数感到困惑,而相反 - 至少对于 d3 v5 - 它是一个你可以访问的全局变量。更改 zoomed
和 mousedowned
的签名为我修复了它。
<!DOCTYPE html>
<meta charset="utf-8">
<title>Zoom with Tooltip from https://observablehq.com/@d3/zoom-with-tooltip</title>
<body>
<svg width="960" height="350"></svg>
</body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
var radius = 6;
var theta = Math.PI * (3 - Math.sqrt(5));
var step = 12;
var width = 800;
var height = 350;
function data() { //(radius,step,theta,width,height){
return (
Array.from({
length: 2000
}, (_, i) => {
const radius = step * Math.sqrt(i += 0.5),
a = theta * i;
return [
width / 2 + radius * Math.cos(a),
height / 2 + radius * Math.sin(a)
];
})
)
};
// Replaced by select below
// const svg = d3.create("svg")
// .attr("viewBox", [0, 0, width, height]);
const svg = d3.select('svg');
// all code below unchanged
const g = svg.append("g")
.attr("class", "circles");
g.append("style").text(`
.circles {
stroke: transparent;
stroke-width: 1.5px;
}
.circles circle:hover {
stroke: black;
}
`);
g.selectAll("circle")
.data(data)
.join("circle")
.datum(([x, y], i) => [x, y, i])
.attr("cx", ([x]) => x)
.attr("cy", ([, y]) => y)
.attr("r", radius)
.attr("fill", ([, , i]) => d3.interpolateRainbow(i / 360))
.on("mousedown", mousedowned)
.append("title")
.text((d, i) => `circle ${i}`);
svg.call(d3.zoom()
.extent([
[0, 0],
[width, height]
])
.scaleExtent([1, 8])
.on("zoom", zoomed));
function mousedowned([, , i]) {
d3.select(this).transition()
.attr("fill", "black")
.attr("r", radius * 2)
.transition()
.attr("fill", d3.interpolateRainbow(i / 360))
.attr("r", radius);
}
function zoomed() {
g.attr("transform", d3.event.transform);
}
</script>