无法使用Angular 4在HighChart上重复的情况下加载系列



我已经在Angular 4应用程序中实现了HighChart。我的Highchart似乎两次加载了同一系列。我用@Input((设置RESSTESTESTESTRESULTS声明来调用的方法称为addseries。我可以看到突发点在那里撞到两次,并两次调用添加程序。我不确定如何防止两次被称为。如果我将添加程序移至ngoninit,那么它不会在加载图表并在页面的刷新上获得值,我可以看到值通过的值。这次它正确显示了一个系列。如果初始化是正确的位置,那么更改检测或从检索数据中滞后存在一些问题。有人可以告诉我我要去哪里出错

import { Component, OnInit, Input,ViewChild } from '@angular/core';
import { StressTestAnalysis } from '../../../../api/dtos';
import { ReactiveComponent } from '@wtw/toolkit/src/utils/base.component';
import { SplineChartComponent } from '../../../../shared/Highcharts/spline/spline-chart.component';
export interface ChartSeries {
  data: number[][];
  name: string;
  color: string;
}
@Component({
  selector: 'app-stress-test-analysis',
  templateUrl: './stress-test-analysis.component.html'
})
export class StressTestAnalysisComponent extends ReactiveComponent implements OnInit {
  isExpanded = false;
  showTable = true;
  private results: Array<StressTestAnalysis> = [];
  @ViewChild(SplineChartComponent) public stressSplineChart: SplineChartComponent;
  //@Input() results: Array<StressTestAnalysis> = [];
  @Input() set stressTestResults(value: Array<StressTestAnalysis>) {
    this.results = value;
    this.addSeries();
  }
  public chartSeries: Array<ChartSeries> = [];
  seriesName: string;
  strategyName: string = '';
  constructor(
  ) { super(); }
  ngOnInit() {
  // this.addSeries();
  }
  private addSeries() {
    if (this.results === null) {
      return;
    }
    this.results.forEach(element => {
      if (element !== null) {
          this.chartSeries.push({ data: element.graphData, name: element.seriesName, color: element.color });
        //  if (this.stressSplineChart) this.stressSplineChart.redraw();
      }
    });
  }
}

父组件html

您可以在这里看到我已经将压力策略初始化为儿童组成部分的atspertestestresults

<div class="container-fluid mt-3 mb-3 test-feasibility--details">
  <app-assumptions-summary></app-assumptions-summary>
</div>
<form #pageForm="ngForm">
  <div class="container-fluid base_strategy p-0 m-0">
    <div class="tb-container col-md-12 p-0 m-0 scroll-auto">
      <app-strategies [strategies]="run.strategies" [linesOfBusinessInput]="run.linesOfBusinessInput"  [redraw]="forceRedraw" (applyChange)="applyChange($event)" (save)="save()"></app-strategies>
      <div class="col-12 test_feasibility--accordion">
        <!-- Accordion -->
        <div id="accordion" role="tablist">
          <app-net-present-value-analysis [npvResults]="npvResults"></app-net-present-value-analysis>
          <app-economic-value-analysis [evResults]="evResults"></app-economic-value-analysis>
          <app-stress-test-analysis [stressTestResults]="stressTestResults"></app-stress-test-analysis>
          <app-ending-surplus-analysis [results]="endingSurplusResults"></app-ending-surplus-analysis>
        </div>
        <!-- Accordion End -->
      </div>
    </div>
  </div>
</form>

图表组件

import { Component, Input, OnChanges } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
@Component({
    selector: 'splinechart',
    template: '<chart [options]="options" (load)="getInstance($event.context)"></chart>',
    styles: [`
    chart {
        display: block;
        width: 100% !important;
         padding:0;
      }`]
})
export class SplineChartComponent implements OnChanges {
    public options: any;
    chart: any;
    @Input() public series: any;
    @Input() public yaxisdata: any;
    @Input() public selectedRating: string = '';
    constructor(private _translate: TranslateService) {
        this.options = {
            credits: {
                enabled: false
            },
            chart: {
                type: 'spline'
            },
            title: {
                text: ''
            },
            subtitle: {
                text: ''
            },
            legend: {
                layout: 'horizontal',
                margin: 25,
                itemMarginTop: 0,
                symbolRadius: 0,
                symbolHeight: 20,
                symbolWidth: 20,
                useHTML: true,
                    title: {
                    text: this._translate.instant('CAPTIVES.RESULTS.COMMON.GRAPH_LEGEND_TITLE'),
                    margin: 50,
                    style: {
                        fontStyle: 'italic',
                        fontWeight: 'normal'
                    }
                },
                align: 'right',
                verticalAlign: 'bottom',
            },
            xAxis: {
                title: {
                    text: this._translate.instant('CAPTIVES.RESULTS.STA.GRAPH_XAXIS')
                }
            },
            yAxis: {
                title: {
                    text: this._translate.instant('CAPTIVES.RESULTS.STA.GRAPH_YAXIS')
                }
            },
            tooltip: {
            },
            plotOptions: {
                series: {
                    cursor: 'pointer',
                    events: {
                        legendItemClick: function() {
                            const elements = document.querySelectorAll('.highcharts-legend-item path');
                            for (let i = 0; i < elements.length; i++) {
                                elements[i].setAttribute('stroke-width', '20');
                                elements[i].setAttribute('stroke-height', '20');
                            }
                            this.chart.redraw();
                        }
                    },
                    allowPointSelect: true,
                },
                spline: {
                    lineWidth: 2,
                    states: {
                        hover: {
                            lineWidth: 3
                        }
                    },
                    marker: {
                        enabled: true,
                        symbol: 'circle'
                    },
                }
            },
            series: [
                {
                    showInLegend: false
                }
            ]
        };
    }
    getInstance(chartInstance): void {
        this.chart = chartInstance;
        this.redraw();
    }
    ngOnChanges(data: any) {
        if (!data.series.currentValue || !this.chart) return;
         var seriesLength = this.chart.series.length;
        for(var i = seriesLength -1; i > -1; i--) {
            this.chart.series[i].remove();
        }
        data.series.currentValue.map(s => {
            this.chart.addSeries(s);
        });
        this.chart.reflow();
    }
   public redraw() {
        if (!this.chart) return;
        //   var seriesLength = this.chart.series.length;
        // for(var i = seriesLength -1; i > -1; i--) {
        //     this.chart.series[i].remove();
        // }
        this.series.map(s => {
            if (s !== null)
                this.chart.addSeries(s);
        });
        const elements = document.querySelectorAll('.highcharts-legend-item path');
        for (let i = 0; i < elements.length; i++) {
            elements[i].setAttribute('stroke-width', '20');
            elements[i].setAttribute('stroke-height', '20');
        }
        this.chart.redraw();
    }
}

父组件代码

import { Component, OnInit } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { RunService, NavBarService } from '@wtw/platform/services';
import { Base } from '@wtw/toolkit';
import { NpvAnalysis, EvAnalysis } from '../../../shared/models/results';
import { Dto } from '@wtw/platform/api';
import { Strategy, StressTestAnalysis, CaptivesRun, EndingSurplus } from '../../../api/dtos';
import { RunModel } from '@wtw/platform/api/dtos';
@Component({
  selector: 'app-results',
  templateUrl: './results.component.html'
})
export class ResultsComponent extends Base.ReactiveComponent implements OnInit {
  run: CaptivesRun;
  npvResults: Array<NpvAnalysis> = [];
  evResults: Array<EvAnalysis> = [];
  stressTestResults: Array<StressTestAnalysis> = [];
  endingSurplusResults: Array<EndingSurplus> = [];
  forceRedraw: { value: number };
  private _baseRun: Dto.RunModel;
  constructor(
    private _runService: RunService,
    private _navBarService: NavBarService,
    private _translate: TranslateService,
  ) {
    super();
  }
  ngOnInit() {
    this._subscriptions = [
      this._runService.activeRun.subscribe((r: any) => {
        this._processRun(r);
      }),
      this._runService.currencyConverted.subscribe(r => {
        this._processRun(r);
        this.save();
        this.forceRedraw = { value: Math.random() * 10000 };
      }),
      this._navBarService.downloadReportEvent.subscribe(x => {
        this.downloadReport();
      })
    ];
  }
  downloadReport() {
    console.log('download report');
  }
  applyChange(event: any) {
    this.run.strategies.splice(event.index, 1, event.strategy);
    this._baseRun.data = this.run;
    this._runTrigger2(this._baseRun, event.index);
  }
  save() {
    this._baseRun.data = this.run;
    this._runService.persist(this._baseRun.runId, this.run, this._baseRun.currencyInfo).uiSignal('save').subscribe(x => {
      this._processResults(this.run.strategies);
    });
  }
  private _runTrigger2(r: Dto.RunModel, strategyIndex: number) {
    this._runService.executeTrigger(r.runId, this.run, { number: 2, param: strategyIndex.toString() }, r.currencyInfo)
      .uiSignal('trigger 2')
      .subscribe(x => {
        this.run = x.data;
        this._processResults(x.data.strategies);
      });
  }
  private _processRun(r: RunModel) {
    this._baseRun = r;
    this.run = r.data as CaptivesRun;
    // Initialising the data
    if (this.run.strategies) {
      if (!this.run.strategies[0].results) {
        this._runTrigger2(this._baseRun, 0);
      } else {
        this._processResults(this.run.strategies);
      }
    }
  }
  private _processResults(strategies: Array<Strategy>) {
    this.npvResults = new Array();
    this.evResults = new Array();
    this.endingSurplusResults = new Array();
    this.stressTestResults = new Array();
    const strategyTranslation = this._translate.instant('CAPTIVES.RESULTS.COMMON.STRATEGY');
    const getStrategyName = (strategy: Strategy, index: number) => {
      let name = this._translate.instant('CAPTIVES.RESULTS.COMMON.BASE_STRATEGY');
      if (index > 0) {
        name = strategyTranslation + ' ' + index;
      }
      return name;
    };
    strategies.forEach((strategy, index) => {
      const strategyName = getStrategyName(strategy, index);
      const results = strategy.results;
      this.npvResults.push(Object.assign(results.npvResult, { strategyName }));
      this.evResults.push(Object.assign(results.evaResult, { strategyName }));
      this.endingSurplusResults.push(Object.assign(results.endingSurplus));
      this.stressTestResults.push(Object.assign(results.stressResult));
    });
  }
}

我会尝试在@Input中设置数组(并且仅设置数据,请勿调用addSeries()(。然后实现onChanges,然后在ngOnChanges中调用您的addSeries方法。我认为正在发生的事情是将@Input设置为CTOR链的一部分,但是它在addSeries中返回,因为数据还不存在,并且再也没有被调用。

所以类似:

@Component({
  selector: 'app-stress-test-analysis',
  templateUrl: './stress-test-analysis.component.html'
})
export class StressTestAnalysisComponent extends ReactiveComponent implements OnChanges {
  isExpanded = false;
  showTable = true;
  private results: Array<StressTestAnalysis> = [];
  @ViewChild(SplineChartComponent) public stressSplineChart: SplineChartComponent;
  @Input() results: Array<StressTestAnalysis>;
  public chartSeries: Array<ChartSeries> = [];
  seriesName: string;
  strategyName: string = '';
  constructor(
  ) { super(); }
  ngOnChanges() {
   this.addSeries();
  }
  private addSeries() {
    if (!this.results) {
      return;
    }
    this.results.forEach(element => {
      if (element !== null) {
          this.chartSeries.push({ data: element.graphData, name: element.seriesName, color: element.color });
        //  if (this.stressSplineChart) this.stressSplineChart.redraw();
      }
    });
  }
}

相关内容

最新更新