Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
图形未使用angular 4正确渲染序列_Angular_Highcharts - Fatal编程技术网

图形未使用angular 4正确渲染序列

图形未使用angular 4正确渲染序列,angular,highcharts,Angular,Highcharts,我用angular 4实现了样条曲线图。我试图在点击按钮时将序列添加到图表中。当用户单击apply按钮时,应向图形中添加一个系列。我遇到的问题是,图形无法刷新以显示添加的序列。用户必须清除浏览器历史记录并重新加载页面才能查看新添加的系列 我在代码中注意到的一个问题是,添加该系列的代码是用OnInit方法编写的,这意味着它只触发了一次。我更改为每次加载页面时都调用它。父组件将结果对象传递给承载图形的子组件。结果组件包含数据和序列对象 我在新代码中遇到的问题是,当用户单击apply按钮时,它会尝试添

我用angular 4实现了样条曲线图。我试图在点击按钮时将序列添加到图表中。当用户单击apply按钮时,应向图形中添加一个系列。我遇到的问题是,图形无法刷新以显示添加的序列。用户必须清除浏览器历史记录并重新加载页面才能查看新添加的系列

我在代码中注意到的一个问题是,添加该系列的代码是用OnInit方法编写的,这意味着它只触发了一次。我更改为每次加载页面时都调用它。父组件将结果对象传递给承载图形的子组件。结果组件包含数据和序列对象

我在新代码中遇到的问题是,当用户单击apply按钮时,它会尝试添加之前添加的相同序列,并将这些序列绑定到图表。因此,图表中会添加重复的序列。有人能告诉我问题出在哪里吗

父组件

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;
  stressTestResults: Array<StressTestAnalysis> = [];
  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.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.stressTestResults.push(results.stressResult);
    });
  }
}
子组件

import { Component, OnInit, Input } from '@angular/core';
import { StressTestAnalysis } from '../../../../api/dtos';
import { ReactiveComponent } from '@wtw/toolkit/src/utils/base.component';

export interface ChartSeries {
  data: number[];
  name: string;
  color: string;
}

export interface YAxisSeries {
  yaxis: number[];
}

@Component({
  selector: 'app-stress-test-analysis',
  templateUrl: './stress-test-analysis.component.html'
})

export class StressTestAnalysisComponent extends ReactiveComponent implements OnInit {
  isExpanded = false;
  showTable = true;
  public chartSeries: Array<ChartSeries> = [];
  yAxisSeries: Array<YAxisSeries> = [];
  yAxisData: number[] = [];
  minYAxis: number;
  maxYAxis: number;
  seriesName: string;
  public results: Array<StressTestAnalysis> = [];
  private _stressResults: Array<StressTestAnalysis> = [];

  @Input() set stressResults(value: Array<StressTestAnalysis>) {
    this.results = value;
    this.addSeries();
    let minY = Math.min(...this.yAxisSeries.map(el => Math.min(...el.yaxis)));
    let maxY = Math.max(...this.yAxisSeries.map(el => Math.max(...el.yaxis)));
    this.generateYAxisArray(minY, maxY);
  }

  constructor( ) { super(); }

  ngOnInit() {
  }

  private addSeries() {
    if (this.results === null) {
      return;
    }


    this.results.forEach(element => {
      if (element.data !== null)
        this.chartSeries.push({ data: element.data, name: element.seriesName, color: element.color });
       if (element.yaxis !== null)
        this.yAxisSeries.push({ yaxis: element.yaxis });
    });
  }

  //Function that generates the array based on the min and max derived from the previous method
  private generateYAxisArray(min: any, max: any) {
    let count = min;
    for (count = min; count <= max; count = count + 500000) {
      this.yAxisData.push(count);
    }
  }


}
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;
        data.series.currentValue.map(s => {
            this.chart.addSeries(s);
        });
        this.chart.reflow();
    }

    redraw() {
        if (!this.chart) return;
        this.chart.yAxis[0].categories = this.yaxisdata;

        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();

    }

}
子组件html

