Как правильно отправить действие из диаграммы Highcharts? - PullRequest
0 голосов
/ 24 марта 2020

Контекст Я пытаюсь визуализировать диаграмму старших графиков, используя избыточность для управления обновлениями состояния. На диаграмме старших диаграмм необходимо

  1. Обновление на основе хранилища приращений (это выполняется в chart.events.render и работает нормально)
  2. Отправка действий по событиям для обновления хранилища приращений ( Я хочу выполнить это в scatter.point.events.mouseOver / mouseOut / click, но это не работает для mouseOver / mouseOut)

Поведение В случае события mouseOver точки, действие успешно отправлено. Однако после отправки действия исходный точечный объект теперь содержит нулевые ссылки. Это вызывает ошибки в нисходящем направлении в Highchart (например, всплывающая подсказка refre sh выдает эту ошибку: TypeError: Невозможно прочитать свойство 'tooltipOptions' типа null.)

import React from 'react'; // version 16.13.0
import Highcharts from 'highcharts' // version 5.0.14
import HighchartsReact from 'highcharts-react-official' // version 2.2.2
import {connect} from 'react-redux';

import {keyValueTableTooltipFormatter} from 'plotUtils';
import {COLORS} from 'plots/constants';
import {
  selectItemsAction,
  deselectItemsAction,
  highlightItemsAction,
  dehighlightItemsAction
} from "stores/call_review/actions";
import {keyAction} from 'stores/api/base/utils';

class FFPlot extends React.Component {
  render() {
    // general properties
    const {series, title, height, width, xAxisTitle, yAxisTitle, range} = this.props;
    const {xMin, xMax, yMin, yMax} = getFFRanges(series, range);

    // guides
    const {guideLines, guideBoxes} = this.props;
    const guides = [...addGuideLines(guideLines, xMax, yMax), ...addGuideBoxes(guideBoxes)];

    // selection
    const {
      highlightedResults,
      selectedResults,
      onClick,
      highlightResult,
      dehighlightResult,
    } = this.props;
    const pointLabels = [];

    const config = {
      series: [...guides, ...series],
      chart: {
        height: height || 500,
        width: width || 500,
        zoomType: 'xy',
        animation: false,
        events: {
          // handle point appearance
          render: function() {
            this.series.forEach(dataSeries => {
              dataSeries.data.forEach(datum => {
                if (datum.result && selectedResults.has(datum.result.id)) {
                  datum.select(true, true);
                } else if (datum.result && !selectedResults.has(datum.result.id)) {
                  datum.select(false, true);
                }
                if (datum.result && highlightedResults.has(datum.result.id)) {
                  datum.setState('hover');
                }
              });
            });
          },
        },
      },
      title: {
        text: title,
      },
      tooltip: {
        enabled: true,
        useHTML: true,
        animation: false,
        hideDelay: 0,
        formatter() {
          return keyValueTableTooltipFormatter(this.point.meta);
        },
      },
      xAxis: {
        title: {
          text: xAxisTitle,
        },
        min: xMin,
        max: xMax,
        gridLineWidth: 0,
        tickAmount: 6,
      },
      yAxis: {
        title: {
          text: yAxisTitle,
        },
        min: yMin,
        max: yMax,
        gridLineWidth: 0,
        lineWidth: 1,
        tickAmount: 6,
        tickWidth: 1,
      },
      legend: {
        enabled: false,
      },
      plotOptions: {
        series: {
          allowPointSelect: true,
          animation: false,
          cursor: 'pointer',
          stickyTracking: false,
        },
        scatter: {
          point: {
            events: {
              mouseOver: function(e) {
                const point = Object.assign({}, this);
                const result_id = this.result.id;
                highlightResult(result_id);
                console.log(this, point) // **** PRINTING ****
              },
              mouseOut: function(e) {
                const result_id = this.result.id;
                dehighlightResult(result_id);
              },
              click: function(e) {
                const result_id = this.result.id;
                onClick(selectedResults, e, result_id);
              },
            },
          },
        },
      },
    };

    return (
      <div>
        <HighchartsReact highcharts={Highcharts} options={config}/>
      </div>
    );
  }
}

const mapState = state => ({
  highlightedResults: state.highlight.results,
  selectedResults: state.selection.results,
});

const mapDispatch = dispatch => {
  const highlightResult = resultID => {
    dispatch(keyAction('results', highlightItemsAction([resultID])));
  };

  const dehighlightResult = resultID => {
    dispatch(keyAction('results', dehighlightItemsAction([resultID])));
  };

  const deselectResults = resultID => {
    dispatch(keyAction('results', selectItemsAction([], false)));
  };

  const onClick = (selectedResults, event, resultID) => {
    if (selectedResults.has(resultID)) {
      if (!event.shiftKey) {
        deselectResults();
      }
      dispatch(keyAction('results', deselectItemsAction([resultID])));
    } else {
      dispatch(keyAction('results', selectItemsAction([resultID], event.shiftKey)));
    }
  };

  return {
    onClick,
    highlightResult,
    dehighlightResult,
  };
};

export default connect(
  mapState,
  mapDispatch
)(FFPlot);

Выход на консоль:

это ->

series: null
color: null
x: null
y: null
...

точка ->

series: l {sorted: false, requireSorting: false, noSharedTooltip: true, trackerGroups: Array(3), takeOrdinalPosition: false, …}
color: "rgba(101, 160, 219, 0.8)"
x: 0.1727881999111891
y: 0.18193335289975
...

Ошибка ->

    at a.Tooltip.refresh (highcharts.js?ea7f:196)
    at a.Pointer.runPointActions (highcharts.js?ea7f:208)
    at C.onMouseOver (highcharts.js?ea7f:392)
    at SVGGElement.d (highcharts.js?ea7f:384)
...