React Recharts -> 散点图中 LabelList 的工具提示问题

React Recharts -> Tooltip problem with LabelList in Scatter chart

一段时间以来,我们遇到了显示在散点图元素上的 LabelList 问题。如果用户将鼠标悬停在它们上面,则不会显示工具提示。

代码:

const {ScatterChart, Scatter, XAxis, YAxis, CartesianGrid, LabelList, Tooltip, Legend} = Recharts;
const data = [{x: 100, y: 200, z: 200}, {x: 120, y: 100, z: 260},
                  {x: 170, y: 300, z: 400}, {x: 140, y: 250, z: 280},
                  {x: 150, y: 400, z: 500}, {x: 110, y: 280, z: 200}]

const SimpleScatterChart = React.createClass({
    render () {
    return (
        <ScatterChart width={400} height={400} margin={{top: 20, right: 20, bottom: 20, left: 20}}>
        <XAxis type="number" dataKey={'x'} name='stature' unit='cm'/>
        <YAxis type="number" dataKey={'y'} name='weight' unit='kg'/>
        <CartesianGrid />
        <Tooltip cursor={{strokeDasharray: '3 3'}}/>
        <Legend onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} />
        <Scatter name='A school' data={data} fill='#8884d8'>
          <LabelList dataKey="x" />
        </Scatter>
      </ScatterChart>
    );
  }
})

ReactDOM.render(
  <SimpleScatterChart />,
  document.getElementById('container')
);

示例:https://jsfiddle.net/alidingling/gvsspn0h/

删除 LabelList 后,它工作正常:

const {ScatterChart, Scatter, XAxis, YAxis, CartesianGrid, LabelList, Tooltip, Legend} = Recharts;
const data = [{x: 100, y: 200, z: 200}, {x: 120, y: 100, z: 260},
                  {x: 170, y: 300, z: 400}, {x: 140, y: 250, z: 280},
                  {x: 150, y: 400, z: 500}, {x: 110, y: 280, z: 200}]

const SimpleScatterChart = React.createClass({
    render () {
    return (
        <ScatterChart width={400} height={400} margin={{top: 20, right: 20, bottom: 20, left: 20}}>
        <XAxis type="number" dataKey={'x'} name='stature' unit='cm'/>
        <YAxis type="number" dataKey={'y'} name='weight' unit='kg'/>
        <CartesianGrid />
        <Tooltip cursor={{strokeDasharray: '3 3'}}/>
        <Legend onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} />
        <Scatter name='A school' data={data} fill='#8884d8'>
        </Scatter>
      </ScatterChart>
    );
  }
})

ReactDOM.render(
  <SimpleScatterChart />,
  document.getElementById('container')
);

示例:https://jsfiddle.net/gt0uy92a/2/

问题是,我们需要在第一个示例中显示 LabelList,我们无法更改位置,但 Tooltip 必须正常工作。

解决方案并不那么简单,有点棘手,但仍然合乎逻辑。如果我们不能用 SVG 渲染元素的方式做任何事情,不能使用 z-index,我们仍然可以设置它们的不透明度。

const CustomizedCircle = props => {
    const {
        cx, cy, fill, size, z,
    } = props;
    const radius = size / 70;
    const value = z;

    return (
        <svg width={radius} height={radius} style={{overflow: 'visible'}}>
            <text style={{fontWeight: FONT_WEIGHT, fontSize: FONT_SIZE}} x={cx} y={cy + 5} textAnchor="middle">{value}</text>
            <circle style={{opacity: OPACITY}} cx={cx} cy={cy} r={radius} fill={fill} />
        </svg>
    );
};

所以我们首先渲染文本,然后渲染圆圈,为了看到圆圈下方的文本,我们正在为圆圈设置某种不透明度。

<LabelList 
  dataKey="x" 
  style={{pointerEvents: 'none'}}
/>

将适用于 you.you 也可以将 onMouseEnter 事件绑定到 LabelList 组件。