«Диаграмма не была размещена» в amChart в оперативных данных при использовании сокета

У меня аналогичная проблема с предупреждением amChart «диаграмма не удалена», что вызывает утечку памяти.

Для решения я просмотрел это https://www.amcharts.com/docs/v4/tutorials/chart-was-not-disposed/

Но поскольку я обновляю диаграмму (живую диаграмму) с помощью сокета, у меня нет статических данных. Я загружаю динамические данные в amChart, используя сокет из базы данных. Я не могу использовать chart.dispose(), который не работает для моего кода, и, честно говоря, я не уверен, правильно ли я использую chart.dispose().

Поскольку я реализовал код amChart в своем сервисе angular, как показано ниже.

На моей угловой службе.

init( currentChart, productChart, gaugeChart, legend ) {
    this.getConfig( currentChart, productChart, gaugeChart, legend );
    this.getConfigMeag();
    this._today = this.datePipe.transform( this._today, 'yyyy-MM-dd HH:mm:ss' );
    this._todate = this.datePipe.transform( this._today, 'yyyy-MM-dd' );
    let socket = io.connect( DatabaseUtility.extractIpFromAddressBar );
    socket.on( 'socketUpdate', ( data ) => {
        this._today = Date.now();
        this._today = this.datePipe.transform( this._today, 'yyyy-MM-dd HH:mm:ss' );
        this._todate = this.datePipe.transform( this._today, 'yyyy-MM-dd' );
        this.getCurrentData( this._today, productChart, gaugeChart, legend );
        this.getCurrentYieldData( this._todate, currentChart);
    } );
}



liveChart( alarmCheck, warningCheck, currentChart ) {
    if ( !this._liveChart) {
        return;
    }

    if(this._chart){
        this._chart.dispose();  //When I added here still I'm getting the "Chart was not disposed" warning
    }

    this._chart = am4core.create( currentChart.nativeElement, am4charts.XYChart );
    this._chart.cursor = new am4charts.XYCursor();
    this._chart.data = this._liveChart;
    if(this._chart){
        this._chart.dispose(); //When I added here it shows "Error: EventDispatcher is disposed"
    }
    this._chart.legend = new am4charts.Legend();
    this._chart.legend.labels.template.text = "Current Yield";

    // Create axes
    let dateAxis = this._chart.xAxes.push( new am4charts.DateAxis() as any );
    dateAxis.dataFields.category = "Date";
    dateAxis.renderer.grid.template.location = 0;
    dateAxis.renderer.minGridDistance = 40;
    dateAxis.renderer.labels.template.location = 0.0001;
    dateAxis.dateFormatter.inputDateFormat = "YYYY-MM-DD, HH:mm";
    dateAxis.dateFormats.setKey( "minute", "HH:mm" );
    dateAxis.baseInterval = {
        "timeUnit": "minute",
        "count": this._configValues.cycleTime
    };

    dateAxis.renderer.line.strokeOpacity = 1;
    dateAxis.renderer.line.strokeWidth = 1;
    dateAxis.renderer.line.stroke = am4core.color( "#3787ac" );

    let valueAxis = this._chart.yAxes.push( new am4charts.ValueAxis() as any );
    valueAxis.autoGridCount = false;
    valueAxis.max = 110;
    valueAxis.min = 0;
    valueAxis.title.text = "(%)";
    valueAxis.title.align = "center";
    valueAxis.title.fontWeight = 400;
    valueAxis.unit = "%";
    valueAxis.unitPosition = "right";

    valueAxis.renderer.line.strokeOpacity = 1;
    valueAxis.renderer.line.strokeWidth = 1;
    valueAxis.renderer.line.stroke = am4core.color( "#3787ac" );

    valueAxis.renderer.ticks.template.disabled = false;
    valueAxis.renderer.ticks.template.strokeOpacity = 1;
    valueAxis.renderer.ticks.template.stroke = am4core.color( "#495C43" );
    valueAxis.renderer.ticks.template.strokeWidth = 2;
    valueAxis.renderer.ticks.template.length = 10;

    if ( warningCheck ) {
        let range = valueAxis.axisRanges.create();
        range.value = this._warningUpperLimit;
        range.grid.stroke = am4core.color( "#cc3300" );
        range.grid.strokeWidth = 2;
        range.grid.strokeOpacity = 1;
        range.label.inside = true;
        range.label.text = "Warning Upper Limit";
        range.label.fill = range.grid.stroke;
        range.label.verticalCenter = "bottom";

        let range2 = valueAxis.axisRanges.create();
        range2.value = this._warningLowerLimit;
        range2.grid.stroke = am4core.color( "#cc3300" );
        range2.grid.strokeWidth = 2;
        range2.grid.strokeOpacity = 1;
        range2.label.inside = true;
        range2.label.text = "Warning Lower Limit";
        range2.label.fill = range2.grid.stroke;
        range2.label.verticalCenter = "bottom";
    }

    if ( alarmCheck ) {
        let range3 = valueAxis.axisRanges.create();
        range3.value = this._alarmUpperLimit;
        range3.grid.stroke = am4core.color( "#A96478" );
        range3.grid.strokeWidth = 2;
        range3.grid.strokeOpacity = 1;
        range3.label.inside = true;
        range3.label.text = "Alarm Upper Limit";
        range3.label.fill = range3.grid.stroke;
        range3.label.verticalCenter = "bottom";

        let range4 = valueAxis.axisRanges.create();
        range4.value = this._alarmLowerLimit;
        range4.grid.stroke = am4core.color( "#A96478" );
        range4.grid.strokeWidth = 2;
        range4.grid.strokeOpacity = 1;
        range4.label.inside = true;
        range4.label.text = "Alarm Lower Limit";
        range4.label.fill = range4.grid.stroke;
        range4.label.verticalCenter = "bottom";
    }

    // Create series
    let series = this._chart.series.push( new am4charts.LineSeries() as any );
    series.tooltipText = "{date}\n[bold font-size: 17px]Value: {valueY}[/]";
    series.dataFields.valueY = "value";
    series.dataFields.dateX = "date";
    series.tensionX = 0.8;
    series.strokeWidth = 3;
    series.strokeOpacity = 5;

    let bullet = series.bullets.push( new am4charts.CircleBullet() );
    bullet.strokeWidth = 2;
    bullet.stroke = am4core.color( "#000" );
    bullet.setStateOnChildren = true;
    bullet.propertyFields.fillOpacity = "opacity";
    bullet.propertyFields.strokeOpacity = "opacity";

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

    /* Create a cursor */
    this._chart.cursor = new am4charts.XYCursor();
}

