简体   繁体   English

如何在React d3 v4条形图中添加工具提示

[英]how to add tooltip in react d3 v4 bar chart

I have to add the tooltip on react d3 v4 bar chart on mouseover.I have tried customized function mentioned below, 我必须在鼠标悬停时在react d3 v4条形图上添加工具提示。我尝试了以下提及的自定义功能,

onMouseOverHandler(d){
   var tooltip = d3Select("body").append("div")   
    .attr("class", "tooltip")               
    .style("opacity", 0);

    tooltip.transition().duration(200).style("opacity", .9);      
    tooltip.html(d)  
    .style("left", d3Select(this).attr("cx") + "px")     
    .style("top", d3Select(this).attr("cy") + "px");

but it's not working. 但它不起作用。 someone can you help me for this one. 有人可以帮我吗?

Thanks, Arun S 谢谢,阿伦·S

I added a tooltip to the example you linked to in your comment to this fork of the original GitHub repository . 我在您对原始GitHub存储库的此fork的注释中链接的示例中添加了工具提示。

I created a Tooltip component. 我创建了一个Tooltip组件。 Of course, keep in mind that this isn't necessarily the "right" or only way to add a tooltip to a React application that uses D3. 当然,请记住,这不一定是向使用D3的React应用程序添加工具提示的“正确”方法或唯一方法。

I went through the following steps: 我经历了以下步骤:

  1. Created state in the Chart component that tracks the data for which bar, if any, is currently hovered Chart组件中的创建状态,该状态跟踪数据当前悬停在其上的条(如果有)

  2. Created onMouseOver and onMouseOut events in the Bars component to determine which bar has just been hovered or left and pass that up to the Chart component to set the new state Bars组件中创建onMouseOveronMouseOut事件,以确定刚刚悬停或离开的柱,并将其向上传递到Chart组件以设置新状态

  3. Passed the state from the Chart component back down to a Tooltip component I created 将状态从“ Chart组件传递回我创建的“ Tooltip组件

The Tooltip component looks like this: Tooltip组件如下所示:

export default ({hoveredBar, scales}) => {
  const { xScale, yScale } = scales
  const styles = {
    left: `${xScale(hoveredBar.title) - 30}px`,
    top: `${yScale(hoveredBar.value)}px`
  }

  return (
    <div className="Tooltip" style={styles}>
      <table>
        <thead>
          <tr>
            <th colSpan="2">{hoveredBar.title}</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td colSpan="1">Bodies</td>
            <td colSpan="1">{hoveredBar.value}</td>
          </tr>
          <tr>
            <td colSpan="1">Year</td>
            <td colSpan="1">{hoveredBar.year}</td>
          </tr>
        </tbody>
      </table>
    </div>
  )
}

I used it in the Chart component, and tracked the currently hovered bar as state: 我在“ Chart组件中使用了它,并跟踪了当前悬停的柱状图的状态:

class Chart extends Component {
  constructor(props) {
    super(props)
    this.xScale = scaleBand()
    this.yScale = scaleLinear()

    this.state = {
      hoveredBar: null
    }
  }

  render() {
    const margins = { top: 50, right: 20, bottom: 100, left: 60 }
    const svgDimensions = {
      width: Math.max(this.props.parentWidth, 300),
      height: 500
    }

    const maxValue = Math.max(...data.map(d => d.value))

    const xScale = this.xScale
      .padding(0.5)
      .domain(data.map(d => d.title))
      .range([margins.left, svgDimensions.width - margins.right])

    const yScale = this.yScale
      .domain([0, maxValue])
      .range([svgDimensions.height - margins.bottom, margins.top])

    return (
      <div className="Chart">
        <svg width={svgDimensions.width} height={svgDimensions.height}>
          <Axes
            scales={{ xScale, yScale }}
            margins={margins}
            svgDimensions={svgDimensions}
          />
          <Bars
            scales={{ xScale, yScale }}
            margins={margins}
            data={data}
            maxValue={maxValue}
            svgDimensions={svgDimensions}
            onMouseOverCallback={datum => this.setState({hoveredBar: datum})}
            onMouseOutCallback={datum => this.setState({hoveredBar: null})}
          />
        </svg>
        { this.state.hoveredBar ?
          <Tooltip
            hoveredBar={this.state.hoveredBar}
            scales={{ xScale, yScale }}
          /> :
          null
        }
      </div>
    )
  }
}

And I set the onMouseOver and onMouseOut events in the Bars component: 然后在Bars组件中设置onMouseOveronMouseOut事件:

export default class Bars extends Component {
  constructor(props) {
    super(props)

    this.colorScale = scaleLinear()
      .domain([0, this.props.maxValue])
      .range(['#F3E5F5', '#7B1FA2'])
      .interpolate(interpolateLab)
  }

  render() {
    const { scales, margins, data, svgDimensions } = this.props
    const { xScale, yScale } = scales
    const { height } = svgDimensions

    const bars = (
      data.map(datum =>
        <rect
          key={datum.title}
          x={xScale(datum.title)}
          y={yScale(datum.value)}
          height={height - margins.bottom - scales.yScale(datum.value)}
          width={xScale.bandwidth()}
          fill={this.colorScale(datum.value)}
          onMouseOver={() => this.props.onMouseOverCallback(datum)}
          onMouseOut={() => this.props.onMouseOutCallback(null)}
        />,
      )
    )

    return (
      <g>{bars}</g>
    )
  }
}

Here I have described a solution to the same problem. 在这里,我描述了解决同一问题的方法。

https://stackoverflow.com/a/56674517/2903711 https://stackoverflow.com/a/56674517/2903711

The result looked this 结果看起来像这样

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM