Amcharts 4: пули-призраки/двойные пули при перезагрузке диаграммы

Описание ошибки

Привет. Я только что получил эту ошибку, когда дубликаты / призрачные маркеры создаются каждый раз, когда моя диаграмма перезагружается, когда появляются новые данные. Я перепробовал все, что мог, глубоко погрузившись в документацию, но не смог избавиться от этих призрачных пуль. Я не уверен, есть ли какая-то ошибка в системе или я делаю что-то не так. Любая помощь будет высоко оценен. Спасибо,

Вот код, который я использую для разработки диаграммы:

import React, { Component } from "react";
import { isEqual } from "lodash";
import * as am4core from "@amcharts/amcharts4/core";
import * as am4charts from "@amcharts/amcharts4/charts";
import am4themes_animated from "@amcharts/amcharts4/themes/animated";
import "./index.scss";

am4core.useTheme(am4themes_animated);
am4core.options.onlyShowOnViewport = true;
am4core.options.queue = true;

export default class index extends Component {
  componentDidMount() {
    let chart = am4core.create(this.props.name, am4charts.XYChart);
    chart.colors.list = [
      am4core.color("#FFFDAD"),
      am4core.color("##F4A460"),
      am4core.color("#75B9FF"),
      am4core.color("#FF94BA"),
    ];
    chart.dateFormatter.dateFormat = "yyyy-MM-dd";
    chart.dateFormatter.utc = false;
    chart.paddingRight = 20;

    let chartEvents = this.props.chartEvents || [];
    chart.data = chartEvents;
    chart.legend = new am4charts.Legend();
    chart.legend.labels.template.fill = am4core.color("#FFFFFF");
    chart.legend.labels.template.propertyFields.fill = "stroke";
    chart.legend.position = "top";
    chart.legend.itemContainers.template.paddingTop = 5;
    chart.legend.itemContainers.template.paddingBottom = 5;
    chart.legend.fontSize = 15;
    chart.legend.marginBottom = 25;
    let marker = chart.legend.markers.template.children.getIndex(0);
    marker.cornerRadius(12, 12, 12, 12);
    marker.strokeWidth = 5;

    let markerTemplate = chart.legend.markers.template;
    markerTemplate.width = 10;
    markerTemplate.height = 10;

    let dateAxis = chart.xAxes.push(new am4charts.DateAxis());
    dateAxis.renderer.labels.template.fill = am4core.color("#FFFFFF");
    dateAxis.title.text = "Time";
    dateAxis.title.fill = am4core.color("#FFFFFF");
    dateAxis.renderer.grid.template.location = 0;
    dateAxis.fontSize = 15;
    dateAxis.skipEmptyPeriods = true;
    dateAxis.renderer.grid.template.disabled = true;
    dateAxis.keepSelection = true;
    dateAxis.groupData = true;
    dateAxis.dateFormats.setKey("day", "yyyy-MM-dd");
    dateAxis.periodChangeDateFormats.setKey("day", "yyyy-MM-dd");
    dateAxis.groupIntervals.setAll([{ timeUnit: "minute", count: 15 }]);
    dateAxis.minZoomCount = 5;
    dateAxis.showOnInit = false;

    let valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
    valueAxis.renderer.labels.template.fill = am4core.color("#FFFFFF");
    valueAxis.tooltip.disabled = true;
    valueAxis.renderer.minWidth = 35;
    valueAxis.title.text = "Units";
    valueAxis.fontSize = 15;
    valueAxis.title.fill = am4core.color("#FFFFFF");
    valueAxis.min = 0;
    valueAxis.renderer.grid.template.disabled = false;

    let series1 = chart.series.push(new am4charts.LineSeries());
    series1.name = "Series1";
    series1.tooltipText = this.renderTooltip("series1");
    series1.dataFields.dateX = "timestamp";
    series1.dataFields.valueY = "series1";
    series1.tooltip.getFillFromObject = false;
    series1.tooltip.background.fill = am4core.color("#FFFDAD");
    series1.tooltip.label.fill = am4core.color("#000");
    series1.stroke = am4core.color("#FFFDAD");
    series1.strokeWidth = 2;
    series1.connect = false;
    series1.showOnInit = false;

    let series2 = chart.series.push(new am4charts.LineSeries());
    series2.name = "Series2";
    series2.tooltipText = this.renderTooltip("series2");
    series2.dataFields.dateX = "timestamp";
    series2.dataFields.valueY = "series2";
    series2.tooltip.getFillFromObject = false;
    series2.tooltip.background.fill = am4core.color("#F4A460");
    series2.tooltip.label.fill = am4core.color("#000");
    series2.stroke = am4core.color("#F4A460");
    series2.strokeWidth = 2;
    series2.connect = false;
    series2.showOnInit = false;

    let series3 = chart.series.push(new am4charts.LineSeries());
    series3.name = "series3";
    series3.tooltipText = `Name: [bold]Series3[/]
    Time :  {timestamp.formatDate('yyyy-MM-dd HH:mm:ss')} `;
    series3.dataFields.dateX = "timestamp";
    series3.dataFields.valueY = "series3";
    series3.strokeOpacity = 0;
    series3.sequencedInterpolation = true;
    series3.tooltip.background.fill = am4core.color("#75B9FF");
    series3.minBulletDistance = 15;

    series3.showOnInit = false;
    series3.autoDispose = true;

    let bullet = series3.bullets.push(new am4charts.Bullet());
    bullet.isDynamic = true;
    let triangle = bullet.createChild(am4core.Triangle);
    triangle.width = 11;
    triangle.height = 11;
    triangle.dy = 5;
    triangle.direction = "bottom";
    triangle.propertyFields.fill = am4core.color("#75B9FF");
    triangle.propertyFields.fillOpacity = 1;
    triangle.fillOpacity = 1;
    triangle.strokeWidth = 1;
    triangle.horizontalCenter = "middle";
    triangle.verticalCenter = "bottom";

    let hoverState = bullet.states.create("hover");
    hoverState.properties.scale = 1.7;

    let series4 = chart.series.push(new am4charts.LineSeries());
    series4.name = "series4";
    series4.tooltipText = `Name: [bold]series4[/]
    Time :  {timestamp.formatDate('yyyy-MM-dd HH:mm:ss')}`;
    series4.dataFields.dateX = "timestamp";
    series4.dataFields.valueY = "series4";
    series4.strokeOpacity = 0;
    series4.sequencedInterpolation = true;
    series4.tooltip.background.fill = am4core.color("#FF94BA");
    series4.minBulletDistance = 15;
    series4.showOnInit = false;
    series4.autoDispose = true;
    let bullet01 = series4.bullets.push(new am4core.Circle());
    bullet01.radius = 5;
    bullet01.propertyFields.fill = am4core.color("#FF94BA");
    bullet01.fillOpacity = 1;
    bullet01.isDynamic = true;

    let hoverState1 = bullet01.states.create("hover");
    hoverState1.properties.scale = 1.7;

    let range = dateAxis.axisRanges.create();
    range.date = new Date();
    range.grid.stroke = am4core.color("red");
    range.grid.strokeWidth = 1;
    range.grid.strokeOpacity = 0.5;

    chart.cursor = new am4charts.XYCursor();
    chart.showOnInit = true;
    chart.zoomOutButton.dom.addEventListener("click", this.resetDateSelector);
    chart.maskBullets = true;

    chart.events.on("shown", () => {
      dateAxis.zoomToDates(this.setStartTime(7), this.setEndTime(2), false);
    });

    this.chart = chart;
    this.dateAxis = dateAxis;
  }