<div class="card">
  <!-- Stress Test Analysis -->
  <div class="card-header" role="tab" id="sta_heading">
    <a data-toggle="collapse" (click)="isExpanded = !isExpanded" href="javascript:void(0);" role="button" [attr.aria-expanded]="isExpanded"
      aria-controls="accordion3" [ngClass]="{'collapsed': !isExpanded}">
      <h5 class="mb-0">{{'CAPTIVES.RESULTS.STA.TITLE'|translate}}</h5>
    </a>
  </div>
  <div [ngClass]="{'show': isExpanded}" id="accordion3" class="collapse" role="tabpanel" aria-labelledby="accordion3_heading"
    data-parent="#accordion" [attr.aria-expanded]="isExpanded">
    <div class="card-body">
      <ul class="nav nav-pills mb-3" id="pills-tab" role="tablist">
        <li class="nav-item">
          <a href="javascript:void(0);" [ngClass]="!showTable ? '' : 'active' " class="nav-link " id="table-tab" data-toggle="pill"
                        role="tab" aria-controls="table" (click)="showTable = !showTable" aria-selected="true">{{'CAPTIVES.RESULTS.COMMON.TABLE'|translate}}</a>
        </li>
        <li class="nav-item">
         <a href="javascript:void(0);" [ngClass]="showTable ? '' : 'active'  " class="nav-link" id="chart-tab" data-toggle="pill"
            role="tab" aria-controls="chart" (click)="showTable = !showTable" aria-selected="false">{{'CAPTIVES.RESULTS.COMMON.CHART'|translate}}</a>
        </li>
      </ul>
      <div class="tab-content" id="pills-tabContent">
        <!-- sta table -->
        <div *ngIf="showTable" class="tab-pane fade show active" id="base-strategy-table--sta" role="tabpanel" aria-labelledby="table-tab">
          <div class="tb-container">
            <div class="tb-row d-flex flex-row">
              <div class="tb-cell col-sm-6 col-md-3 col-lg-2 col-6"></div>
              <div *ngFor="let result of results;" class="tb-cell col-sm-6 col-md-3 col-lg-2 col-6">
                <h6>{{'CAPTIVES.RESULTS.STA.AVERAGE_SURPLUS'|translate}}</h6>
              </div>
            </div>
            <div class="tb-row d-flex flex-row">
              <div class="tb-cell col-sm-6 col-md-3 col-lg-2 col-6">{{'CAPTIVES.RESULTS.STA.CURRENT_LEVEL_CAPTILIZATION'|translate}}</div>
              <div *ngFor="let result of results;" class="tb-cell col-sm-6 col-md-3 col-lg-2 col-6">{{result?.curlevel|percent:'.1-2'}}</div>
            </div>
            <div class="tb-row d-flex flex-row">
              <div class="tb-cell col-sm-6 col-md-3 col-lg-2 col-6">{{'CAPTIVES.RESULTS.STA.TEN_PERCENT_LESS_CURRENT_LEVEL_CAPTILIZATION'|translate}}</div>
              <div *ngFor="let result of results;" class="tb-cell col-sm-6 col-md-3 col-lg-2 col-6">{{result?.decrease|percent:'.1-2'}}</div>
            </div>
            <div class="tb-row d-flex flex-row">
              <div class="tb-cell col-sm-6 col-md-3 col-lg-2 col-6">{{'CAPTIVES.RESULTS.STA.TEN_PERCENT_MORE_CURRENT_LEVEL_CAPTILIZATION'|translate}}</div>
              <div *ngFor="let result of results;" class="tb-cell col-sm-6 col-md-3 col-lg-2 col-6">{{result?.increase|percent:'.1-2'}}</div>
            </div>
          </div>
        </div>
        <!-- sta table End -->
        <!-- sta Chart -->
        <div *ngIf="!showTable" class="tab-pane base-strategy-chart fade show active" id="base-strategy-chart--nva" role="tabpanel"
          aria-labelledby="chart-tab">
          <div class="tb-container">

            <div class="tb-row d-flex flex-row">
              <div class="tb-cell col-12 pt-5">
               <splinechart [series]="chartSeries" [yaxisdata]="yAxisData">
               </splinechart>
                </div>

            </div>
          </div>

          <!-- sta Chart End -->
        </div>
      </div>
    </div>
  </div>
  <!-- Card + Stress Test Analysis End-->
