I'm trying to scale a slice of this Victory Pie chart on mouse hover but I'm having a difficult time getting it to render correctly. Has anyone had any luck with this? I've tried adding things like transform: scale(1.2) to the mutation style but it moves the slice rather than scales (I believe this is because scale scales based on the point of (0,0)). I've also tried playing around with translate or matrix but I can't get it to work correctly. Here's my code:
<div style={{ width: '150px' }}>
<VictoryPie
data={[
{ x: 'Cats', y: 35, label: 'Cats \n 35%' },
{ x: 'Dogs', y: 40, label: 'Dogs \n 40%' },
{ x: 'Birds', y: 55, label: 'Birds \n 55%' }
]}
labelComponent={
<VictoryTooltip
cornerRadius={10}
pointerWidth={30}
pointerLength={20}
flyoutPadding={{ top: 10, bottom: 10, left: 25, right: 25 }}
style={{ fontSize: '36px', fill: '#FFF' }}
flyoutStyle={{ fill: '#414B5F' }}
orientation="right"
/>
}
colorScale={['tomato', 'orange', 'gold', 'cyan', 'navy']}
innerRadius={100}
events={[
{
target: 'data',
eventHandlers: {
onMouseOver: () => {
return [
{
target: 'data',
mutation: () => ({ style: { fill: 'red', width: 30 } })
},
{
target: 'labels',
mutation: () => ({ active: true })
}
]
},
onMouseOut: () => {
return [
{
target: 'data',
mutation: () => {}
},
{
target: 'labels',
mutation: () => ({ active: false })
}
]
}
}
}
]}
/>
</div>
I added a simple mutation that changes the slice to red on hover and that works great. I'm just having a difficult time finding the best way to make the slice scale up slightly without causing problems.
Thanks in advance
You can use a custom component to render slices
const CustomSlice = (props) => {
const [scale, setScale] = useState(1);
// modified transformation from here
// https://github.com/FormidableLabs/victory/blob/844109cfe4e40b23a4dcb565e551a5a98015d0c0/packages/victory-pie/src/slice.js#L74
const transform = `translate(${props.origin.x}, ${props.origin.y}) scale(${scale})`;
return (
<Slice
{...props}
style={{ ...props.style }}
events={{
onMouseOver: (e) => {
if (props.events.onMouseOver) {
props.events.onMouseOver(e);
}
setScale((c) => c * 1.2);
},
onMouseOut: (e) => {
if (props.events.onMouseOut) {
props.events.onMouseOut(e);
}
setScale(1);
}
}}
transform={transform}
/>
);
};
<div style={{ width: "150px" }}>
<VictoryPie
dataComponent={<CustomSlice />}
data={[
{ x: "Cats", y: 35, label: "Cats \n 35%" },
{ x: "Dogs", y: 40, label: "Dogs \n 40%" },
{ x: "Birds", y: 55, label: "Birds \n 55%" }
]}
labelComponent={
<VictoryTooltip
cornerRadius={10}
pointerWidth={30}
pointerLength={20}
flyoutPadding={{ top: 10, bottom: 10, left: 25, right: 25 }}
style={{ fontSize: "36px", fill: "#FFF" }}
flyoutStyle={{ fill: "#414B5F" }}
orientation="right"
/>
}
colorScale={["tomato", "orange", "gold", "cyan", "navy"]}
innerRadius={100}
events={[
{
target: "data",
eventHandlers: {
onMouseOver: (e) => {
return [
{
target: "data",
mutation: () => ({
style: { fill: "red", width: 30 }
})
},
{
target: "labels",
mutation: () => ({ active: true })
}
];
},
onMouseOut: () => {
return [
{
target: "data",
mutation: () => {}
},
{
target: "labels",
mutation: () => ({ active: false })
}
];
}
}
}
]}
/>
</div>