D3 仅在 Vue 3 组件的第一个实例中正常工作
Posted
技术标签:
【中文标题】D3 仅在 Vue 3 组件的第一个实例中正常工作【英文标题】:D3 working properly only in first instance of Vue 3 component 【发布时间】:2021-10-31 04:37:00 【问题描述】:我正在开发 Vue 3 应用程序,我想在其中使用一个组件的多个实例。每个组件都应该有它的 D3 实例来显示各种 SVG 图像。在我的情况下,D3 仅在 Vue 组件的第一个实例上按预期工作。
点是由 D3 随机生成的。在检查元素时,我可以看到在组件的第二个实例中没有附加任何点。问题截图可以找到here.
我的 D3 组件如下所示:
<template>
<div class="fill-100">
<svg ref="svgRef" height=667>
<g></g>
</svg>
</div>
</template>
<script>
import ref, onMounted from "@vue/runtime-core";
import select, zoom from "d3";
export default
name: "SldSvgD3",
props: ["id"],
setup()
const svgRef = ref(null);
onMounted(() =>
const svg = select(svgRef.value);
svg.append("svg")
let data = [], width = 400, height = 667, numPoints = 100;
let zoom3 = zoom()
.on('zoom', handleZoom);
function handleZoom(e)
select('svg g')
.attr('transform', e.transform);
function initZoom()
select('svg')
.call(zoom3);
function updateData()
data = [];
for(let i=0; i<numPoints; i++)
data.push(
id: i,
x: Math.random() * width,
y: Math.random() * height
);
function update()
select('svg g')
.selectAll('circle')
.data(data)
.join('circle')
.attr('cx', function(d) return d.x; )
.attr('cy', function(d) return d.y; )
.attr('r', 3);
initZoom();
updateData();
update();
);
return svgRef
</script>
<style lang="scss">
.fill-100
width: 100%;
height: 100%;
</style>
D3 缩放和平移的实现取自this site
【问题讨论】:
【参考方案1】:我不知道d3.select()
调用的范围对于整个应用程序来说是全局的。在我的情况下,解决方案只是为根 div 创建唯一的 id 并在任何操作之前选择此 div。
This question 对我很有帮助。
完整代码:
<template>
<div class="fill-100" :id="'sld_div'+this.id">
</div>
</template>
<script>
import ref, onMounted from "@vue/runtime-core";
import * as d3 from "d3";
export default
name: "SldSvgD3",
props: ["id"],
setup(props)
const svgRef = ref(null);
const svg_width = 400;
const svg_height = 667;
onMounted(() =>
const svg = d3
.select("#sld_div"+props.id)
svg.append("svg")
.attr("id","sld_root"+props.id)
.attr("width", svg_width)
.attr("height", svg_height)
.append("g")
.attr("id","sld_root_g"+props.id)
let data = [], width = 600, height = 400, numPoints = 100;
let zoom = d3.zoom()
.on('zoom', handleZoom);
function handleZoom(e)
d3.select("#sld_div"+props.id)
.select('svg g')
.attr('transform', e.transform);
function initZoom()
d3.select("#sld_div"+props.id)
.select('svg')
.call(zoom);
function updateData()
data = [];
for(let i=0; i<numPoints; i++)
data.push(
id: i,
x: Math.random() * width,
y: Math.random() * height
);
function update()
d3.select("#sld_div"+props.id)
.select('svg g')
.selectAll('circle')
.data(data)
.join('circle')
.attr('cx', function(d) return d.x; )
.attr('cy', function(d) return d.y; )
.attr('r', 3);
initZoom();
updateData();
update();
);
return svgRef
</script>
<style lang="scss">
.fill-100
width: 100%;
height: 100%;
</style>
【讨论】:
以上是关于D3 仅在 Vue 3 组件的第一个实例中正常工作的主要内容,如果未能解决你的问题,请参考以下文章