Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scale rect element from center

I'm currently using rect elements as points on a map and I want to scale their size but the D3 animation always animates the change in width/height starting from the top left corner. Is there a way to scale a rect from the center point so it expands in all directions when animating?

This is the simple D3 code. It is animating the change to width, height rx and ry.

.selectAll(".anchor")
    .transition()
    .duration(800)
    .delay(function (d, i) {
        return i * 50;
    })
    .attr("fill", _graphics.colors.red)
    .attr("stroke", _graphics.colors.charcoal)
    .attr("width", 10)
    .attr("rx", function (d) {
        return 10 / 2
    })
    .attr("ry", function (d) {
        return 10 / 2
    });
like image 673
PFlans Avatar asked Mar 23 '26 09:03

PFlans


1 Answers

You could play with all parameters (x, y, width, height). If the width is supposed to increase by 100, then decreasing x by 100/2=50 will make the rect appear to grow from its center:

var svg = d3.select("body").append("svg")
  .attr("width", 700)
  .attr("height", 400);

var data = [
  { x: 50, y: 50, width: 25, height: 50 },
  { x: 180, y: 65, width: 40, height: 20 }
];

svg.selectAll("rect")
  .data(data)
  .enter()
  .append("rect")
  .attr("x", function(d) { return d.x; })
  .attr("y", function(d) { return d.y; })
  .attr("width", function(d) { return d.width; })
  .attr("height", function(d) { return d.height; })
  .style("fill", "blue")
  .transition()
    .duration(3000)
    .attr("x", function(d) { return d.x - 25; })
    .attr("y", function(d) { return d.y - 50; })
    .attr("width", function(d) { return d.width + 50; })
    .attr("height", function(d) { return d.height + 100; });
<script src="https://d3js.org/d3.v5.js"></script>
like image 95
Xavier Guihot Avatar answered Mar 26 '26 01:03

Xavier Guihot