rakannimer / react-google-charts

A thin, typed, React wrapper over Google Charts Visualization and Charts API.
https://react-google-charts.com/
MIT License
1.59k stars 345 forks source link

[Bug]: loadingStatus state for react-google-charts is set as loading permanantly #710

Open akshit-dev101 opened 1 year ago

akshit-dev101 commented 1 year ago

Would you like to work on a fix?

Current and expected behavior

import { Chart } from "react-google-charts";

function SankeyGraph(props) {
  const data = [
    ["From", "To", "Weight"],
    ["A", "X", 5],
    ["A", "Y", 7],
    ["A", "Z", 6],
    ["B", "X", 2],
    ["B", "Y", 9],
    ["B", "Z", 4],
  ];

  const options = {};
  return (
    <Chart
      chartType="Sankey"
      width="40%"
      height="200px"
      data={data}
      options={options}
    />
  );
}

export default SankeyGraph;
{
  "loadingStatus": "loading",
  "google": null
}

This is the state of the component even after all the rendering is done, it stays in loading, I tried the same code on code sandbox it worked fine.

Reproduction

Want able to reproduce this issue outside my project environment

react-google-charts version

v4.0.1

Possible solution

No response

davoam commented 1 year ago

@akshit-dev101 in our case it happened because we use Google Maps as well.

When charts are loaded and then a user goes to GoogleMap screen, the problem you mentioned appears. It happens because google map react library deletes window.google object on component unmount.

In the same time in the charts library, it is expected that if there is a script on the page, there should be window.google object. Which never happens, and the library is stuck on the loading state.

akshit-dev101 commented 1 year ago

@davoam any luck with the solution?

davoam commented 1 year ago

We just work around the problem. This is code inside our component which shows charts. It removes script from the dom and forces the library to load chart again

useLayoutEffect(() => {
    if (!window.google) {
      const script = document.querySelector('script[src="https://www.gstatic.com/charts/loader.js"]');
      const scriptLoaded = script?.getAttribute('data-loaded');
      if (script && scriptLoaded) {
        script.remove();
      }
    }
  }, []);

I think you need to investigate your case. Probably, there is another reason. You can begin with checking value window.google in browser console

akshit-dev101 commented 1 year ago

Currently, I have window.google as shown below, I tried using the code you provide, didn't work, but if I hard refresh the whole page the chart is visible @davoam, also I have the window.object , its not deleted as you said in the first comment.


    "charts": {
        "loader": {
            "VersionSpecific": {}
        }
    },
    "loader": {
        "LoadFailure": false
    },
    "visualization": {
        "ModulePath": {},
        "Version": "51",
        "Locale": "",
        "isDebug": false,
        "isPseudo": false,
        "mapsApiKey": {},
        "data": {},
        "errors": {
            "rV": "google-visualization-errors",
            "s6": "google-visualization-errors-",
            "v6": "google-visualization-errors:",
            "mV": "google-visualization-errors-all-",
            "r6": "google-visualization-errors: container is null",
            "tia": "background-color: #c00000; color: white; padding: 2px;",
            "Qja": "background-color: #fff4c2; color: black; white-space: nowrap; padding: 2px; border: 1px solid black;",
            "Sja": "font: normal 0.8em arial,sans-serif; margin-bottom: 5px;",
            "qja": "font-size: 1.1em; color: #00c; font-weight: bold; cursor: pointer; padding-left: 10px; color: black;text-align: right; vertical-align: top;"
        },
        "events": {},
        "datautils": {}
    }
}`
davoam commented 1 year ago

Sorry, I have no ideas what else may cause the problem. Most likely, in your case, there is another reason. Try setting breakpoints in devtools inside the library code and check what happens.

Danariel commented 3 months ago

I had this same problem with my charts. At the beginning I though it happened because I was loading too many charts in the same page (I was rendering 16 charts in one page with custom components that imported the Chart component, so 16 imports per render of the page). But later on, even with one chart, it was stuck at "loadingStatus": "loading" and the promise to process the chart was not executed.

After 1 week of tests, console.log for everything, etc I think I isolated the problem:

So I had to add a condition to only render the Chart if the data I'm going to send is a non-empty array or, at least, an empty array. If data is null, undefined or any other data, I only render a custom loader. Since doing that I had no problems with the loading of the charts.

I was setting a 'const [chartData, setChartData] = useState([]);' to store the data I was sending to the chart, and the console.log was printing 'undefined' at some of the renders. Because I'm using custom components for rendering the charts, I just added the condition inside the return to render the custom loader instead of the Chart component.

Hope this help someone avoid being very frustrated/angry/depressed because something that should work fine is not working.

NOTE: just in case, I'm using React 17