Hello Everyone I'm struggling for a while with what i thought was a peace of Cake, but not.
- I'have a Vuejs (v2) component that render a D3 (v7.8.5). radial Tree (full project is build with electron).
The rendering is fine
- I have a @wheel on the div that contains the SVG rendering
- The wheel trigger a method that check if ctrl key is down (zoom in zoom out only when ctrl+ wheel)
- If wheel Delta <0 Do ZoomIn
- If wheel Delta >0 Do ZoomOut
My code so far looks like
Template
...
<v-row class ="ma-4 d-flex justify-center" v-if="Mainview">
<div ref="chartContainer" class="chart-container" @wheel="HandleChartZoom"></div>
</v-row>
...
Script
...
mounted(){
this.drawChart(this.graphData)
},
methods:{
drawChart(datapayload) {
d3.select("svg").remove()
const data = datapayload
const width = 1500;
const height = 900;
const radius = Math.min(width, height) / 2.6;
const svg = d3
.select(this.$refs.chartContainer)
.append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', `translate(${width / 2}, ${height / 2})`)
const treeLayout = d3.tree().size([2 * Math.PI, radius]);
const root = d3.hierarchy(data);
const treeData = treeLayout(root);
// eslint-disable-next-line
const link = svg
.selectAll('.link')
.data(treeData.links())
.enter()
.append('path')
.attr('class', 'link')
.attr('d', d3.linkRadial().angle(d => d.x).radius(d => d.y))
.attr('stroke-width', '2px')
.attr('stroke', d => d.source.data.color)
.attr('fill', 'none')
const node = svg
.selectAll('.node')
.data(treeData.descendants())
.enter()
.append('g')
.attr('class', 'node')
.attr(
'transform',
d => `rotate(${(d.x * 180) / Math.PI - 90}) translate(${d.y}, 0)`
)
// eslint-disable-next-line
.on('mouseover', function(d){
d3.select(this).select('text').attr("font-size", "1.5em").attr("font-weight", "bold");
})
// eslint-disable-next-line
.on('mouseout',function(d){
d3.select(this).select('text').attr("font-size", "0.65em").attr("font-weight", "normal");
})
.on("contextmenu",d => this.handleNodeRightClick(d));
node
.append('circle')
.attr('r', 4)
.attr('fill', function(d) { return d.data.color; })
node
.append('text')
.attr('dy', '0.31em')
.attr("font-size", "0.65em")
.attr('x', d => (d.x < Math.PI ? 6 : -6))
.attr('text-anchor', d => (d.x < Math.PI ? 'start' : 'end'))
.attr('transform', d => (d.x >= Math.PI ? 'rotate(180)' : null))
.text(d => d.data.name)
.attr('id',function(d) { return d.data.Id; })
// .on('click',d => this.handleNodeClick(d))
},
HandleChartZoom(e){
if(!e.ctrlKey){return}
const Xpos= e.offsetX
const Ypos=e.offsetY
if(e.deltaY<0){
console.log("zoomIn")
// do ZoomIn 10 % center on Xpos Ypos
}
if(e.deltaY>0){
console.log("zoomOut")
// do ZoomOut 10% center on mouse position Xpos Ypos
}
}
}
...
I tried several Way to Achieve ZoomIn ZoomOut Like
- How to set up d3-zoom correctly in vue?
- https://www.d3indepth.com/zoom-and-pan/
- https://snyk.io/advisor/npm-package/d3-zoom/functions/d3-zoom.zoom
- https://d3-graph-gallery.com/graph/interactivity_zoom.html
But nothing worked in my case Thanks for the help