简体   繁体   中英

High Charts fails to add series dynamically

I am using HighCharts for the first time and it's proving to be difficult to find sources to help me with this problem.

I am trying to display multiple charts with different numbers of series. Rather than set up multiple options templates I want to use just one and use a function to customize the options object each time. Here I've provided mock data for what one of the charts will look like as received from the API. In the application I plan on feeding it from HTML.

I keep running into various problems due to my lack of understanding of HighCharts, right now I am just going around in circles fixing one problem only for a past problem to pop-up again I was hoping someone can point me in the right direction. This is my Class:

export class CompletenessTabComponent implements OnInit, AfterViewInit {
  @ViewChild('chartTarget') chartTarget: ElementRef;

  chart: Highcharts.ChartObject;

  dataObj = {"id":0,
    "tableName":"d1 vs d2",
    "data":{"d1Count":[50,45,55,60,70],
      "d2Count":[40,32,55,58,33],
      "Errors":[2,3,4,1,0]},
    "dates":[20180927,20180928,20181001,20181002,20181003]
  };

  constructor() { }

  setHighChartOptions(data, seriesNames, chartTitle ): any {
    count = 1;
    highChartOptions.title.text = chartTitle;
    highChartOptions.xAxis.data = data.dates;
    this.chart.series[0].setData(this.dataObj.data[0]);
    Object.keys(data.data).forEach((key) =>
      this.chart.addSeries({
        name: seriesNames[count],
        data: data.data[key],
        type: 'line'
      }) count ++
    );
    return highChartOptions;
  }
  getHighChartOptions(){
    return highChartOptions;
  }
  ngOnInit() {
    this.chart = chart(this.chartTarget.nativeElement, this.setHighChartOptions(this.dataObj, ['d1', 'd2', 'error'], this.dataObj.tableName));
    Object.keys(this.dataObj.data).forEach(key =>
    console.log(key, this.dataObj.data[key]))
  }
  ngAfterViewInit() {
  }

}

const highChartOptions = {
  colors:
    ['#058DC7', '#50B432', '#ED561B', '#DDDF00', '#24CBE5', '#64E572', '#FF9655', '#FFF263', '#6AF9C4'],

  credits: {
    enabled: false
  },
  chart: {
    backgroundColor: null,
  },
  legend: {
    layout: 'vertical',
    align: 'right',
    verticalAlign: 'top',
    itemStyle: {
      fontSize: '10px',
      fontWeight: 'normal'
    }
  },
  tooltip: {
    valuePrefix: '$'
  },
  title: {
    text: ''
  },
  xAxis: {
    type: 'date',
    data: [],
    title: 'date'
  },
  yAxis: {
    title: {
      align: 'middle',
      rotation: 0,
      text: ''
    }
  },
  plotOptions: {
    series: {
      marker: {
        enabled: false
      },
      shadow: false
    }
  },
  series: [{
    type: 'line',
    name: '',
    data: [null]
  }]
};

A few errors I keep receiving are:

in setHighChartOptions() : Cannot read property 'series' of undefined (at, this.chart.series[0]), & cannot read 'keys' of undefined (at the start of the ForEach loop).

I believe the big issue is the chart object is undefined which doesn't make sense since I've instantiated it at the top of the class and then onInit I set the chart options.

I hope you will be able spot my errors and assist me. Thank You.

First of all, you must be careful to use import correctly all js package in your Angular project:

import { chart } from 'highcharts';
import * as Highcharts from 'highcharts';

Also, you must check does your package installed correctly with "npm"?

After all, As my point of view, this example can help you to better understand how to use "highcharts" package in your project, other configs depend on the version of "highcharts" you are using it.

import { Component, ElementRef, ViewChild } from '@angular/core';
import { chart } from 'highcharts';
import * as Highcharts from 'highcharts';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'Highcharts Sample';

  @ViewChild('chartTarget') chartTarget: ElementRef;

  chart: Highcharts.ChartObject;

  ngAfterViewInit() {
    const options: Highcharts.Options = {
      chart: {
        type: 'bar'
      },
      title: {
        text: 'Sample Title'
      },
      xAxis: {
        categories: ['Top Test', 'Test 2', 'Test3']
      },
      yAxis: {
        title: {
          text: 'Fox Rex'
        }
      },
      series: [{
        name: 'Tomi',
        data: [1, 0, 4]
      }, {
        name: 'Alex',
        data: [5, 7, 3]
      }]
    };

    this.chart = chart(this.chartTarget.nativeElement, options);
  }

  addSeries(){
    this.chart.addSeries({
      name:'Test',
      data:[2,3,7]
    })    
  }
}

And HTML template of sample:

<div #chartTarget>
  chart target sample
</div>

Also, you must serve data to highcharts as the format is standard for that, check JSON sample data format in examples in highcharts website.

Most probably, it's because you're trying to refer to series which is not already defined. Actually, if you calling the setHighchartsOptions for a first time, your chart is not defined yet.

In order to make it works, please try to init the chart first (even could be the empty chart, without any data), and then call another methods on Chart object, like addSeries . Something like that, but i didn't saw whole your app, so it's hard to write completely adjusted solution.

ngOnInit() {
    this.chart = chart(this.chartTarget.nativeElement, {});
    this.chart.update(this.setHighChartOptions(this.dataObj, ['d1', 'd2', 'error'], this.dataObj.tableName))
    Object.keys(this.dataObj.data).forEach(key =>
    console.log(key, this.dataObj.data[key]))
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM