Highcharts with angular2 and SystemJS Setup - highcharts

had a tough time trying to get ng2-highcharts and angular2 to work nicely together.
what I have is;
import * as Highcharts from 'highcharts';
window['Highcharts'] = Highcharts;
bootstrap(AppComponent);
SystemJS Config;
map: {
"highcharts": "node_modules/highcharts/highcharts.js",
"ng2-highcharts": "node_modules/ng2-highcharts",
}
as you can see, this is quite a hack but its the only way I could get it working - when I remove the manual window assignment, I get
ReferenceError: Highcharts is not defined
at Ng2Highcharts.Object.defineProperty.set
So my question is, surely there is a better way? Any ideas?
I am using it like so;
import { Component, OnInit } from 'angular2/core';
import { Ng2Highcharts } from 'ng2-highcharts/ng2-highcharts';
#Component({
selector: 'component',
styleUrls: ['.comp.css'],
templateUrl: '.comp.html',
directives: [Ng2Highcharts]
})
Thanks

I have slightly modified the original implementation of ng2-highcharts I retreived few months ago to overcome some issues (I had to use jQuery - probably the most current version of the package does not need any twick any more). In any case this is the code of the directive I use
/// <reference path="../../typings/highcharts/highcharts.d.ts" />
declare var jQuery: any;
import {Directive, ElementRef, Input} from 'angular2/core';
#Directive({
selector: '[ng2-highcharts]'
})
export class Ng2Highcharts {
hostElement: ElementRef;
chart: HighchartsChartObject;
constructor(ele: ElementRef) {
this.hostElement = ele;
}
#Input('ng2-highcharts') set options(opt:HighchartsOptions) {
if(!opt) {
console.log('No valid options...');
console.log(opt);
return;
}
if(opt.series || opt.data) {
let nativeEl = this.hostElement.nativeElement;
let jQ = jQuery(nativeEl);
this.chart = jQ.highcharts(opt);
} else {
console.log('No valid options...');
console.dir(opt);
}
}
}
In index.html I have
System.config({
packages: {
app: {
format: 'register',
defaultExtension: 'js'
},
ng2Highcharts: {
format: 'register',
defaultExtension: 'js'
},
.....
.....
}})
and
<script src="./lib/jquery/dist/jquery.js"></script>
<script src="./lib/highcharts/highstock.js"></script>
<script src="./lib/highcharts/modules/exporting.js"></script>
<script src="./lib/highcharts/highcharts-more.js"></script>
In the components that need to use the directive the html code looks like the following:
<div [ng2-highcharts]="chartOptions"></div>
chartOptions are created with code like this
createNewchartOptions() {
return {
title: {text: "Performance vs Benchmark (" + this.periodText + ")"},
rangeSelector: {
selected: 4},
xAxis: {
type: 'datetime'
},
yAxis: {
labels: {
formatter: function () {
return (this.value > 0 ? ' + ' : '') + this.value + '%';}
},
plotLines: [{
value: 0,
width: 2,
color: 'silver'}]
},
plotOptions: {
series: {
compare: 'percent'}
},
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b> ({point.change}%)<br/>',
valueDecimals: 2}
};
}
Last thing you need to do is to set the series in the chartOptions (I do not put code since too linked to my app).
I hope this helps

Related

Type 'number' has no properties in common with type 'XrangePointOptionsObject' [duplicate]

