Search code examples
reactjsdownloadkendo-uipngkendo-react-ui

Kendo React save chart as image


I'm having a problem about the download of the kendo react chart as an image,
currently the download works but only for my latest chart (I have six of them)
I've recreated the error in stackblitz
As you can see whenever I try to download one of the 2 charts the downloaded one is always the latest one
Is there any way for fixing this?


Solution

  • The problem is that refContainer is being set twice inside your App component in the example you linked. One time for each of your charts. The reference will always refer to the second chart, because the second chart overwrites the value of refContainer last.

    What you can do instead is to create a CustomChart component that holds its own ref (refContainer). This way you can render multiple instances of this component, without the refs clashing. This also allows us to get rid of some duplicate code for creating the chart.

    So you can do something like this:

    import * as React from "react";
    import {
      Chart,
      ChartSeries,
      ChartSeriesItem,
      ChartCategoryAxis,
      ChartCategoryAxisItem,
      exportVisual,
    } from "@progress/kendo-react-charts";
    
    import { exportImage } from "@progress/kendo-drawing";
    import { saveAs } from "@progress/kendo-file-saver";
    
    const CustomChart = ({ categories, data }) => {
      let refContainer = React.useRef(null);
    
      const onExportVisual = () => {
        const chartVisual = exportVisual(refContainer);
        if (chartVisual) {
          exportImage(chartVisual).then((dataURI) => saveAs(dataURI, "chart.png"));
        }
      };
    
      return (
        <>
          <button onClick={() => onExportVisual()}>Export as visual element</button>
          <Chart ref={(chart) => (refContainer = chart)}>
            <ChartCategoryAxis>
              <ChartCategoryAxisItem categories={categories} />
            </ChartCategoryAxis>
            <ChartSeries>
              <ChartSeriesItem data={data} />
            </ChartSeries>
          </Chart>
        </>
      );
    };
    
    const App = () => {
      return (
        <div>
          <CustomChart
            categories={[2015, 2016, 2017, 2018]}
            data={[10, 100, 100, 10]}
          />
          <CustomChart
            categories={[2015, 2016, 2017, 2018]}
            data={[100, 10, 10, 100]}
          />
        </div>
      );
    };
    
    export default App;