You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React ApexChart更新选项时如何保持缩放级别不重置?

问题

使用React ApexChart展示数据,设置开关控制数据标签的显示/隐藏,修改选项时图表缩放级别会被重置。如何在React中实现更新选项时保留缩放级别?是否需要改用原生ApexChart实现?

组件示例代码

import Chart from "react-apexcharts";
import React, { useEffect, useState } from 'react';
import { Layout } from "antd";

interface Props {
  series?: ApexAxisChartSeries;
  chartOptiosn?: Record<string, any>;
  [ key: string ]: any;
}

export const DynamicChart: React.FC<Props> = React.memo( ( props: Props ) => {
  const { Content } = Layout;
  const { series, chartOptions, uuid } = props;
  const [ initialRerender, setInitialRerender ] = useState( false );

  useEffect( () => {
    if ( !initialRerender ) {
      setInitialRerender( true );
    }
  }, [ initialRerender ] );

  useEffect( () => {
  }, [] );


  useEffect( () => {
    console.log( chartOptions );
  }, [ chartOptions ] );


  return (
    <Layout>
      <Content>
        <Chart
          options={ { ...structuredClone( chartOptions || {} ), chart: { ...chartOptions.chart, id: uuid } } }
          series={ series }
          type="area"
          height={ 350 }
        />
      </Content>
    </Layout>

  );
} );

图表配置选项

export const defaultOptions: ApexCharts.ApexOptions = {
  series: [],
  chart: {
    animations: {
      enabled: true,
      easing: "linear",
      dynamicAnimation: {
        speed: 300
      }
    },
    toolbar: {
      show: true,
      tools: {
        download: `<svg viewBox="64 64 896 896" focusable: "false" name= "download" theme="outlined"><path d="M505.7 661a8 8 0 0012.6 0l112-141.7c4.1-5.2.4-12.9-6.3-12.9h-74.1V168c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v338.3H400c-6.7 0-10.4 7.7-6.3 12.9l112 141.8zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z"></path></svg>`,
        selection: false,
        zoom: true,
        zoomin: true,
        zoomout: true,
        pan: true,
        customIcons: []
      },
    },
    zoom: {
      enabled: true
    }
  },
  dataLabels: {
    enabled: false
  },
  yaxis: {
    labels: {
      style: {
        fontSize: "14px",
        fontWeight: 600,
        colors: [ "#8c8c8c" ],
      },
    },
  },
  xaxis: {
    type: "datetime"
  }
};
解决方案

不需要改用原生实现,通过以下方式可在React中保留缩放状态:

1. 核心思路

问题根源是每次更新chartOptions时,组件传递了新的options对象导致图表重新初始化,丢失缩放状态。解决方案是直接操作图表实例,保存并恢复缩放范围。

2. 修改后的组件代码

import Chart from "react-apexcharts";
import React, { useEffect, useRef, useState } from 'react';
import { Layout } from "antd";

interface Props {
  series?: ApexAxisChartSeries;
  chartOptions?: Record<string, any>;
  [key: string]: any;
}

export const DynamicChart: React.FC<Props> = React.memo((props: Props) => {
  const { Content } = Layout;
  const { series, chartOptions, uuid } = props;
  const chartRef = useRef<{ chart: ApexCharts }>(null);
  // 保存当前缩放的X轴范围
  const [savedXRange, setSavedXRange] = useState<{ min: number; max: number } | null>(null);

  // 监听缩放/平移事件,保存当前范围
  const handleZoomPan = () => {
    if (!chartRef.current) return;
    const xAxis = chartRef.current.chart.xaxis;
    setSavedXRange({ min: xAxis.min, max: xAxis.max });
  };

  // 更新图表选项时,保留缩放状态
  useEffect(() => {
    if (!chartRef.current || !chartOptions) return;

    // 先更新选项,第三个参数设为false表示不重置缩放
    chartRef.current.chart.updateOptions(chartOptions, false, false);
    // 如果有保存的缩放范围,恢复
    if (savedXRange) {
      chartRef.current.chart.updateOptions(
        { xaxis: { min: savedXRange.min, max: savedXRange.max } },
        true, // 重绘图表
        false // 不重置缩放状态
      );
    }
  }, [chartOptions]);

  // 更新系列数据时,保留缩放状态
  useEffect(() => {
    if (!chartRef.current || !series) return;

    chartRef.current.chart.updateSeries(series, false);
    if (savedXRange) {
      chartRef.current.chart.updateOptions(
        { xaxis: { min: savedXRange.min, max: savedXRange.max } },
        true,
        false
      );
    }
  }, [series]);

  return (
    <Layout>
      <Content>
        <Chart
          ref={chartRef}
          options={{
            ...chartOptions || {},
            chart: {
              ...chartOptions?.chart,
              id: uuid,
              events: {
                zoom: handleZoomPan,
                pan: handleZoomPan
              }
            }
          }}
          series={series}
          type="area"
          height={350}
        />
      </Content>
    </Layout>
  );
});

3. 关键细节说明

  • 使用useRef获取图表实例,直接调用原生updateOptions和updateSeries方法,避免组件重新渲染导致实例重建
  • 在zoom和pan事件中保存当前X轴的缩放/平移范围
  • 调用updateOptions时,第三个参数设为false,表示不重置缩放状态
  • 去掉structuredClone,避免创建新的options对象触发不必要的组件更新

内容的提问来源于stack exchange,提问作者Andy95

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 07:10:32