样条图组件

import { Component, OnInit, Input } from '@angular/core';
import { StressTestAnalysis } from '../../../../api/dtos';
import { ReactiveComponent } from '@wtw/toolkit/src/utils/base.component';

export interface ChartSeries {
  data: number[];
  name: string;
  color: string;
}

export interface YAxisSeries {
  yaxis: number[];
}

@Component({
  selector: 'app-stress-test-analysis',
  templateUrl: './stress-test-analysis.component.html'
})

export class StressTestAnalysisComponent extends ReactiveComponent implements OnInit {
  isExpanded = false;
  showTable = true;
  public chartSeries: Array<ChartSeries> = [];
  yAxisSeries: Array<YAxisSeries> = [];
  yAxisData: number[] = [];
  minYAxis: number;
  maxYAxis: number;
  seriesName: string;
  public results: Array<StressTestAnalysis> = [];
  private _stressResults: Array<StressTestAnalysis> = [];

  @Input() set stressResults(value: Array<StressTestAnalysis>) {
    this.results = value;
    this.addSeries();
    let minY = Math.min(...this.yAxisSeries.map(el => Math.min(...el.yaxis)));
    let maxY = Math.max(...this.yAxisSeries.map(el => Math.max(...el.yaxis)));
    this.generateYAxisArray(minY, maxY);
  }

  constructor( ) { super(); }

  ngOnInit() {
  }

  private addSeries() {
    if (this.results === null) {
      return;
    }


    this.results.forEach(element => {
      if (element.data !== null)
        this.chartSeries.push({ data: element.data, name: element.seriesName, color: element.color });
       if (element.yaxis !== null)
        this.yAxisSeries.push({ yaxis: element.yaxis });
    });
  }

  //Function that generates the array based on the min and max derived from the previous method
  private generateYAxisArray(min: any, max: any) {
    let count = min;
    for (count = min; count <= max; count = count + 500000) {
      this.yAxisData.push(count);
    }
  }


}
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;
        data.series.currentValue.map(s => {
            this.chart.addSeries(s);
        });
        this.chart.reflow();
    }

    redraw() {
        if (!this.chart) return;
        this.chart.yAxis[0].categories = this.yaxisdata;

        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();

    }

}
您是否使用任何角度包装的海图?有一个官方的:还有一些非官方的,比如:这些将有助于动态事件,比如添加新系列,以及在角度图中使用一般的高图表

代码this.chart.yAxis[0]。categories=this.yaxisdata;这不好。如果要安全地更新轴的类别,请使用

legendItemClick中的图例项更改可能不起作用-项的状态具有API文档:


如果你能分享stackblitz的演示,我会很高兴。我不确定在stackblitz中模拟这个问题有多容易。在调试过程中,我可以告诉您问题出在子组件中,以下代码被击中两次@Input set stressResultsvalue:Array{this.results=value;this.addSeries;让minY=Math.min…this.yaxisseseries.mapel=>Math.min…el.yaxis;让maxY=Math.max…this.yaxisseseries.mapel=>Math.max…el.yaxis;this.generateyaxisarraryminy,maxY;}我还怀疑这是forloop this.results.foreachement=>{if element.data!==null this.chartSeries.push{data:element.data,name:element.seriesName,color:element.color};if element.yaxis!==null this.yAxisSeries.push{yaxis:element.yaxis};}我应该改用map吗