I'm getting this error Type 'number' has no properties in common with type 'XrangePointOptionsObject'. I want to add bar chart using angular highchatrs in my angular project but I'm not able to add because of this error. So can you please help me to solve this error.
Thanks.
this is my component.ts file
import { Chart } from 'angular-highcharts';
import * as Highcharts from 'highcharts'
#Component({
selector: 'app-bar-chart',
templateUrl: './bar-chart.component.html',
styleUrls: ['./bar-chart.component.scss']
})
export class BarChartComponent implements OnInit {
orderChart: Chart;
revenueChart: Chart;
options: Highcharts.Options;
constructor() { }
ngOnInit() {
this.init();
}
init() {
this.options = {
chart: {
type: 'column'
},
title: {
text: 'Total Predected Vs Actual'
},
xAxis:{
categories: ['2010', '2011', '2012', '2013', '2014', '2015', '2016', '2017'],
crosshair: true
},
yAxis : {
min: 0 ,
},
tooltip : {
headerFormat: '<span style = "font-size:10px">{point.key}</span><table>',
pointFormat: '<tr><td style = "color:{series.color};padding:0">{series.name}: </td>' +
'<td style = "padding:0"><b>{point.y:.1f} mm</b></td></tr>', footerFormat: '</table>',
shared: true, useHTML: true
},
plotOptions : {
column: {
pointPadding: 0.2,
borderWidth: 0
}
},
series: [
{
name: "Predected",
data :[14,17,9,10,6,19,6,8]
},
{
name: "Actual",
data: [65,74,44,66,9,23,36,51]
}
]
};
let orderChart = new Chart(this.options);
this.orderChart = orderChart;
let revenueChart = new Chart(this.options);
this.revenueChart = revenueChart;
}
}
so the error is shown on the data in the series.
I was facing the same issue. you need to use following input
[runOutsideAngular]="true"
so it will be
<highcharts-chart [Highcharts]="Highcharts" [options]="chartOptions.trends" [runOutsideAngular]="true"
style="width: 100%; height: 400px; display: block;">
</highcharts-chart>

How to fix this error Type 'number' has no properties in common with type 'XrangePointOptionsObject'

I'm getting this error Type 'number' has no properties in common with type 'XrangePointOptionsObject'. I want to add bar chart using angular highchatrs in my angular project but I'm not able to add because of this error. So can you please help me to solve this error.
Thanks.
this is my component.ts file
import { Chart } from 'angular-highcharts';
import * as Highcharts from 'highcharts'
#Component({
selector: 'app-bar-chart',
templateUrl: './bar-chart.component.html',
styleUrls: ['./bar-chart.component.scss']
})
export class BarChartComponent implements OnInit {
orderChart: Chart;
revenueChart: Chart;
options: Highcharts.Options;
constructor() { }
ngOnInit() {
this.init();
}
init() {
this.options = {
chart: {
type: 'column'
},
title: {
text: 'Total Predected Vs Actual'
},
xAxis:{
categories: ['2010', '2011', '2012', '2013', '2014', '2015', '2016', '2017'],
crosshair: true
},
yAxis : {
min: 0 ,
},
tooltip : {
headerFormat: '<span style = "font-size:10px">{point.key}</span><table>',
pointFormat: '<tr><td style = "color:{series.color};padding:0">{series.name}: </td>' +
'<td style = "padding:0"><b>{point.y:.1f} mm</b></td></tr>', footerFormat: '</table>',
shared: true, useHTML: true
},
plotOptions : {
column: {
pointPadding: 0.2,
borderWidth: 0
}
},
series: [
{
name: "Predected",
data :[14,17,9,10,6,19,6,8]
},
{
name: "Actual",
data: [65,74,44,66,9,23,36,51]
}
]
};
let orderChart = new Chart(this.options);
this.orderChart = orderChart;
let revenueChart = new Chart(this.options);
this.revenueChart = revenueChart;
}
}
so the error is shown on the data in the series.
I was facing the same issue. you need to use following input
[runOutsideAngular]="true"
so it will be
<highcharts-chart [Highcharts]="Highcharts" [options]="chartOptions.trends" [runOutsideAngular]="true"
style="width: 100%; height: 400px; display: block;">
</highcharts-chart>

How to use add series and update methods in the high chart wrapper for angular?

