plouc / nivo

nivo provides a rich set of dataviz components, built on top of the awesome d3 and React libraries
https://nivo.rocks
MIT License
13.11k stars 1.03k forks source link

First render of bar chart is in animated state even if animate={false}, resulting in empty chart when no re-render available #2127

Open pstaubs opened 2 years ago

pstaubs commented 2 years ago

Describe/explain the bug

I am trying to render some (plain, non-responsive) nivo charts sever-side on a rails server using react_component with prerender:true (to support wkhtmltopdf). This works fine for most charts I have come across, except for bar charts.

<Bar
      animate={false}
      isInteractive={false}
      {...CommonChartProperties(props)}
/>

For some reason the prerendered bar chart SVG contains bars with width="0" (specifically the SVG RECT element) and labels with fill-opacity="0" (specifically the SVG TEXT element), resulting in a chart that looks empty, even if the correct svg elements are present and properly positioned.

Here's an example bar generated by the above component if I pre-render it and look at the raw HTML

<g transform="translate(794, 201)">
    <rect width="0" height="49" rx="0" ry="0" fill="rgba(23, 190, 207, 1)" stroke-width="0" stroke="rgba(13, 107, 117, 1)" focusable="false"></rect>
    <text x="13" y="24.5" text-anchor="middle" dominant-baseline="central" fill-opacity="0" style="font-family:sans-serif;font-size:11px;fill:rgba(13, 107, 117, 1);pointer-events:none">48</text>
</g>

To Reproduce

Examine the first render of any bar chart, for example, e.g. if prerendering on a rails server

<% puts react_component("path/to/component",
    props={...},
    html_options={prerender: true}
  )%>

Expected behavior

I expect animate={false} means that the component renders for the first time without any unresolved animations.

Additional context

In a browser, the pre-rendered component appears to be re-rendered (imperceptibly instantly) with the correct fill-opacity and bar width properties, but this is not the case if I am printing to wkhtmltopdf. Does animate={false} really turn off animations on a technical level, or does it just shorten the animation to be near instant, so it doesn't look animated, but in reality the initial chart is rendered in a pre-animated state? It's clear that the bar width is already known since the bars are correctly positioned. It's only stylistic properties awaiting update.

My current workaround is to manually override the SVG's style, but this is a pain especially if the bar width is not fixed.

<style>
  svg text {
    fill-opacity: 1;
  }
  svg rect {
    width: 28px;
  }
</style>
arackaf commented 1 year ago

This appears to be a valid issue. Can we re-open?

Huararanga commented 1 year ago

Same for me. I reproduced it by using @nivo/express and touching nivo/samples/bar.svg.

anthony-insummary commented 1 month ago

Is there any update on this?

We have a very large data set and animate set to false, but when we switch data sets, it is still animating in, which is causing UI freeze and choppy display until the animation is finished, at which point everything works fine.