JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://d3js.org/d3.v4.min.js"></script>
<div id="content"></div>
<button id="move">Move</button>
<button id="reset">Reset</button>
JavaScript
let svg = d3.select('#content')
.append('svg')
.attr('width', 500)
.attr('height', 500);
let data = [
{x: 100, y: 100, rotation: 45},
];
appendRect('node', 'red', rotateFirst);
appendRect('node2', 'blue', translateFirst);
function appendRect(cssClass, color, transformFunction) {
svg.selectAll(`g.${cssClass}`)
.data(data)
.enter()
.append('g')
.attr('class', cssClass)
.attr('transform', d => transformFunction(d))
.append('rect')
.attr('style', 'fill:' + color)
.attr('width', 30)
.attr('height', 10);
}
function getRotation(d) {
let width = 30;
let height = 10;
let center = {
x: d.x + width / 2,
y: d.y + height / 2
};
return `rotate(${d.rotation} ${center.x} ${center.y})`;
}
function rotateFirst(d) {
return `${getRotation(d)} translate(${d.x}, ${d.y})`;
}
function translateFirst(d) {
return `translate(${d.x}, ${d.y}) ${getRotation(d)}`;
}
function performMove(selection, data, transformFunction) {
let transition = d3.transition('move').duration(1000);
selection.data(data)
.transition(transition)
.attr('transform', (d) => transformFunction(d));
}
d3.select('#move')
.on('click', () => {
console.log('move');
let newData = data.map(item => Object.assign({}, item));
newData[0].x += 30;
newData[0].y += 20;
newData[0].rotation += 45;
console.log(newData);
performMove(svg.selectAll('g.node'), newData, rotateFirst);
performMove(svg.selectAll('g.node2'), newData, translateFirst);
});
d3.select('#reset')
.on('click', () => {
console.log('reset');
let newData = data.map(item => Object.assign({}, item));
performMove(svg.selectAll('g.node'), newData, rotateFirst);
performMove(svg.selectAll('g.node2'), newData, translateFirst);
});