You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi, I am newish to d3, so maybe there is a way to do this that is easier than what I came up with, so if so please let me know. I couldn't find anything helpful.
When you make a pie chart, I think you have to do something like this at the start:
where 'info' is in the format produced by the function returned by d3.pie().
Apparently data() is fairly flexible, but I ended up using this format because I was not sure
what it was expecting in order to properly construct the pie segments. Maybe just something with
startAngle and endAngle properties??? I don't like using an undocumented interface there because it
might change out from under me.
Then I wanted to move the slices with a transition. This was also harder than it should have been,
since apparently there was no way to access the "from" startAngle and endAngle from within the interpolator.
So I had to do something like this:
This discussion was converted from issue #3835 on April 07, 2024 02:57.
Heading
Bold
Italic
Quote
Code
Link
Numbered list
Unordered list
Task list
Attach files
Mention
Reference
Menu
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Hi, I am newish to d3, so maybe there is a way to do this that is easier than what I came up with, so if so please let me know. I couldn't find anything helpful.
When you make a pie chart, I think you have to do something like this at the start:
const g = d3.select(svg)
.attr('width', width)
.attr('height', height)
.append("g")
.attr("id",chartID)
.attr("transform",
translate(${x}, ${y})
);const pie = d3.pie()
.sort(null)
.value(d => d.value);
const arc = d3.arc()
.outerRadius(outerRadius)
.innerRadius(innerRadius);
const slices = g.selectAll('.slice')
.data(pie(data))
.enter()
.append("g")
.attr("class", 'slice');
That is all well and good if your slices are contiguous, but what if they are not? I did it this way:
Everything the same up to the slices definition except you can leave out the pie definition. Then
const slices = g.selectAll('.slice')
.data(info)
.enter()
.append("g")
.attr("class", 'slice');
where 'info' is in the format produced by the function returned by d3.pie().
Apparently data() is fairly flexible, but I ended up using this format because I was not sure
what it was expecting in order to properly construct the pie segments. Maybe just something with
startAngle and endAngle properties??? I don't like using an undocumented interface there because it
might change out from under me.
Then I wanted to move the slices with a transition. This was also harder than it should have been,
since apparently there was no way to access the "from" startAngle and endAngle from within the interpolator.
So I had to do something like this:
slices
.select("path")
.transition()
.duration(1000)
.attrTween("d", function(d) {
const interpolateStartAngle = d3.interpolate(getStartAngle(d.data.label), d.startAngle);
const interpolateEndAngle = d3.interpolate(getEndAngle(d.data.label), d.endAngle);
this._current = d;
return t => {
updatedArc
.startAngle(x=interpolateStartAngle(t))
.endAngle(interpolateEndAngle(t));
return updatedArc(d);
};
});
with these functions defined:
function getStartAngle(name) {
let d = previousDonutInfoGlobal.find(obj => name.indexOf(obj.data.label)===0);
return d.startAngle;
}
function getEndAngle(name) {
let d = previousDonutInfoGlobal.find(obj => name.indexOf(obj.data.label)===0);
return d.endAngle;
}
First off, is there a better/easier way that would work? And if not, couldn't you make the start info available somehow to the interpolator?
Beta Was this translation helpful? Give feedback.
All reactions