Below is the code to have a circle and scale it on mouseover using D3. It does what it is supposed to do but also takes cricle to somewhere else, meaning circle scales and jumps(translates) to some other location. I cannot apprehend the cause for it.
this.node = this.chartLayer.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(data.nodes)
.enter().append("circle")
.attr("r", 10)
.attr("fill", (d) => { return this.colors(d.group); })
.on('mouseover', function(d) {
d3.select(this).attr('transform', 'scale(' + 2 + ')');
})
This has nothing to do with D3 (be it v3 or v4). The problem here is that scale
is centered at the origin (0,0) of the SVG, which is the top left corner. Because of this, any element that is not on that position (0,0) will seem to move.
Have a look at this (hover over the circle):
var circle = d3.select("circle");
circle.on('mouseover', function(d) {
d3.select(this).attr('transform', 'scale(' + 2 + ')');
})
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg>
<circle cx="150" cy="75" r="20" fill="teal"></circle>
</svg>
Solution: translate the element to the origin before the scale:
var circle = d3.select("circle");
circle.on('mouseover', function(d) {
d3.select(this).attr('transform', 'translate(-150,-75) scale(' + 2 + ')');
})
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg>
<circle cx="150" cy="75" r="20" fill="teal"></circle>
</svg>
D3 Solution (way better): simply change the radius of the circle:
var circle = d3.select("circle");
circle.on('mouseover', function(d) {
d3.select(this).attr('r', 40);
})
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg>
<circle cx="150" cy="75" r="20" fill="teal"></circle>
</svg>