react-apexcharts icon indicating copy to clipboard operation
react-apexcharts copied to clipboard

basic column chart - when xaxis categories updates dynamically, that's not reflected in chart

Open panimaya-gembrill opened this issue 4 years ago • 5 comments

I tried using below code in my application. https://apexcharts.com/react-chart-demos/column-charts/basic/

In the below graph I can see the xaxis categories updates dynamically based on data. but in graph that's not reflected.

image

expected outcome:

  • [ ] When xaxis categories updated dynamically it should reflect in the graph

image

panimaya-gembrill avatar Aug 04 '21 09:08 panimaya-gembrill

any update? I am facing the same issue :(

petr-hybler avatar Apr 29 '22 11:04 petr-hybler

I also encountered the same problem.

joe94113 avatar May 06 '22 05:05 joe94113

In vue, I can use updateOptions to solve the problem.

<apexchart ref="chart" type="bar" height="350" :options="chartOptions" :series="series"></apexchart>

<script>
methods:{
  change(){
    this.$refs.chart.updateOptions({
        xaxis: {
            type: 'date',
            categories: [1,2,3],
        }
    });
  }
}
</script>

joe94113 avatar May 06 '22 06:05 joe94113

In react I can use useEffect to monitor and update the state changes.

useEffect(() => {
    setState((prevState) => {
      return {
        ...prevState,
        options: {
          ...prevState.options,
          xaxis: {
            categories: templatePerformancechartData.map(
              (data) => data.emailTemplateName
            ),
            labels: {
              trim: true,
              maxHeight: 50,
            },
          },
        },
      };
    });
  }, [templatePerformancechartData]);

<ReactApexChart options={state.options} series={state.series} type="bar" height={350} />

panimaya-gembrill avatar May 06 '22 08:05 panimaya-gembrill

For me (using a component class), the following works just fine. I bind a separate function to update the different properties of the chart depending on changed intervals or filters from the main App component. It can be adapted to use the function components instead.

export function updateChart(chart) {
    const series = chart.series;
    const labels = chart.labels;

    this.setState({
        series: series, // Updating with the new series
        options: {
            xaxis: {
                categories: labels // This is what is necessary to also update the categories
            }
        }
    });
}

And don't forget to bind the function in the constructor method for the chart.

updateChart = updateChart.bind(this);

So whenever I update the the date filter or any other data in my main component I just call the function and the chart is updated (both series and labels)

componentDidUpdate() {
    updateChart(this.state.charts.new_chart_data);
}

And this is the chart component itself

class ExampleChart extends React.Component {
    constructor(props) {
        super(props);

        const chart = this.props.chart;

        updateChart = updateChart.bind(this);

        this.state = {
            options: {
                chart: {
                    id: "example-chart",
                    toolbar: {
                        show: false
                    },
                },
                dataLabels: {
                    enabled: true
                },
                stroke: {
                    curve: 'smooth'
                },
                xaxis: {
                    categories: chart.labels
                }
            },
            days: this.props.days,
            series: chart.series
        };
    }

    render() {
        return (
            <div className="app">
                <div className="row">
                    <div className="mixed-chart">
                        <Chart
                            options={this.state.options}
                            series={this.state.series}
                            type={this.props.type}
                            width="100%"
                            height="400px"
                        />
                    </div>
                </div>
            </div>
        );
    }
}

I am still somewhat of a novice when it comes to React, and there are possibly better solutions. But I just wanted to add this approach since I got it working with the desired effect.

11902398 avatar Jul 05 '22 15:07 11902398