I want to create chart based on the JSON data.
I using angular2-highcharts my ChartsMain component looks like:
#Component({
moduleId: module.id,
selector: 'charts',
templateUrl: 'charts.html',
directives: [CHART_DIRECTIVES,]
providers: [DataService]
})
export class ChartsMain {
result: Data[];
constructor(DataService:DataService) {
DataService.getData().subscribe(res => this.result = res);
this.options = {
chart: {
type: "candlestick"
},
title: {
text: "JSON data"
},
xAxis: {
type: "category",
allowDecimals: false,
title: {
text: ""
}
},
yAxis: {
title: {
text: "Number"
}
},
series: [{
name: "Hour",
data: this.result
}]
};
}
options: Object;
And my DataService looks:
#Injectable()
export class DataService {
http: Http;
constructor(http: Http) {
this.http = http;
}
getData(): Observable<Array<Data>> {
return this.http.get('http://JSON-DATA')
.map(this.extractData)
.catch(this.handleError)
}
private extractData(res: Response) {
let body = res.json();
return body || { };
}
private handleError(error: any) {
// In a real world app, we might use a remote logging infrastructure
// We'd also dig deeper into the error to get a better message
let errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Server error';
console.error(errMsg); // log to console instead
return Observable.throw(errMsg);
}
}
My chart
Where is a problem, why is chart empty? How do I fill the chart with JSON data. JSON data must be in any specific format?
A candlestick chart is typically used to present the open, high, low and close price over a period of time..
Sample expected JSON format looks like this-
[
[1250553600000,23.09,23.46,23.06,23.43],
[1250640000000,23.25,23.61,23.21,23.51],
[1250726400000,23.57,23.82,23.52,23.76],
[1250812800000,23.95,24.20,23.83,24.17],
[1251072000000,24.30,24.39,24.04,24.15],
[1251158400000,24.21,24.42,24.16,24.20],
[1251244800000,24.13,24.22,23.82,23.92],
[1251331200000,24.11,24.22,23.55,24.21],
[1251417600000,24.61,24.64,24.08,24.29],
[1251676800000,24.02,24.12,23.79,24.03],
]
Here is sample component with candlestick highchart-
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
}
}]
};
});
}
EDIT:
In your case you are not setting chart options inside subscribe. You should set like this-
this._http.get('http://knowstack.com/webtech/charts_demo/data.json')
.map(this.extractData)
.subscribe((response) => {
this.options = {
title : { text : 'knowstack' },
series : [{
name : 'knowstack',
data : response.json()
}]
};
},
(error) => {
this.errorMessage = <any>error
});
Please note - data from knowstack will only work with simple charts (not candlestick)
EDIT 2: column chart
Please refer below configuration. This is how you can use column chart.
this.options1 = {
title : { text : 'simple column chart' },
series: [{
type : 'column',
data: [["Maths",15],["Physics",16],["Biology",18],["Chemistry",19]]
}]
};
EDIT 3: sample of key-value pair json
import { Component } from '#angular/core';
import { CHART_DIRECTIVES } from 'angular2-highcharts';
#Component({
selector: 'my-app',
directives: [CHART_DIRECTIVES],
styles: [`
chart {
display: block;
}
`]
template: `<chart [options]="options"></chart>`
})
class AppComponent {
constructor() {
var data = [{"key":"Math","value":98},{"key":"Physics","value":78},{"key":"Biology","value":70},{"key":"Chemistry","value":90},{"key":"Literature","value":79}];
this.options = {
title : { text : 'simple chart' },
xAxis: {
type: 'category'
},
series: [{
data: data.map(function (point) {
return [point.key, point.value];
})
}]
};
}
options: Object;
}
Ok it is work. I use service which in my first post, I just changed component: constructor(http: Http, jsonp : Jsonp, DataService:DataService) {
DataService.getData().subscribe(res => this.result = res);
http.request('').subscribe(res => {
this.options = {
chart: {
type: 'column'
},
plotOptions: {
column: {
zones: [{
value: 12,
},{
color: 'red'
}]
}
},
series: [{
data: this.result
}]
};
});
}
options: Object;
in this case json data: [{"key":"Math","value":98},{"key":"Physics","value":78},{"key":"Biology","value":70},{"key":"Chemistry","value":90},{"key":"Literature","value":79}]
How can I split this data like there http://www.knowstack.com/webtech/charts_demo/highchartsdemo4.html
Related
I have a json like this :
[ {
"id": 1,
"libraryName": "lib1",
"bookName": "book1",
"bookPrice": 250.45,
"unitSold": 305
},
{
"id": 2,
"libraryName": "lib1",
"bookName": "book2",
"bookPrice": 450.45,
"unitSold": 150
},
{
"id": 3,
"libraryName": "lib1",
"bookName": "book3",
"bookPrice": 120.25,
"unitSold": 400
}]
I want to recuperate all the bookNames of this json in a list without creating the method getBookNames (because I want a standard way for any field of the json)
So, in the component.ts I used :
sales:any;
getSale () {
this.service.getSales().subscribe(data=> {this.sales = data,
console.log(this.sales.bookName)
})
}
It gives me undefined object in the console ! How can I solve this without creating a method getBookNames() ?
This is my class :
export interface Sale {
id: number
bookname : string
Libraryname: string
Bookprice : number
Unitsold : number
}
This is my service:
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Sale } from './Sale';
#Injectable({
providedIn: 'root'
})
export class MyserviceService {
constructor(private http: HttpClient) { }
getSales () {
return this.http.get<Sale>("http://localhost:8081/sales/all")
}
}
The data obtained from the API is an array. So you could use array map() function to obtain a list of all the properties from the elements. Try the following
sales: any;
unitsSold = [];
getSale () {
this.service.getSales().subscribe(data=> {
this.sales = data,
console.log(data.map(item => item.bookName)); // <-- output: ['book1', 'book2', 'book3'];
console.log(data.map(item => item.id)); // <-- output: [1, 2, 3];
this.unitsSold = data.map(item => item.unitSold); // <-- [305, 150, 400]
});
}
I don't see anything lost here to recuperate.
Im trying to map JSON Data to show it in a Bar-Chart. The final Array I need has to look like this:[883, 5925, 17119, 27114, 2758].
Actually, the Array I want to use to set the barChartData (dringlichkeitenValues[])seems to be empty. Sorry for my bad coding skills. Can anyone show me how to solve this Problem?
JSON:
[{
"id": 1,
"value": 883
},
{
"id": 2,
"value": 5925
},
{
"id": 3,
"value": 17119
},
{
"id": 4,
"value": 27144
},
{
"id": 5,
"value": 2758
}]
api.service.ts
getDringlichkeiten(): Observable<IDringlichkeit[]> {
return this.http.get<IDringlichkeit[]>(this.ROOT_URL + '/aufenthalte/dringlichkeit');}
dringlichkeit.ts
export interface IDringlichkeit {
id: number;
value: number;
}
bar-chart.component.ts
export class BarChartComponent implements OnInit {
public dringlichkeitValues:number[] = [];
public dringlichkeiten: IDringlichkeit[];
public barChartLabels:String[] = ["1", "2", "3", "4", "5"];
public barChartData:number[] = this.dringlichkeitValues;
public barChartType:string = 'bar';
constructor(private aufenthaltService: AufenthaltService) {
}
ngOnInit() {
this.loadData();
this.getDringlichkeitValues();
}
loadData(){
this.aufenthaltService.getDringlichkeiten()
.subscribe( data => this.dringlichkeiten = data);
}
getDringlichkeitValues(){
let dringlichkeitValues:number[]=[];
this.dringlichkeiten.forEach(dringlichkeit=>{
dringlichkeitValues.push(dringlichkeit.value)
this.dringlichkeitValues = dringlichkeitValues;
});
return this.dringlichkeitValues;
}
}
UPDATE:
I updated my component but now my Array is still empty after subscribing to the Observable.
bar-chart.component.ts
chart: Chart;
dringlichkeiten: IDringlichkeit[] = [];
constructor(private aufenthaltService: AufenthaltService) {
}
ngOnInit() {
this.aufenthaltService.getDringlichkeiten()
.subscribe( data => {
this.dringlichkeiten = data;
//dringlichkeiten-Array full
console.log(this.dringlichkeiten);
});
//dringlichkeiten-Array empty
console.log(this.dringlichkeiten);
this.chart = new Chart('canvas', {
type: 'bar',
data: {
labels: this.dringlichkeiten.map(x => x.id),
datasets: [
{
label: 'Dringlichkeiten',
data: this.dringlichkeiten.map(x => x.value),
backgroundColor: ['#FF6384', '#4BC0C0', '#FFCE56', '#E7E9ED', '#36A2EB']
}
]
},
});
}
To get the "values" from your JSON array, you can use:
dringlichkeiten.map(x => x.value)
This will get you an array you require, i.e.:
[883, 5925, 17119, 27114, 2758]
You can then pass this array to chartJS for it to render you a chart like so:
this.chart = new Chart('canvas', {
type: 'bar',
data: {
labels: dringlichkeiten.map(x => x.id),
datasets: [
{
label: 'My Bar Chart',
data: dringlichkeiten.map(x => x.value),
backgroundColor: ['red', 'green', 'yellow', 'blue', 'orange']
}
]
},
});
Take a look at this simplified working SlackBlitz example.
Hope this helps!
I am trying to read json data from a restFul server and populate a smart table with the results. I am stuck and cant seem to find out how to get it to work. It seems I am able to read the Json data from the restFul server but I am not real sure how to load it into the smart-table.
Any help is greatly appreciated!
Here are the parts of the application that are used:
the service (smart-table.service):
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { HttpErrorResponse, HttpResponse } from '#angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';
export interface LCQIWK {
date: Date;
rank: number;
zone: string;
enodeb: string;
market: string;
usid: number;
impact: number;
tnol: number;
ret: number;
acc: number;
irat: number;
tput: number;
rtt: number;
}
const REST_SERVER = 'http://nonprod-hywrca02-zltv3747-0001- ingress.idns.cci.att.com:31840/thor';
// import { LCQIWK } from './models/lcqiwk';
#Injectable()
export class SmartTableService {
constructor(private http: HttpClient) { }
getData() {
return this.http.get<LCQIWK>(REST_SERVER + '/cqi/lte/wk')
.pipe(
retry(3), // retry a failed request up to 3 times
catchError(this.handleError) // then handle the error
);
}
private handleError(error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
// A client-side or network error occurred. Handle it accordingly.
console.error('An error occurred:', error.error.message);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
console.error(
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
}
// return an observable with a user-facing error message
return throwError(
'Something bad happened; please try again later.');
}
}
cqi-table.component
import { Component } from '#angular/core';
import { LocalDataSource } from 'ng2-smart-table';
import { LCQIWK, SmartTableService } from '../../../#core/data/smart-table.service';
// import { LCQIWK } from '../../../#core/data/models/lcqiwk';
#Component({
selector: 'app-cqi-table',
templateUrl: './cqi-table.component.html',
providers: [ SmartTableService ],
styleUrls: ['./cqi-table.component.scss']
})
export class CqiTableComponent {
settings = {
actions: false,
columns: {
date: {
title: 'Date',
type: 'number',
},
rank: {
title: 'Rank',
type: 'string',
},
zone: {
title: 'ZONE',
type: 'string',
},
enodeb: {
title: 'eNodeB',
type: 'string',
},
market: {
title: 'Market',
type: 'string',
},
usid: {
title: 'USID',
type: 'number',
},
impact: {
title: 'Impact',
type: 'number',
},
tnol: {
title: 'TNoL',
type: 'string',
},
ret: {
title: 'RET',
type: 'string',
},
acc: {
title: 'ACC',
type: 'string',
},
irat: {
title: 'IRAT',
type: 'string',
},
tput: {
title: 'TPUT',
type: 'number',
},
rtt: {
title: 'RTT',
type: 'number',
},
},
};
error: any;
headers: string[];
lcqiwk: LCQIWK;
source: LocalDataSource = new LocalDataSource();
constructor(private smartTableService: SmartTableService) {
this.smartTableService.getData()
.subscribe(
(data: LCQIWK) => this.lcqiwk = { ...data }, // success path
// this.source.load(this.lcqiwk),,
error => this.error = error, // error path
);
}
clear() {
this.lcqiwk = undefined;
this.error = undefined;
this.headers = undefined;
}
/* showConfig() {
this.smartTableService.getData()
.subscribe(
(data: LCQIWK) => this.lcqiwk = { ...data }, // success path
// this.source.load(this.lcqiwk),
error => this.error = error // error path
);
} */
}
// this.source.load(data);
Try this way...
this.smartTableService.getData()
.subscribe((data) => {
for (let i = 0; i < data.length; i++) {
data = {
id: (i + 1),
date : data[i].date,
rank : data[i].rank,
zone : data[i].zone,
enodeb : data[i].enodeb,
market : data[i].market,
usid : data[i].usid
// ... Add all data
}
this.source.add(data)
}
this.source.refresh();
});
}
I am new to angular and doing a sample project in which I want to show some JSON data in a grid.
I'm using ag-grid for the same.
I have the following Json response that I'm getting from a rest API :-
[
{
"id": 64,
"name": "Utopia",
"language": "English",
"genres": [
"Drama",
"Science-Fiction",
"Thriller"
],
"status": "Ended",
"image": {
"medium": "http://static.tvmaze.com/uploads/images/medium_portrait/0/474.jpg",
"original": "http://static.tvmaze.com/uploads/images/original_untouched/0/474.jpg"
}
},
{
"id": 65,
"name": "Bones",
"language": "English",
"genres": [
"Drama",
"Crime",
"Medical"
],
"status": "Ended",
"image": {
"medium": "http://static.tvmaze.com/uploads/images/medium_portrait/80/201202.jpg",
"original": "http://static.tvmaze.com/uploads/images/original_untouched/80/201202.jpg"
}
}
]
I was able to successfully bind the data for the simple keys like id, name, language etc. but when it comes to binding the nested object I'm not able to do it.
If you look at the above json response, The 'image' field is an object. How can I get the value of 'medium' or 'original' key from it and just show the image in my row ?
Some help is appreciated, as this is the point I'm getting stuck at.
Below is my component code :-
shows.component.ts
#Component({
selector: 'app-shows',
templateUrl: './shows.component.html',
styleUrls: ['./shows.component.css']
})
export class ShowsComponent implements OnInit {
public gridOptions: GridOptions;
public tvShowsColumnDefs = new ShowColumn;
public showMetaData: any;
constructor(private _contentService: ContentService, private _router: Router,
private _route: ActivatedRoute) {
// GridOptions Initialized
this.gridOptions = <GridOptions>{};
this.gridOptions.columnDefs = this.tvShowsColumnDefs.columnDefs;
}
ngOnInit() {
// Prepare Grid Row Data
this.prepareRowData();
}
prepareRowData() {
// API Call for getting TV-Shows
this._contentService.getAllShows()
.subscribe(response => {
const shows = response;
console.log('TVShows-API Response ', shows);
// Setting Grid RowData using api response
this.gridOptions.api.setRowData(shows);
});
}
show.columnDef.ts
export class ShowColumn {
public columnDefs = [
{ field: 'id', headerName: '', width: 50 },
{ field: 'image', headerName: '', width: 50, cellRendererFramework: null},
{ field: 'name', headerName: '', width: 250},
{ field: 'language', headerName: 'Language', width: 100},
{ field: 'genres', headerName: 'Genres', width: 250},
{ field: 'status', headerName: 'Status', width: 145 }
];
constructor() { }
}
The nested properties are accessible by the dot notation (.), e.g.:
{ field: 'image.medium', headerName: '', width: 50}
For the nested arrays, a value-getter will most likely do the job:
function genreValueGetter(params) {
const arr = params.data.genres as Array<string>;
return arr.join(', ');
}
{ headerName: 'Genres', valueGetter: genreValueGetter, width: 250},
First let me build classes:
export class myShow {
image: myImage;
id: number;
...
constructor(obj: any) {
this.document = new myImage(obj.image);
this.id = obj.id;
...
}
}
export class myImage {
medium: string;
original: string;
constructor(obj?: any) {
if(obj){
this.medium = obj.medium;
this.original = obj.original;
}
}
}
Then you can use .map operator
allShows: myShow[] = [];
prepareRowData(){
this._contentService.getAllShows().map((shows: myShow[])=> {
return shows.map((show: myShow)=>{
return new myShow(show);
})
}).subscribe((allShows)=> {
this.allShows = allShows;
});
}
I have just started working on Angular 4 and I am trying to render some data which I receive from angular service in json format, into angular-datatable, but whichever option i try its not working for me.
The table is coming, the columns are coming, however the data inside the columns are not displaying.
Any help would be great,
Thanks in advance..!!!!
Please find my code below:
component.html
<table datatable [dtOptions]="dtOptions" class="row-border hover"></table>
component.ts
import { Component, OnInit } from '#angular/core';
import { FleetDataService } from '../../services/fleet-data.service';
import { Subject } from 'rxjs/Subject';
#Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.scss']
})
export class DashboardComponent implements OnInit {
private fleetData: any;
dtOptions: DataTables.Settings = {};
dtTrigger: Subject<any> = new Subject();
constructor(private getFleetData:FleetDataService) { }
ngOnInit() {
this.getFleetData.getFleetData().subscribe(
fleetData => {
this.fleetData = fleetData;
console.log(this.fleetData);
this.dtTrigger.next();
},
err => {
console.log(err);
}
);
this.dtOptions = {
pagingType: 'full_numbers',
columns: [{
title: 'First Name',
data: this.fleetData
}, {
title: 'Last Name',
data: this.fleetData
}, {
title: 'Score',
data: this.fleetData
}]
};
}
}
component.service
import { Injectable } from '#angular/core';
import { HttpModule, Http, Response, Headers, RequestOptions } from
'#angular/http';
import { Observable } from 'rxjs/Rx';
#Injectable()
export class FleetDataService {
constructor(private http: Http) { }
getFleetData() {
return this.http.get("../../assets/data/test.json")
.map((res:Response) => res.json())
.catch((error:any) => Observable.throw(error.json().error || 'Server
Error'));
}
}
test.json
[{
"FirstName": "Jill",
"LastName": "Smith",
"Score": "disqualified"
}, {
"FirstName": "Eve",
"LastName": "Jackson",
"Score": "94"
}, {
"FirstName": "John",
"LastName": "Doe",
"Score": "80"
}, {
"FirstName": "Adam",
"LastName": "Johnson",
"Score": "67"
}]
You set your dtOptions outside the subscribe.
If you do this the fleetData stays empty so dtOptions is never set correctly, because an Observable is asynchronous. I propose this code:
export class DashboardComponent implements OnInit {
dtOptions: DataTables.Settings = {};
dtTrigger: Subject<any> = new Subject();
constructor(private getFleetData:FleetDataService) { }
ngOnInit() {
this.getFleetData.getFleetData().subscribe(
fleetData => {
console.log(fleetData);
this.buildDtOptions(fleetData)
this.dtTrigger.next();
},
err => {
console.log(err);
});
}
private buildDtOptions(fleetData: any): void {
this.dtOptions = {
pagingType: 'full_numbers',
columns: [
{title: 'First Name', data: fleetData},
{title: 'Last Name', data: fleetData},
{title: 'Score', data: fleetData}
]
};
}
}
For this error: ERROR TypeError: Cannot read property 'aDataSort' of undefined. You can do a spinner (ngIf / else) in the view and when data are loaded you display the datatable