我有一个用
VictoryPie
实现的饼图。我想当鼠标悬停在每个切片上时显示一个标签。
我在
MouseFollowToolTip
组件中放置了一条打印语句。当页面加载时,语句已打印五次,这是有道理的,因为有五个切片。然后,当我在饼图周围移动鼠标时,它会继续打印。
但是,它在任何时候都不会显示与切片关联的标签。
import React from 'react';
import Grid from '$components/grid';
import { VictoryLegend, VictoryPie, VictoryTooltip, VictoryLabel, Selection } from 'victory';
const creditScoreMakeup = [
{
x: 'Payment history',
y: 35,
label:
'The best way for you to improve \nyour credit score is to \nfocus on making payments on time.',
},
{
x: 'Credit utilization',
y: 30,
label:
'You should try to carry little \nto no balance on your credit card \nto lower your credit utilization and \nimprove your credit score.',
},
{
x: 'Length of history',
y: 15,
label:
'A longer credit history provides lenders with more information about how you use credit which helps them predict how you will behave financially long-term.',
},
{
x: 'Credit diversity',
y: 10,
label:
'Having a mix of loans and credit cards \ngives lenders the impression that you can \nhandle various forms of credit responsibly.',
},
{
x: 'Credit inquiries',
y: 10,
label:
'Having many inquiries in a \nshort period of time in your \ncredit history suggests that you \nare in financial trouble and need \na significant amount of money.',
},
];
class MouseFollowToolTip extends React.Component {
static defaultEvents = [
{
target: "data",
eventHandlers: {
onMouseOver: evt => {
const { x, y } = Selection.getSVGEventCoordinates(evt);
return {
mutation: () => ({
target: "labels",
x,
y,
active: true
})
};
},
onMouseMove: evt => {
const { x, y } = Selection.getSVGEventCoordinates(evt);
return {
mutation: () => ({
target: "labels",
x,
y,
active: true
})
};
},
onMouseOut: () => {
return { target: "labels", mutation: () => ({ active: false }) };
}
}
}
];
render() {
console.log("called")
return <VictoryTooltip {...this.props} pointerLength={0} renderInPortal={false} />;
}
}
class CreditScore extends React.Component {
render() {
return (
<svg width={1000} height={1000}>
<VictoryLegend
standalone={false}
renderInPortal={false}
colorScale="green"
legendWidth={50}
x={20}
y={40}
gutter={20}
title="Legend"
centerTitle
style={{ border: { stroke: 'black' } }}
data= {creditScoreMakeup.map((a, ind) => {
return { name: a.x };
})}
/>
<VictoryPie
colorScale="green"
data={creditScoreMakeup}
standalone={false}
renderInPortal={false}
width={800}
height={400}
padding-right={100}
style={{ parent: { maxWidth: '50%' } }}
//labels={d => `${d.label}%`}
labelComponent= {<MouseFollowToolTip/>}
/>
</svg>
);
}
}
我在这里做了一个沙箱
这是一个在 CreditScore 组件内跟踪鼠标移动的解决方案:
class MouseFollowTooltip extends VictoryTooltip {
render() {
return (
<VictoryTooltip
{...this.props}
pointerLength={16}
renderInPortal={false}
/>
);
}
}
class CreditScore extends React.Component {
state = {
x: 0,
y: 0
};
updateCoords = e => {
this.setState({ x: e.clientX, y: e.clientY });
};
render() {
return (
<svg onMouseMove={this.updateCoords} width={1000} height={1000}>
<VictoryLegend
standalone={false}
renderInPortal={false}
colorScale="green"
legendWidth={50}
x={20}
y={40}
gutter={20}
title="Legend"
centerTitle
style={{ border: { stroke: "black" } }}
data={creditScoreMakeup.map((a, ind) => {
return { name: a.x };
})}
/>
<VictoryPie
colorScale="green"
data={creditScoreMakeup}
standalone={false}
renderInPortal={false}
width={800}
height={400}
padding-right={100}
style={{ parent: { maxWidth: "50%" } }}
labels={d => `${d.label}%`}
labelComponent={
<MouseFollowTooltip x={this.state.x} y={this.state.y} />
}
/>
</svg>
);
}
}