ng2-highcharts chart update after load - highcharts

I'm using angular 2, firebase and ng2-highcharts.
I assign data after I receive them from firebase like so :
this.items = af.database.list('/items');
this.optionsAsync = this.items.map(data => {
this.options.series[0].data = data.map(item => ([item.x, item.y]));
return this.options;
});
Then in my view template I have :
<div [ng2-highcharts]="optionsAsync | async"></div>
This is working fine at first load. But unfortunately when new data are received chart is not updated. Any idea ?

I found a solution by referencing highcharts component with #ViewChild like so :
in component class :
import { ViewChild, Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.css'],
directives: [Ng2Highcharts]
})
export class AppComponent {
#ViewChild(Ng2Highcharts)
chartElement: Ng2Highcharts;
private chartData = {
chart: {
zoomType: 'x'
},
colors: ['rgba(255,0,255,1)'],
title: {
text: 'Items'
},
credits: '',
series: [{
type: 'area',
name: 'Items',
data: []
}]
};
chartData$ = new Subject();
ngOnInit() {
this.items.subscribe((data: any) => {
this.chartData.series[0].data = data.map(item => ([item.x, parseFloat(item.y)]) );
this.chartData$.next(this.chartData);
if(this.chartElement && this.chartElement.chart) {
var serieRef = this.chartElement.chart.series[0];
serieRef.setData(this.chartData.series[0].data);
}
});
}
}

Related

Dynamically Enable/Disable Mat-Selection-List Mat-List-Option

I have the following mat-selection-list. I need it to enable the options in a cascading fashion. i.e. The Second Selection will not be enabled until the First Selection is selected. The Third Selection will not be enabled until the Second Selection is select, etc...
Here is the html code for the list:
<mat-selection-list id='selectedParameters' [(ngModel)]="selectedCriteria">
<mat-list-option *ngFor="let item of incomingParameters" [selected]="item.selected" [value]="item.name"
[disabled]="item.disabled" checkboxPosition="before" (click)="GetChange(item)">
{{item.name}}
</mat-list-option>
</mat-selection-list>
Here is how I populate the List:
if (this.data.criteria.FirstSelection) {
arr.push({
name: 'First Selection',
selected: false,
disabled: 'false',
});
}
if (this.data.criteria.SecondSelection) {
arr.push({
name: 'Second Selection',
selected: false,
disabled: 'true',
});
}
if (this.data.criteria.ThirdSelection) {
arr.push({
name: 'Third Selection',
selected: false,
disabled: 'true',
});
}
if (this.data.criteria.FourthSelection) {
arr.push({
name: 'Fourth Selection',
selected: false,
disabled: 'true',
});
}
if (this.data.criteria.FifthSelection) {
arr.push({
name: 'Fifth Selection',
selected: false,
disabled: 'true',
});
}
if (this.data.criteria.Sixth Selection) {
arr.push({
name: 'Sixth Selection',
selected: false,
disabled: 'true',
});
}
How can I cascade the enabling/disabling of the options?
Nice question, here is my solution, get the length of the selected array and enable those that are less than the value!
html
<h1 class="mat-headline">MatSelectionList</h1>
<h2 class="mat-subheading-1">Input compareWith is not triggered</h2>
<mat-selection-list
#matSelectionList
[compareWith]="compareServiceTypes"
[(ngModel)]="data"
(ngModelChange)="uncheck($event)"
multiple
>
<mat-list-option
checkboxPosition="before"
[value]="s.id"
[selected]="data.includes(s.id)"
*ngFor="let s of serviceTypes; trackBy: s?.id; let i = index"
[disabled]="i > getMax()"
>
{{ s.label }}
</mat-list-option>
</mat-selection-list>
{{ data | json }}
<div class="mat-small material-version">
#angular/material: {{ version.full }}
</div>
ts
import { ViewChild } from '#angular/core';
import { Component } from '#angular/core';
import { MatSelectionList, VERSION } from '#angular/material';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
#ViewChild('matSelectionList') matSelectionList: MatSelectionList;
version: any;
data: any;
serviceTypes = [];
constructor() {
this.version = VERSION;
this.data = [];
setTimeout(() => {
this.serviceTypes = [
{
id: 1,
label: 'Service type 1',
},
{
id: 2,
label: 'Service type 2',
},
{
id: 3,
label: 'Service type 2',
},
{
id: 4,
label: 'Service type 2',
},
{
id: 5,
label: 'Service type 2',
},
];
}, 1000);
}
uncheck(value) {
let found = null;
this.serviceTypes.forEach((item, index) => {
if (
(this.data[index] || this.data[index] === 0) &&
item.id !== this.data[index] &&
!(found || found === 0)
) {
found = index;
}
});
if (found || found === 0) {
this.data.splice(found);
}
}
getMax() {
return this.data.length;
}
compareServiceTypes(st1: any, st2: any) {
console.log('compareServiceTypes');
// const result = st1 && st2 ? st1.id === st2.id : st1 === st2;
return st1 && st2 ? st1.id === st2.id : st1 === st2;
}
}
stackblitz

