I have a Vue app that utilizes d3 to create rectangles within a child component.
The number of rectangles created is dependent on the values within the data property of the parent.
Modifying the data will update the existing rectangles in the child component.
After updating the data, the correct number of rectangles corresponding to the data are displayed.
My goal is to prevent the creation of a new "g" element each time.
One solution I have considered so far involves using d3.remove to delete the existing "g" element if an update occurs and then creating a new one.
// Parent Component
<template>
<Child :data="data" />
<button type="button" @click="changeData">Click to Change</button>
</template>
<script>
import Child from "./components/Child.vue";
export default {
name: "App",
components: {
Child,
},
data() {
return {
data: [1],
};
},
methods: {
changeData() {
this.data = [1, 2];
},
},
};
</script>
// Child Component
<template>
<div class="foo">
<svg ref="svgRef"></svg>
<h1>I Have This Prop</h1>
</div>
</template>
<script>
import d3 from "@/assets/d3";
import { onMounted, ref, watchEffect } from "@vue/runtime-core";
export default {
name: "Circles",
props: ["data"],
setup(props) {
const svgRef = ref(null);
onMounted(() => {
watchEffect(() => {
const selectSvg = d3.select(svgRef.value);
selectSvg
.selectAll("g")
.data(Object.values(props.data))
.join("g")
.attr("transform", (d, i) => `translate(60, ${i * 21})`)
.append("rect")
.attr("width", 20 + "px")
.attr("height", 20 + "px")
.attr("fill", d3.color("orange"));
});
});
return { svgRef };
},
};
</script>
<style scoped>
.limit {
max-width: 100px;
}
</style>