  componentDidUpdate(oldProps) {
    if (
      !isEqual(
        oldProps.chartEvents,
        this.props.chartEvents
      ) &&
      typeof this.props.chartEvents === "object" &&
      this.props.chartEvents.length !== 0
    ) {
      this.chart.data = this.props.chartEvents;
      this.chart.reinit();
    }
  }

  componentWillUnmount() {
    if (this.chart) {
      this.chart.dispose();
    }
  }

  renderTooltip = (name) => {
    return `{name}: [bold]{${name}}[/]
    Time: {timestamp.formatDate('yyyy-MM-dd HH:mm:ss')}[/]`;
  };

  setStartTime = (days) => {
    let currentDate = new Date();
    let pastTime = currentDate.setDate(currentDate.getDate() - days);
    return pastTime;
  };

  setEndTime = (days) => {
    let currentDate = new Date();
    let futureTime = currentDate.setDate(currentDate.getDate() + days);
    return futureTime;
  };

  resetDateSelector = () => {
    this.dateAxis.zoomToDates(this.setStartTime(7), this.setEndTime(2));
  };

  render() {
    return (
      <div
        id={this.props.name}
        style={{ width: "100%", minHeight: "550px" }}
      ></div>
    );
  }
}

Окружающая среда

  • Версия Амчартс: 4.9.23
  • Версия реакции: 16.12.0
  • Версия браузера Chrome: 83.0.4103.61.

person Praveen Venigalla    schedule 22.05.2020    source источник


Ответы (1)


Я смог решить эту проблему, используя следующий код:

for (const series of chart.series) { series.bulletsContainer.disposeChildren() }

перед установкой

chart.data = data;

Я смог получить это решение из следующей ветки ошибки № 1908 Amcharts4: https://github.com/amcharts/amcharts4/issues/1908

person Praveen Venigalla    schedule 25.05.2020