Edit is not enabled for custom datepicker control in angular

I created an angular material custom date picker control, it is working and able select and update the date but when I tried to edit the input box it was not allowed. always it is readonly
Below is the code for reference. Can someone suggest this?
import { Component, EventEmitter, forwardRef, Input, OnInit, Output } from '#angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor} from '#angular/forms';
import { MatDatepickerInputEvent } from '#angular/material/datepicker';
import { formatDate } from '#angular/common';
import { DateAdapter, MAT_DATE_FORMATS, NativeDateAdapter } from '#angular/material/core';
type Value=number;
export const PICK_FORMATS = {
parse: {dateInput: {month: 'short', year: 'numeric', day: 'numeric'}},
display: {
dateInput: 'input',
monthYearLabel: {year: 'numeric', month: 'short'},
dateA11yLabel: {year: 'numeric', month: 'long', day: 'numeric'},
monthYearA11yLabel: {year: 'numeric', month: 'long'}
}
};
class PickDateAdapter extends NativeDateAdapter {
format(date: Date, displayFormat: Object): string {
if (displayFormat === 'input') {
return formatDate(date,'MM/dd/yyyy',this.locale);;
} else {
return date.toDateString();
}
}
}
#Component({
selector: 'app-date',
templateUrl: './date.component.html',
styleUrls: ['./date.component.css'],
providers:[
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(()=>DateComponent),
multi:true
},
{provide: DateAdapter, useClass: PickDateAdapter},
{provide: MAT_DATE_FORMATS, useValue: PICK_FORMATS}
]
})
export class DateComponent implements OnInit,ControlValueAccessor {
value: Value;
isDisable:boolean;
#Input() placeholder:string;
#Input() min: Date;
#Input() max:Date;
#Output() changed = new EventEmitter<Value>();
constructor() { }
ngOnInit(): void {
}
get inputValue():Date{
return this.value ? new Date(this.value):null;
}
private propagateChange: any = () =>{ };
private propagateTouched: any = () =>{ };
writeValue(value: Value): void {
this.value=value
}
registerOnChange(fn: any): void {
this.propagateChange=fn;
}
registerOnTouched(fn: any): void {
this.propagateTouched=fn;
}
setDisabledState(isDisabled: boolean): void {
this.isDisable=isDisabled;
}
onChanged( event:MatDatepickerInputEvent<Date>):void{
const value=event.value ? event.value.getTime():null;
this.value=value;
this.propagateChange(value);
this.changed.emit(value);
}
OnClosed():void{
this.propagateTouched();
}
}
// Custome Control HTML
<div>
<input type="text"
[matDatepicker]="picker"
(dateChange)="onChanged($event)"
(click)="picker.open()"
[attr.disabled]="isDisable ? true : null"
[value]="inputValue" [min]="min" [max]="max"
placeholder="{{placeholder || 'Choose a date '}}"
>
<mat-datepicker-toggle matSuffix [for]="picker" [disabled]="isDisable"></mat-datepicker-toggle>
<mat-datepicker #picker (closed)="OnClosed()"></mat-datepicker>
</div>
//custom field
<app-date formControlName="Activedate" placeholder="Date" ></app-date>
I created an angular material custom date picker control, it is working and able select and update the date but when I tried to edit the input box it was not allowed. always it is readonly
Below is the code for reference. Can someone suggest this?
Thanks in advance

How to create packedbubble with HighchartsReact

