Reputation: 43
I have developed vuejs + d3.js + jit library project earlier. Nowadays, I need to attach hover function to d3.js svg element to show popup dialog of hovered element's information. I tried many times following some stackoverflow instructions. But all of them are not suitable for my one. Here is my snippet code.
allNodes.append("circle").attr("@mouseover", "console.log('test');");
allNodes.append("circle").attr(":v-on:mouseover", "console.log('dfdfd');");
The above code doesn't work in anyway because the d3.js element is rendered when vue component is mounted and the vue template parser can't compile the v-on, @mouseover attribute.
But following code works fine.
allNodes.append("circle").attr("onmouseover", "console.log('test');");
So I thought that I would attach native javascript function to vue method to show popup dialog.
But I'm not sure how to config all projects structure and where to place the native function in my project.
Please help me.
Thanks.
Upvotes: 4
Views: 2912
Reputation: 2042
You can use .on("mouseover", this.vueMethod)
on your d3 selection where this.vueMethod
is defined inside the Vue component's methods
object.
new Vue({
el: "#app",
data: {
todos: [
{ text: "Learn JavaScript", done: false },
{ text: "Learn Vue", done: false },
{ text: "Play around in JSFiddle", done: true },
{ text: "Build something awesome", done: true }
],
todoHovered: "hover a circle"
},
mounted() {
const svg = d3.select(this.$refs.chart)
.append("svg")
.attr("width", 400)
.attr("height", 100);
const circles = svg.selectAll("circle")
.data(this.todos).enter()
.append("circle")
.attr("cx", 10)
.attr("cy", (d,i) => 10 + i * 15)
.attr("r", 5)
.style("fill", d => d.done ? "green" : "red");
circles.on("mouseover", this.showMessage);
circles.on("mouseout", (e) => d3.select(e.currentTarget).attr("r", 5));
},
methods: {
showMessage(e, d) {
d3.select(e.currentTarget).attr("r", 8);
this.todoHovered = `${d.text} is ${d.done ? 'done' : 'not done'}`;
}
}
})
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
<script src="https://d3js.org/d3.v6.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<div id="app">
<div ref="chart">
</div>
<p>
Message: {{ todoHovered }}
</p>
</div>
Upvotes: 5