I am using high chart wrapper in my angular5 app with the help of below link.
high chart wrapper
but how can I use addSeries() to add series into the existing chart and how can I update the properties of existing chart.
how can I use addSeries() to add series into the existing chart and
how can I update the properties of existing chart.
When using highcharts-angular wrapper it is not recommended to use chart methods like addSeries() or update() directly on chart reference.
You have to update a whole component, not only chart properties. It can be achieved by updating chartOptions object (add new series, point, title etc) and setting updateFlag = true. Check the code and demo posted below.
app.module.ts:
import { BrowserModule } from "#angular/platform-browser";
import { NgModule } from "#angular/core";
import { HighchartsChartModule } from "highcharts-angular";
import { ChartComponent } from "./chart.component";
import { AppComponent } from "./app.component";
#NgModule({
declarations: [AppComponent, ChartComponent],
imports: [BrowserModule, HighchartsChartModule],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
chart.component.html:
<div class="boxChart__container">
<div>
<highcharts-chart
id="container"
[Highcharts]="Highcharts"
[constructorType]="chartConstructor"
[options]="chartOptions"
[callbackFunction]="chartCallback"
[(update)]="updateFlag"
[oneToOne]="true"
style="width: 100%; height: 400px; display: block;"
>
</highcharts-chart>
<button (click)="updateChart()">Update Chart</button>
</div>
</div>
chart.component.ts:
import { Component, OnInit } from "#angular/core";
import * as Highcharts from "highcharts";
import * as HighchartsMore from "highcharts/highcharts-more";
import * as HighchartsExporting from "highcharts/modules/exporting";
HighchartsMore(Highcharts);
HighchartsExporting(Highcharts);
#Component({
selector: "app-chart",
templateUrl: "./chart.component.html"
})
export class ChartComponent implements OnInit {
title = "app";
chart;
updateFlag = false;
Highcharts = Highcharts;
chartConstructor = "chart";
chartCallback;
chartOptions = {
series: [
{
data: [1, 2, 3, 6, 9]
}
],
exporting: {
enabled: true
},
yAxis: {
allowDecimals: false,
title: {
text: "Data"
}
}
};
constructor() {
const self = this;
this.chartCallback = chart => {
// saving chart reference
self.chart = chart;
};
}
ngOnInit() {}
updateChart() {
const self = this,
chart = this.chart;
chart.showLoading();
setTimeout(() => {
chart.hideLoading();
self.chartOptions.series = [
{
data: [10, 25, 15]
},
{
data: [12, 15, 10]
}
];
self.chartOptions.title = {
text: "Updated title!"
};
self.updateFlag = true;
}, 2000);
}
}
Demo:
https://codesandbox.io/s/oomo7424pz
Docs reference:
updateFlag - https://github.com/highcharts/highcharts-angular#options-details
here is a very useful answer for learning how to updata a highchart.
https://www.highcharts.com/demo/chart-update
it explains a method chart.update
chart.update({
chart: {
inverted: false,
polar: false
},
subtitle: {
text: 'Plain'
}
});
For adding series the following method is used
chart.addSerie(serie,true);
flag 'true' here is equivalent to chart.redraw();
OR
var chart = new Highcharts.Chart(options);
chart.addSeries({
name: array.name,
data: array.value
});
If you are going to add several series you should set the redraw flag to false and then call redraw manually after as that will be much faster.
var chart = new Highcharts.Chart(options);
chart.addSeries({
name: 'Bill',
data: [1,2,4,6]
}, false);
chart.addSeries({
name: 'John',
data: [4,6,4,6]
}, false);
chart.redraw();
For more information and methods you can visit the Official Highcharts API page:
https://api.highcharts.com/class-reference/Highcharts.Chart
When using angular-highcharts wrapper as
import { Chart } from 'angular-highcharts';
create charts as below
chart = new Chart({
chart: {
type: 'line'
},
title: {
text: 'Linechart'
},
credits: {
enabled: false
},
series: [
{
name: 'Line 1',
data: [1, 2, 3]
}
]
});
now you can call all API methods on this

How to set Highcharts options in Angular 5

