0

I am using this npm package to make charts: https://www.npmjs.com/package/angular-highcharts

I have an interface and I want to take values from the interface to populate the chart. At this stage all I want is a line graph.

I tried various ways of doing this with arrays, and so long as I initialise the array by hard-coding all the values it works fine, but I would like to dynamically load values from a service into an interface, then take the values from the interface into the chart. What am I doing wrong?

Here is my component.ts

import { Component, OnInit } from '@angular/core';
import { Chart } from 'angular-highcharts';
import { WeatherstatsService } from '../weatherstats.service';
import 'rxjs/add/operator/map';

interface WeatherData {
  id: any;
  year: any;
  measurement_type: string;
  location: string;
  month_or_season: string;
  value?: any;
}

let datavalues: WeatherData [] = [];

@Component({
  selector: 'weatherchart',
  templateUrl: './weatherchart.component.html',
  styleUrls: ['./weatherchart.component.css']
})
export class WeatherchartComponent implements OnInit {

  constructor(private weatherstatsservice: WeatherstatsService) { }



  title = "Title";
  data: any;
  datavalues = datavalues;
  values: Array<number> = [];


  chart = new Chart({
        chart: {
          type: 'line'
        },
        title: {
          text: this.title,
        },
        credits: {
          enabled: false
        },
        series: [{
          name: 'Line 1',
          data: this.datavalues.year,
        }]
      });

    // add point to chart serie
    add() {
      this.chart.addPoint(Math.floor(Math.random() * 10));
    }

    ngOnInit() {
          this.weatherstatsservice.getWeatherData()
            .subscribe(data => {
              this.data = data.slice(0, 100);
             if(this.data){
              this.data.forEach( res => {
                this.datavalues.push({
                  id: res.id,
                  year: res.year,
                  measurement_type: res.measurement_type,
                  location: res.location,
                  month_or_season: res.month_or_season,
                  value: res.value,
                })
               });
               console.log(this.datavalues);

            }
        })
      }


    }
Davtho1983
  • 3,827
  • 8
  • 54
  • 105
  • Probably your data set is not matching – Sajeetharan Dec 01 '17 at 15:58
  • When I log it to the console there's no problem - data fits perfectly – Davtho1983 Dec 01 '17 at 15:59
  • 1
    I think it's a common issue with the library, i faced the same issue with ng2-charts and can be solved by redraw it using the API. – Sajeetharan Dec 01 '17 at 16:00
  • I'm afraid I have no clue how to do that - I'm pretty new to angular – Davtho1983 Dec 01 '17 at 16:05
  • This is how the library is intended to work. You can either pass in the chart options with data when it renders, or you can pass in the options then add the data to the chart. If you do option 2 you will have call a redraw method so highcharts know to update the chart. In other words highcharts isn't watching for data changes, you have to manually tell it to update. – LLai Dec 01 '17 at 16:38
  • did it help and sorted? – Sajeetharan Dec 01 '17 at 16:45
  • Honestly, I got frustrated with highcharts so I switched to ng2-charts. I'm still pretty confused about how to put this.datavalues.value into the chart tho – Davtho1983 Dec 01 '17 at 16:50
  • You can do what Sajeetharan posted, but you need to pass in an array that highcharts can read. That array should look like one of these [formats](https://api.highcharts.com/highcharts/series.line.data) – LLai Dec 01 '17 at 17:08
  • But I don't know how to convert the array in my interface to an array in that format. It seems like this.datavalues.value should be an array of just the value field of my interface? And what Sajeetharan posted seems to be about ng2-charts not highcharts. I don't really know how to apply what he's suggesting. – Davtho1983 Dec 01 '17 at 17:22
  • You can find what Sajeetharan is suggesting in the [angular2-highcharts github](https://github.com/gevgeny/angular2-highcharts#dynamic-interaction-with-chart-object). To transform your array you can do something like `let data = this.dataValues.map(item => item.value)` This will give you something like `[1, 2, 3]`. Now you can pass it in as Sajeetharan suggested `this.chart.series[0].setData(data)`. – LLai Dec 01 '17 at 17:29
  • When you do `this.datavalues.value` you are trying to access the array with a key (in your case `.value`), however arrays can not be accessed this way. You must iterate through the array and get `value` from each iteration. Hence `.map()` – LLai Dec 01 '17 at 17:32

1 Answers1

0

It's common issue with the library, i faced the same issue with ng2-charts and can be solved by redraw it using the API.

You can do it by passing the instance of the chart as,

<chart [options]="options" (load)="saveInstance($event.context)"></chart>

and in TS

chart: Object;
saveInstance(chartInstance): void {
     this.chart = chartInstance;
}

and when you get the data from the API, you can redraw as

updateSeries(data: Array<any>): void {
   this.chart.series[0].setData(data);
}
Sajeetharan
  • 216,225
  • 63
  • 350
  • 396