Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combining translate and rotate with D3

Tags:

d3.js

Quite possibly this repeats some of this SO question, but the code is overly-complicated and the OP hasn't added solution code. And this related question is no longer replicable.

I'm trying to figure out how to combine rotations and translations in the right order. It's possible to rotate around the origin as in this example. But when we follow this with a translation the original rotation is undone.

Is it possible to structure this for correct sequential application?

jsfidle code:

HTML:

<script src="http://d3.geotheory.co.uk/d3-transform.js"></script>

SVG:

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

//Draw the Rectangle
var rect = svg.append("rect")
    .attr("x", 0).attr("y", 0)
    .attr("width", 50).attr("height", 100)
    .style("fill", "purple");

var rotate = d3.svg.transform().rotate(-45);
var translate = d3.svg.transform().translate(200, 100);

rect.attr('transform', rotate);

var rect2 = rect.attr('transform', rotate);
rect2.attr('transform', translate);
like image 902
geotheory Avatar asked Nov 17 '13 12:11

geotheory


2 Answers

If you're looking to do this in D3 version 4.x+ you can do it like so:

.attr('transform', 'translate(200,100)rotate(-45)')

https://bl.ocks.org/mbostock/1345853

like image 182
Henry Zhu Avatar answered Oct 29 '22 07:10

Henry Zhu


You're creating two different transformations. Assigning one doesn't add to the other. That is, in doing

rect2.attr('transform', translate);

you're undoing the first one, as it is overwritten.

To have both, add them both to one transition, e.g.

var rotateTranslate = d3.svg.transform().rotate(-45).translate(200, 100);
rect2.attr('transform', rotateTranslate);

To do this dynamically, you'll need to do something like this.

.attr("transform", function() {
    return d3.svg.transform()
        .translate(200, 100)
        .rotate(-45)
        .translate(-d3.select(this).attr("width")/2, -d3.select(this).attr("height")/2)();
}

Complete jsfiddle here.

like image 29
Lars Kotthoff Avatar answered Oct 29 '22 05:10

Lars Kotthoff