Nivo: Charts are not responsive when inside a Flex Row

Created on 4 Jan 2019  路  11Comments  路  Source: plouc/nivo

Reproducible demo here: https://codesandbox.io/s/lp16vvz6n7

As you can see, the top chart here (in the flex row) is not responsive.

Happy to help contribute if no one on the core team immediately knows. It might have something to do with react-measure that's used in @nivo/core for the <ResponsiveWrapper> component.

bug

Most helpful comment

I solved this issue with the AutoSizer HOC.

import { AutoSizer } from 'react-virtualized'
<AutoSizer>
    {({ height, width }) => (
        <Pie
            height={height}
            width={width}
            ...
         />
    )}
</AutoSizer>

Because of the known issues like "infinitely growing diagrams" I almost always use the AutoSizer wrapper in favour of the components.

All 11 comments

I solved this issue with the AutoSizer HOC.

import { AutoSizer } from 'react-virtualized'
<AutoSizer>
    {({ height, width }) => (
        <Pie
            height={height}
            width={width}
            ...
         />
    )}
</AutoSizer>

Because of the known issues like "infinitely growing diagrams" I almost always use the AutoSizer wrapper in favour of the components.

I ran into this issue too. I ended up using Recharts instead because I was on a deadline and I needed something that worked. It's unfortunate, because the Nivo charts certainly look better.

@ja0nz Wow this works great. I've been using React Virtualized for a while now but I never would have thought to use its auto-sizer. Thanks

I was having the same issue when using the <ResponsiveLine> component inside a flex container. Strangely, when increasing the viewport width the chart would resize perfectly, but when decreasing it the chart would stay as it was as its widest point. Refreshing the page would fix everything again.

I've since implemented @ja0nz solution (as well as changing from <ResponsiveLine> to <Line>) and can confirm that it works a treat.

react-virtualized is a great library but quite heavy.
There is a separate package for auto sizing called react-virtualized-auto-sizer.

The following code is a light-weight version of @ja0nz's solution.

import AutoSizer from "react-virtualized-auto-sizer";

Minor addition to @ja0nz's solution. I think AutoSizer width should be 100% to keep the tooltips inbound.
import AutoSizer from 'react-virtualized/dist/commonjs/AutoSizer'; <AutoSizer style={{ width:'100%' }}> {({ height, width }) => ( <Pie height={height} width={width} ... /> )} </AutoSizer>

Like @tanmaybhatt said, the tooltip (both anchor and tooltip width) has problems when using @ja0nz 's solution.
To sum it up, the Autosizer container for the chart has 0 width, which causes the tooltip calculation to incorrectly detect a width of 0 all the time here https://github.com/plouc/nivo/blob/f2816f44f2fad60025d57bca6721c3c1cec8f14b/packages/tooltip/src/hooks.js#L35
which then decides to always use the same anchor direction.

My fix for it was something like this:
(do take into account that my chart has a fixed height)

    <AutoSizer disableHeight>
      {({width}) => (
        <div style={{width: width + 'px'}}>
          <Line
            height={500}
            width={width}
           //...
          />
        </div>
    </AutoSizer>

Reproducible demo here: https://codesandbox.io/s/lp16vvz6n7

Got similar problem and tried to tinker with your sandbox.
I solved this by adding min-width: 0

.flex-1 {
  flex: 1 1 0%;
  min-width: 0;
}

@ronsigter, like this:

<div style={{
     minWidth: 0, 
     height: 400}}>
     <WaffleChart data={data} />
</div>

?

Didn't work here

Any update on this bug? I am seeing the same behavior in both flexbox and grid. react-virtualized doesn't feel like a great work-around for me.

I tried to use Autosizer but then any buttons one below the chart component are unclickable. Any thoughts?

Edit: I know the problem now but not the solution. The <Autosizer> component is in a <div> with a button. The Parent <div> height is 400px. The button is 20px. The <Autosizer> assumes the parent's full height of 400 instead of 380 px. I'm not familiar with Autosizer, so is this the expected behavior?

Was this page helpful?
0 / 5 - 0 ratings