React-vis: Bar Series onValueMouseOut not triggering

Created on 25 Jul 2017  路  13Comments  路  Source: uber/react-vis

I am using vertical clustered bar chart. Rest of the functionality works well, but onValueMouseOut does not trigger when I leave a particular bar.
Here is my snippet from React render:

{
          data.map((item, i) => {
            if (!item.disabled) {
              return (
                <BarSeries
                  key={i}
                  color={item.color}
                  data={item.datum}
                  title={item.title}
                  onValueMouseOver={(datapoint, event) => getHintData(datapoint, event, item.title)}
                  # **onValueMouseOut**={(datapoint, event) => this._removeHintData(datapoint, event)}
                  onValueClick={(datapoint, event, j) => handleBarClick(datapoint, event, j, item.datum)}
                />
              );
            }
            return null;
          })
        }
bug

Most helpful comment

My workaround was to have animation in state, and set it to true by default, set it to false on onValueMouseOver, and set it back to true on onValueMouseOut.

It will still be nice if this gets fixed since I don't like having another state in my component.

<VerticalBarSeries
    data={data}
    onValueMouseOver={() => { this.setState({ animation: true }) }}
    onValueMouseOut={() => { this.setState({ animation: false }) }}
    animation={this.state.animation}
/>

All 13 comments

Hey @ArbaazAnDossani

I did a cursory check on some of the examples and they appear to have their onValueMouseOver/onValueMouseOut/onValueClick working in good order. is there a chance that you animation on? It is a known issue (#381) that animation causes problems here. Additionally you shouldn't be using BarSeries (bar-series) directly, as that will most likely cause problems?

Hey @mcnuttandrew

I am using Vertical Stacked Bar Graph sample, I removed the animation prop and now onMouseOut is working fine.
Can you please explain how are these two issues related and what is the solution when I need both animation as well as onMouseout function?

Thanks!

@ArbaazAnDossani

This problem is caused by the relationship between our Animation component and listeners. As best I can tell the problems arise from higher order components causing problems. In #554 I tried out a different strategey for getting around this, that boils down to adding invisible two copies of the series of concern, like so

<XYPlot>
<VerticalBarSeries animation data={mydata}>
<VerticalBarSeries data={mydata} opacity={0} onMouseOut={() => {...}}>
</XYPlot>

So that the invisible series handles all of the mouse events and the visible series is animated. This solution is not perfectly ideal, however it is a perfectly valid workaround. If we can't come up with a better solution to this problem, this solution will be integrated into the main library.

@jckr It looks like this was closed, referencing #711, which was closed referencing this bug. Can we re-open one of them? And even earlier bug was raised (#381) which was closed as "similar to [this bug]"

I can confirm I've just encountered this bug with <MarkSeries/>. It works fine after removing the animation prop from the <XYPlot/>.

Re-opened. The still best strategy I've thought of is the one deployed in arc series, which puts a secondary ghost series of the top of the animated one for control of the event hooks. I don't really think there will be a better solution, unless there happens to be some way to untangle the way that the animation component works.

(PRS and ideas welcome)

I agree with @mcnuttandrew as a temporary solution for the current issue.
But populating DOM twice is never a great idea.

same problem here!

I got the same problem too.

The workaround does not work so well to be honest.

I think it worths raise a ticket and fix this in some PR.

Cheers

@ArbaazAnDossani

This problem is caused by the relationship between our Animation component and listeners. As best I can tell the problems arise from higher order components causing problems. In #554 I tried out a different strategey for getting around this, that boils down to adding invisible two copies of the series of concern, like so

<XYPlot>
<VerticalBarSeries animation data={mydata}>
<VerticalBarSeries data={mydata} opacity={0} onMouseOut={() => {...}}>
</XYPlot>

So that the invisible series handles all of the mouse events and the visible series is animated. This solution is not perfectly ideal, however it is a perfectly valid workaround. If we can't come up with a better solution to this problem, this solution will be integrated into the main library.

My workaround was to have animation in state, and set it to true by default, set it to false on onValueMouseOver, and set it back to true on onValueMouseOut.

It will still be nice if this gets fixed since I don't like having another state in my component.

<VerticalBarSeries
    data={data}
    onValueMouseOver={() => { this.setState({ animation: true }) }}
    onValueMouseOut={() => { this.setState({ animation: false }) }}
    animation={this.state.animation}
/>

@mizozobu , your solution works wonderfully! For anyone else -- you can also assign your animation options, e.g. { damping: 10, stiffness: 200} to your animation variable in state.

@mizozobu, your solution works great. wanted to note that the same issue with annimation exists for higher order components that make width/height flexible. One may need to remove the HOC to use this solution.

Yes it's not working with HOC makeFlexible but I fix it by using XYPlot as a child component of ReactResizeDetector
<ReactResizeDetector handleWidth={true} onResize={this.onResize}> {(width) => (<XYPlot width={width} height={this.props.height} xType="ordinal" animation={false} >

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Tom-Gorup picture Tom-Gorup  路  3Comments

jonnydodad picture jonnydodad  路  4Comments

cang-afero picture cang-afero  路  4Comments

samhogg picture samhogg  路  4Comments

martoncsikos picture martoncsikos  路  4Comments