I am trying to use something like that :
If you can give me working example with react and packedbubble it will be very helpful.
the issue that I am using react and trying to do something like:
constructor(props) {
super(props);
this.state = {
options: {
title: {
text: 'My chart'
},
series: [{
data: [1, 2, 3]
}]
}
}
}
render() {
return (
<HighchartsReact highcharts = {Highcharts} options={this.state.options}/>
);
}
To create packedbubble you have to load highcharts-more module:
require("highcharts/highcharts-more")(Highcharts);
Demo:
https://codesandbox.io/s/highcharts-react-demo-8pkxr

How to use candlestick highchart in Angular2?

I am looking for Highcharts (highcharts.com) CandleSticks example with Angular2.
Could anyone explain or provide sample on how to use it in Angular2 RC with typescript?
Cheers
Sanket
Here is sample example
import { Component } from '#angular/core';
import {JSONP_PROVIDERS, Jsonp} from '#angular/http';
import { CHART_DIRECTIVES } from 'angular2-highcharts';
#Component({
selector: 'high-chart',
directives: [CHART_DIRECTIVES],
providers: [JSONP_PROVIDERS],
template: `
<h2> This is HighChart CandleStick component </h2>
<chart type="StockChart" [options]="options3"></chart>
`
})
export class HighChartsComponent {
options3: Object;
constructor(jsonp : Jsonp) {
jsonp.request('https://www.highcharts.com/samples/data/jsonp.php?a=e&filename=aapl-ohlc.json&callback=JSONP_CALLBACK').subscribe(res => {
this.options3 = {
title : { text : 'CandleSticks' },
rangeSelector : {
selected : 1
},
series : [{
type : 'candlestick',
name : 'CandleSticks',
data : res.json(),
dataGrouping : {
units : [
[
'week', // unit name
[1] // allowed multiples
], [
'month',
[1, 2, 3, 4, 6]
]
]
},
tooltip: {
valueDecimals: 2
}
}]
};
});
}

Trouble with integrating ng2-highcharts

I am trying to use ng2-highcharts in my application. But after importing the necessary classes using the statement
import {Ng2Highcharts, Ng2Highmaps, Ng2Highstocks} from 'ng2-highcharts/ng2-highcharts';**
if I try to specify these classes in the array of directives in my component (directives: [Ng2Highcharts]), I am getting the following error in my console.
[TypeError: require is not a function][1]
My System.config looks as follows
System.config
Can someone tell me what I am missing here ?
You need to define 'ng2-highchart' within your SystemJS configuration:
<script>
System.config({
map: {
'ng2-highchart': 'node_modules/ng2-highchart'
},
(...)
});
</script>
See this question for more details:
How to use highcharts with angular 2?
Here is my candlestick sample... see if this helps.
import { Component } from '#angular/core';
import {JSONP_PROVIDERS, Jsonp} from '#angular/http';
import { CHART_DIRECTIVES } from 'angular2-highcharts';
#Component({
selector: 'high-chart',
directives: [CHART_DIRECTIVES],
providers: [JSONP_PROVIDERS],
template: `
<h2> This is HighChart CandleStick component </h2>
<chart type="StockChart" [options]="options3"></chart>
`
})
export class HighChartsComponent {
options3: Object;
constructor(jsonp : Jsonp) {
jsonp.request('https://www.highcharts.com/samples/data/jsonp.php?a=e&filename=aapl-ohlc.json&callback=JSONP_CALLBACK').subscribe(res => {
this.options3 = {
title : { text : 'CandleSticks' },
rangeSelector : {
selected : 1
},
series : [{
type : 'candlestick',
name : 'CandleSticks',
data : res.json(),
dataGrouping : {
units : [
[
'week', // unit name
[1] // allowed multiples
], [
'month',
[1, 2, 3, 4, 6]
]
]
},
tooltip: {
valueDecimals: 2
}
}]
};
});
}
Remove format: 'register' from you packages. This will help it detect the right format. Or you can add the format as follows:
System.config({
packages: {
app: {
format: 'register',
defaultExtension: 'js'
},
"node_modules/ng2-highcharts": {
format: 'cjs',
defaultExtension: 'js'
}
},
map: {
"ng2-highcharts/ng2-highcharts" : "node_modules/ng2-highcharts/ng2-highcharts"
},
paths: {
"ng2-highcharts/ng2-highcharts" : "node_modules/ng2-highcharts/ng2-highcharts"
}
});

Resources