触发窗口调整大小事件时,高图复选框会倍增

时间:2019-01-31 16:02:59

标签: reactjs highcharts

我有一个应用程序,其中包含一个位于图表底部的复选框(按图例项)。

当我调整应用程序窗口的大小时,事件监听器(记录“调整大小”事件)会相应地更改图表的宽度,并在图表上显示一个新的复选框。

一个新的复选框也出现以及当图表主题被改变。

这使我相信每当重新渲染Highcharts(我使用React)时,都会创建一个新的复选框。

最初,仅存在一个复选框:

enter image description here

页面一次调整大小后:

enter image description here

多次调整大小后:

enter image description here

此外,总有在图表的右上角一个复选框(第一调整大小后出现):

enter image description here

在componendDidMount()周期,仅将复选框添加到图表一次。它使用这个选项添加到单个系列:

showCheckbox: true

在第一和唯一的时间,其生成图表,并将此选项被称为在主组件循环componentDidMount功能:

主容器

import Charts from './Charts';
import * as highcharts from 'highcharts';

class MainComponent exteds React.Component<Props, State> {

    public async componentDidMount() {
        try {
            // Here the charts are generated
            const initialOpts = Charts.generateCharts(); 

            const min = 1000;
            const max = 5000;
            highcharts.charts.map(chart => {
                chart.xAxis[0].setExtremes(min, max, undefined, false)
            });
        } catch { ... }
        this.chartDimensionsHandler();
        window.addEventListener('resize', this.chartDimensionsHandler);
    }

    private chartDimensionsHandler() {
        const chartHeight: number = ZoomService.getChartHeight();
        this.setState({ chartHeight }); 
        // When the state is set, component re-renders and causes the issue
    }
    /* 
    Theme is passed as props to the main component thus whenever theme changes, 
    new props arrive and component along with higcharts is also 
    re-rendered what causes a new checkbox to appear on top right of the chart
    */
}

图表类

export class ChartService {
    public generateCharts() {
        return this.charts.map((char) => this.generateDataChart(chart));
    }



    private generateDataChart(chart: Chart): Options {
        const { slices } = chart;
        const xValues = slices.map(slice =>
          Number(slice[chart.xAxis.name].value)
        );
        const xAxis = this.generateXAxisOptions(chart);
        const yAxis = [ ... ];

        const options = { xAxis, yAxis };

        // Create line series
        try {
          const lineSeries = this.constructDataSeries(chart, xValues);

          // Create events series
          const eventsCharts = this.charts.filter(
            x => x.type === 'events'
          );
          const eventsSeries = eventsCharts.map((evChart: Chart) => {
            // Here I call a function which sets 'showCheckbox' to true
            const allEvents = this.createEventSeries(evChart!)[0];
            allEvents.yAxis = 1;
            return allEvents;
          });

          const otherSeries = ...; // Irrelevant code

          // Add all series
          const series = [...otherSeries, ...eventsSeries];
          return Object.assign(options, { series });
        } catch (e) {
          return Object.assign(
            options,
            { series: [] },
            {
              lang: {
                noData: `Fail.`
              }
            }
          );
        }
      }

  private constructEventSeries(chart) {
    const { slices, yAxis, xAxis } = chart;
    const xValues = slices.map(slice =>
      Number(slice[xAxis.name].value)
    );

    return yAxis.map((item) => ({
      name: item.label,
      type: 'line',
      data: this.convertEventData(slices, xValues),
      lineWidth: 0,
      showCheckbox: true, // THE PLACE WHERE I SET showCheckbox to true
      marker: {
        enabled: true,
        radius: 10,
        symbol : 'circle'
      },
      meta: {
        type: 'events'
      }
    }));
  }

}

有人知道为什么每绘制一个新复选框都会向图表中添加一个新复选框(无论图表是否调整大小)?

1 个答案:

答案 0 :(得分:0)

我发现,每当记录resize事件时,Highcharts都会自动调用chart.reflow()函数,这会使复选标记倍增。组件setState函数使情况更糟。

通过使用higcharts函数chart.setSize(width, height, animation: boolean)直接将事件调用的功能从设置组件的状态更改为设置图表的尺寸。

然后,在CSS我设定第二复选框均未显示通过使用第n个子属性(因为resize事件总是创建第二复选框,没有办法关闭它(大概从highcharts一个bug) )。

这是我的解决方法。