I had a similar issue. But I was using D3 to position my elements, and wanted the transform and transition to be handled by CSS. This was my original code, which I got working in Chrome 65:
//...
this.layerGroups.selectAll('.dot')
.data(data)
.enter()
.append('circle')
.attr('transform-origin', (d,i)=> `${valueScale(d.value) * Math.sin( sliceSize * i)}
${valueScale(d.value) * Math.cos( sliceSize * i + Math.PI)}`)
//... etc (set the cx, cy and r below) ...
This allowed me to set the cx
,cy
, and transform-origin
values in javascript using the same data.
BUT this didn't work in Firefox! What I had to do was wrap the circle
in the g
tag and translate
it using the same positioning formula from above. I then appended the circle
in the g
tag, and set its cx
and cy
values to 0
. From there, transform: scale(2)
would scale from the center as expected. The final code looked like this.
this.layerGroups.selectAll('.dot')
.data(data)
.enter()
.append('g')
.attrs({
class: d => `dot ${d.metric}`,
transform: (d,i) => `translate(${valueScale(d.value) * Math.sin( sliceSize * i)} ${valueScale(d.value) * Math.cos( sliceSize * i + Math.PI)})`
})
.append('circle')
.attrs({
r: this.opts.dotRadius,
cx: 0,
cy: 0,
})
After making this change, I changed my CSS to target the circle
instead of the .dot
, to add the transform: scale(2)
. I didn't even need use transform-origin
.
NOTES:
I am using d3-selection-multi
in the second example. This allows me to pass an object to .attrs
instead of repeating .attr
for every attribute.
When using a string template literal, be aware of line-breaks as illustrated in the first example. This will include a newline in the output and may break your code.