В моем угловом компоненте

 ngAfterViewInit() {
    this.zone.runOutsideAngular( () => {
        this._service.init( this.currentChart, this.productChart, this.gaugeChart, this.legend );
    } );

}

ngOnDestroy() : void {
    this.zone.runOutsideAngular( () => {
        if ( this._service.chart ) {
            this._service.chart.dispose();
        }
    } );
}

HTML

 <div class="tile__content">
        <div [style.width.%]="100" [style.height.px]="480" #currentChart></div>
    </div>

Если я использую am4core.disposeAllCharts(), я не увижу никакого графика.

Какое правильное место для dispose chartdata?


person Kirataka    schedule 26.11.2019    source источник
comment
Вы добавили ширину HTML-элементу?   -  person Jimmy Kane    schedule 26.11.2019
comment
@ДжиммиКейн Да. Я только что обновил HTML.   -  person Kirataka    schedule 26.11.2019
comment
Пожалуйста, не добавляйте проценты. Используйте min-width: 320px, а затем процент. Попробуй это   -  person Jimmy Kane    schedule 26.11.2019


Ответы (1)


Я не знаю Angular, но в Vue.js мне пришлось распоряжаться диаграммой и в tick создавать ее снова. Итак, я сделал что-то вроде этого:

    loadChart(){
      if (this.chart) {
        this.chart.dispose();
        this.chart = null;
      }

      this.chartIsLoading = true;

      // other preparation code here

      // clear and then new loading on the next tick is needed for the disposing to finish.
      const that = this;
      this.$nextTick( () => {
        that.loadJsonCharts();
      });
    },

Вот ветка о тике в Angular: Когда и почему использовать «галочку» в Angular 2?

Надеюсь, поможет!

person DomDom    schedule 17.04.2020