I tried to set following
Highcharts.setOptions({ lang: { thousandsSep: ',' } });
Trying to set thousand separator as default is space.
Error TS2686: 'Highcharts' refers to a UMD global, but the current
file is a module. Consider adding an import instead.
I am using "highcharts": "^6.1.0".
import {Component, OnInit, ViewEncapsulation,Inject, ViewChild,ElementRef,AfterContentInit, OnDestroy, Input} from '#angular/core';
import { chart } from 'highcharts';
import { Race } from '../../../race';
import { BaseComponent } from '../../../base/base.component';
#Component({
selector: 'nc-mobility',
templateUrl: './mobility.component.html',
styleUrls: ['./mobility.component.css']
})
export class MobilityComponent extends BaseComponent implements OnInit, AfterContentInit, OnDestroy {
#Input() mobility: Array<any>;
// highchart declarations
#ViewChild('mobilityDist') chartTarget: ElementRef;
chart: Highcharts.ChartObject;
constructor() { super(); }
ngOnInit() {
}
ngAfterContentInit() {
const options: Highcharts.Options = {
chart: {
type: 'column'
},
series: this.mobility.map(x => {
return { name: x.name, data: [x.value] };
}),
credits: {
enabled: false
}
};
this.chart = chart(this.chartTarget.nativeElement, options);
}
ngOnDestroy() {
this.chart = null;
}
}
Error occurs because you import only one function from Highcharts, by this:
import { chart } from 'highcharts';
In order to use setOptions, you need to also import this function or import whole Highcharts module, just like that:
import * as Highcharts from 'highcharts';
// import Highcharts
import Highcharts from "highcharts";
//set the options in your constructor
Highcharts.setOptions({
lang: {
thousandsSep: ","
}
});

drag and drop plotline angular2-highcharts typescript

I want to add the drag and drop event functionality to the xAxis plotline in angular2 highcharts. The answer to this question has a good description of how to do it - https://stackoverflow.com/a/18484071/4567096. (http://jsfiddle.net/VXTeR/1/ - link from answer) I am trying to adapt the code to angular2-highcharts. Being a newbie to TS/JS/Angular2, I am not sure what the mistakes are. The code I tried is:
import { Component,OnInit} from '#angular/core';
import { CHART_DIRECTIVES, Highcharts } from 'angular2-highcharts';
#Component({
selector: 'smooth',
directives: [CHART_DIRECTIVES],
template:`<chart [options]="options"></chart>`
})
export class AppSmoothComponent
{options:Object;
line;clickX;clickY;
chart;
ngOnInIt(){
this.dranganddrop(this.chart)
}
dranganddrop=function(chart)
{console.log(chart.xAxis[0].plotLinesAndBands[0]);
this.line=chart.xAxis[0].plotLinesAndBands[0].svgElem.translate(0,0)
.on('mousedown', this.start);
}
start = function (e) {
$(document).bind({
'mousemove.line': this.step,
'mouseup.line': this.stop
});
this.clickX = e.pageX - this.line.translateX;
}
step = function (e) {
this.line.translate(e.pageX - this.clickX, e.pageY - this.clickY)
}
stop = function () {
$(document).unbind('.line');
}
constructor(){
this.options={
xAxis:[{
plotLines:[{value:3,width:6,color:'blue',id:'T1'}],
}],
series:[{
data:[1,2,3,4,5],
allowPointSelect:true
}]
}
}
}
I would appreciate any help in understanding how to make this work or a simpler way to add drag and drop to xAxis plotline.
It might look like:
Template
<chart [options]="options" (load)="load($event.context)"></chart>
Component
export class App {
options = {
xAxis: [{
plotLines: [{ value: 3, width: 6, color: 'blue', id: 'T1' }],
}],
series: [{
data: [1, 2, 3, 4, 5],
allowPointSelect: true
}]
};
line: any;
clickX: any;
start = (e) => {
document.addEventListener('mousemove', this.step);
document.addEventListener('mouseup', this.stop)
this.clickX = e.pageX - this.line.translateX;
}
step = (e) => {
this.line.translate(e.pageX - this.clickX)
}
stop = () => {
document.removeEventListener('mousemove', this.step);
document.removeEventListener('mouseup', this.stop);
}
load(instance) {
this.line = instance.xAxis[0].plotLinesAndBands[0].svgElem
.attr({
stroke: 'yellow'
})
.css({
'cursor': 'pointer'
})
.translate(0, 0)
.on('mousedown', this.start);
}
}
Plunker Example

Resources