AMcharts Map in angular js - angularjs

I am currently working on AM Charts Maps. I want to implement below link in angularjs. How do I convert into angular js? Should i have to implement directive?
link
<div id="chartdiv"></div>

You can add the following files for the component.
map.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './map.component.html',
styleUrls: ['./map.component.css']
})
export class MapComponent {
private id = "mapdiv";
private options;
makeChartConfig() {
return {
"type": "map",
"theme": "light",
"colorSteps": 10,
"dataProvider": {
"map": "indiaLow",
"areas": [{
"id": "IN-AN",
"value": 4447100
}, {
"id": "IN-AP",
"value": 626932
}, {
"id": "IN-KA",
"value": 5130632
}]
},
"areasSettings": {
"autoZoom": true
},
"valueLegend": {
"right": 10,
"minValue": "little",
"maxValue": "a lot!"
}
};
}
ngOnInit() {
this.options = this.makeChartConfig();
}
}
map.component.html
<amCharts [id]="id" [options]="options" [style.width.%]="100" [style.height.px]="500"></amCharts>

Related

How to convert API Object to Array

I stuck with this error ERROR Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.
I am trying to fetch data from API but it's showing me this error, as I am still learning angular please guide me on how to tackle this kind of errors.
metadata-service.service.ts
import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs';
import { Pincodes } from 'src/app/Model/Pincodes';
import { baseURL } from 'src/environments/environment';
#Injectable({
providedIn: 'root'
})
export class MetadataServiceService {
constructor(private http:HttpClient) { }
public GetPincodes() : Observable<any> {
console.log("Calling GetPincodes API")
return this.http.get("/Metadata/api/metadata/getpincodes") // My API Link
}
}
API consist of the following data
{
"program": null,
"version": null,
"dateTime": null,
"success": true,
"errorCode": null,
"errorMessage": null,
"message": "Pincodes read Successfully",
"data": [
{
"pincode": 400708,
"village": "Airoli",
"taluka": "Thane",
"district": "Thane",
"state": "Maharashtra"
},
{
"pincode": 416007,
"village": "Kaamba",
"taluka": "Kalyan",
"district": "Thane",
"state": "Maharashtra"
},
{
"pincode": 421102,
"village": "Atali",
"taluka": "Kalyan",
"district": "Thane",
"state": "Maharashtra"
},
{
"pincode": 421501,
"village": "Ambarnath",
"taluka": "Ambarnath",
"district": "Thane",
"state": "Maharashtra"
},
{
"pincode": 421503,
"village": "Ambeshiv",
"taluka": "Ambarnath",
"district": "Thane",
"state": "Maharashtra"
}
]
}
I am interested in the data array
Pincode.ts
export class Pincodes {
pincode : number
village : string
taluka : string
district : string
state : string
}
register-page.component.ts
import { Component, OnInit } from '#angular/core';
import { data } from 'jquery';
import { Pincodes } from 'src/app/Model/Pincodes';
import { MetadataServiceService } from 'src/app/shared/services/metadata-service.service';
import { Albums } from "src/app/Model/albums";
import { Observable, of } from 'rxjs';
import {MatTableDataSource, MatTableModule} from '#angular/material/table';
import { report } from 'process';
#Component({
selector: 'app-register-page',
templateUrl: './register-page.component.html',
styleUrls: ['./register-page.component.css']
})
export class RegisterPageComponent implements OnInit {
observeData : Pincodes[]
modifiedText: any;
PinSelected : any = {}
constructor(private _metadataService: MetadataServiceService) { }
ngOnInit(){
this._metadataService.GetPincodes()
.subscribe(data => {
this.observeData = data;
});
}
onPincodeSelected(val : Pincodes){
console.log("value" + val);
this.customFunction(val)
}
customFunction(val : Pincodes){
this.modifiedText = "The Selected Pin was " + val.pincode + " and selected District is " + val.village
console.log("modifiedText" + this.modifiedText);
console.log("Pincode Selected" + this.PinSelected);
console.log("observeData Selected" + this.observeData);
}
}
register-page.component.html
<select
[(ngModel)]="PinSelected"
(ngModelChange)="onPincodeSelected($event)"
>
<option *ngFor="let pin of observeData" [ngValue]="pin">
{{ pin.pincode }}
</option>
</select>
<div>
<p>{{ modifiedText }}</p>
</div>
Error: Cannot find a differ supporting object '[object Object]' of type 'object'.
Try this:
ngOnInit(){
this._metadataService.GetPincodes()
.subscribe(res=> {
this.observeData = res.data;
});
}

Export AmCharts to image/pdf in React application

Working on an application bootstrapped with create-react-app.
I need to export amChart to jpg/png/pdf formats.
I'm trying to export like in this codepen I've found: codepen export amchart example
var chart = AmCharts.makeChart("chart-header", {
"type": "pie",
"theme": "light",
"dataProvider": [ {
"country": "Czech Republic",
"litres": 301.9
}, {
"country": "Austria",
"litres": 128.3
}, {
"country": "UK",
"litres": 99
}, {
"country": "The Netherlands",
"litres": 50
}],
"valueField": "litres",
"titleField": "country",
"export": {
"enabled": true,
"menu": []
}
})
chart["export"].capture({}, function() {
this.toPNG({}, function(base64) {
console.log(base64)
})
})
But it doesn't work in my case. It gives me: Uncaught TypeError: chart.export.capture is not a function all the time.
So.. right or wrong, below is the simplified solution I've found.
On click "export" button, I make this.setState({ shouldExportChart: true }). In the "render" event listener I check whether it's true, if so, perform export and set to false.
In the same way, calling this.toJPG() we can export to JPG format.
For PDF generation I used jspdf, for archiving - jszip.
Dependencies in package.json:
"#amcharts/amcharts3-react": "^3.0.3",
"amcharts3": "^3.21.13",
"amcharts3-export": "github:amcharts/export"
"file-saver": "^1.3.3",
"fabric-webpack": "^1.6.0-rc.1"
Component.jsx:
import 'amcharts3'
import AmCharts from '#amcharts/amcharts3-react'
import 'amcharts3-export'
import 'fabric-webpack'
import FileSaver from 'file-saver'
const chartConfig = {
options: {
...,
"export": {
"enabled": true,
"menu": []
},
"listeners": [
{
event: 'rendered',
method: (e) => {
if (window.fabric) {
e.chart.export.capture({}, function () {
this.toPNG({}, function (base64) {
this.toBlob({
data: base64,
type: 'image/png'
}, (blob) => {
FileSaver.saveAs(blob, 'chart.png')
})
})
})
}
}
}
]
}
}
<AmCharts.React {...chartConfig} />

Can't show data from local json file in browser

I want to show JSON data in browser so that model, provider, storage and condition displays in separate divs.
There is no error in console and i can't figure out where is the problem.
Link updated for stackblitz, kindly have a look into it.
Github Repo
Here is the link for stackblitz.
iphone.json
{
"model": [
"iPhone 5",
"iPhone 5s",
"iPhone SE"
],
"provider": [
"Unlocked",
"AT&T"
],
"storage": [
"16",
"32"
],
"condition": [
"Brand New",
"Mint"
]
}
sell.service.ts
import { Injectable } from '#angular/core';
import { Observable } from "rxjs/Observable";
import { Http, Response } from "#angular/http";
import { HttpClient} from '#angular/common/http';
import "rxjs/add/operator/map";
export interface Staticdata {
model: Array<Model>;
provider: Array<Provider>;
storage: Array<Storage>;
condition: Array<Condition>;
}
export interface Model {
name: string;
}
export interface Provider {
carrier: string;
}
export interface Storage {
size: number;
}
export interface Condition {
quality: string;
}
#Injectable()
export class SellService {
fileUrl = '../static-data/iphone.json';
constructor(public http:HttpClient) {}
getData(){
return this.http.get(this.fileUrl);
}
}
sell-iphone.component.ts
import { Component, OnInit } from '#angular/core';
import { SellService, Staticdata } from "../shared/sell.service";
import * as data from "../static-data/iphone.json";
#Component({
selector: 'app-sell-iphone',
templateUrl: './sell-iphone.component.html',
styleUrls: ['./sell-iphone.component.css'],
providers: [ SellService ]
})
export class SellIphoneComponent implements OnInit {
constructor(public sellService: SellService){
}
ngOnInit() {}
staticData : Staticdata;
showData(){
return this.sellService.getData().subscribe((data: Staticdata) => this.staticData = {
model: data.model,
provider: data.provider,
storage: data.storage,
condition: data.condition
});
}
}
your json must be like:
{
"model": [
{
"name": "iPhone 5"
},
{
"name": "iPhone 5s"
},
{
"name": "iPhone SE"
}
],
"provider": [
{
"carrier": "Unlocked"
},
{
"carrier": "AT&T"
}
],
"storage": [
{
"size": "16"
},
{
"size": "32"
}
],
"condition": [
{
"quality": "Brand New"
},
{
"quality": "Mint"
}
]
}
Or you must transform the data you received. You can do it in the service better than in the component.
getData(){
return this.http.get(this.fileUrl).pipe(map((res:any)=>{
return {
model:res.model.map(m=>{return {name:m}}),
provider:res.provider.map(p=>{return{carrier:p}}),
storage:res.storage.map(s=>{return{size:s}}),
condition:res.condition.map(c=>{return{quality:c}})
}
})
);
}
If you're using angular-cli, you must put your file.json in the folder "assets"

app/mocks.ts(1,2): error TS1109: Expression expected

I'm learning Angular and after some time I've run into this problem with a mocks.ts file:
1) mocks.ts looks like this:
#import { Races } from './races';
export const RACES: Races[] = [{
"id": 1,
"name": "Daytona Thunderdome",
"date": new Date('2512-01-04T14:00:00'),
"about": "Race through the ruins of an ancient Florida battle arena.",
"entryFee": 3200,
"isRacing": false
}, {
"id": 2,
"name": "San Francisco Ruins",
"date": new Date('2512-07-03T20:00:00'),
"about": "Drift down the streets of a city almost sunk under the ocean.",
"entryFee": 4700,
"isRacing": true
}, {
"id": 3,
"name": "New York City Skyline",
"date": new Date('2512-07-12T21:00:00'),
"about": "Fly between buildings in the electronic sky.",
"entryFee": 4300,
"isRacing": true
}];
2)I'm importing Races from races.ts file, which looks like this:
export class Races {
"id": number;
"name": string;
"date": string;
"about": string;
"entryFee": number;
"isRacing": boolean;
}
3) And than I'm importing RACES to races.component.ts, which looks like this:
import { Component } from '#angular/core';
import { Races } from './races';
import { RACES } from './mocks';
#Component({
selector: 'races',
templateUrl: 'app/races.component.html',
styleUrls: ['app/races.component.css']
})
export class RacesComponent {
races: Races[];
cash = 10000;
ngOnInit() {
this.races = RACES;
};
// Write your function here
totalCost() {
var sum = 0;
for(let race of this.races) {
if(race.isRacing) {
sum += race.entryFee;
}
}
return sum;
};
}
Any help is very much appreciated!
Thanks!

Highcharts using Directives in AngularJS

I am new to Angular and just getting used to how everything fits together. I want to display a chart through a directive. This chart will be static data so will neither be dynamically loaded nor updated, it is taken from a JSON.
I have referenced here but the main difference is that I am not loading Highcharts in the view. I am loading it globally in the .js file from my bower_components directory. This is my code:
.js
/* global Highcharts */
angular.module("fusoDataLoggerChart", [])
.controller("fusoDataLoggerChartController", ["$http", "$scope", function($http, $scope) {
"use strict";
$scope.data = {
"activities": [
{},
{},
{
"title": "Engine speed",
"type": "DATA_LOGGER",
"result": {
"Engine speed": {
"data": [
{
"timestamp": 0,
"value": {
"type": "QUANTITY",
"unit": "rpm",
"value": 900
}
},
{
"timestamp": 1000,
"value": {
"type": "QUANTITY",
"unit": "rpm",
"value": 1000
}
},
{
"timestamp": 2000,
"value": {
"type": "QUANTITY",
"unit": "rpm",
"value": 2000
}
}
]
},
"Accelerator pedal position": {
"data": [
{
"timestamp": 0,
"value": {
"type": "QUANTITY",
"unit": "%",
"value": 0
}
},
{
"timestamp": 1000,
"value": {
"type": "QUANTITY",
"unit": "%",
"value": 10.6
}
},
{
"timestamp": 2000,
"value": {
"type": "QUANTITY",
"unit": "%",
"value": 11
}
}
]
}
}
}
]
}
}])
.directive("fusoDataLoggerChart", function() {
"use strict";
return {
scope: {},
restrict: 'E',
link: function(scope) {
scope.dataLoggerData = scope.data["activities"][2]["result"];
scope.timestamps = getData()[0];
scope.engineSpeeds = getData()[1];
scope.pedalPositions = getData()[2];
var chart = new Highcharts.Chart({
chart: {
type: 'line',
animation: false,
renderTo: "DataLoggerChartContainer",
zoomType: 'x'
},
credits: {
enabled: false
},
title: {
text: null
},
xAxis: {
type: "linear",
title: {
text: "Timestamp"
},
min: 0,
categories: scope.timestamps
},
yAxis: [{ //Engine Speed
title: {
text: 'Engine Speed'
},
labels: {
format: '{value} RPM'
},
opposite: true
}, { //Accelerator Pedal Position
title: {
text: 'Accelerator Pedal Position'
},
labels: {
format: '{value} %'
},
min: 0,
max: 100,
// FIXME: 'allowDecimal' may not work
allowDecimal: true
}],
series: [{
name: 'Engine Speed',
type: 'spline',
yAxis: 1,
tooltip: {
valueSuffix: ' RPM'
},
data: scope.engineSpeeds
}, {
name: 'Accelerator Pedal Position',
type: 'spline',
yAxis: 2,
tooltip: {
valueSuffix: ' %'
},
data: scope.pedalPositions
}]
});
function getData() {
var timestamps = [],
engineSpeeds = [],
pedalPositions = [];
var engineSpeedData = scope.dataLoggerData["Engine Speed"]["data"],
pedalPosData = scope.dataLoggerData["Accelerator Pedal Position"]["data"];
for (var i in engineSpeedData) {
timestamps.push(engineSpeedData[i].timestamp);
}
for (var j in engineSpeedData) {
engineSpeeds.push(engineSpeedData[j].value.value);
}
for (var k in pedalPosData) {
pedalPositions.push(pedalPosData[k].value.value);
}
return [timestamps, engineSpeeds, pedalPositions];
}
}
}
});
HTML
<fuso-data-logger-chart>
<div id="DataLoggerChartContainer"></div>
</fuso-data-logger-chart>
When I go to where the chart is to be rendered, nothing is shown (and only the HTML code set manually is displayed with nothing inside when I check in DevTools).
N.B: I realize I do not need the controller yet but it is there as in future the JSON will be got from a rest call from within the controller
Any help appreciated.
This isn't a full answer to your question, but I noticed a way you can make your HTML directive a little cleaner so that you could instead use this format:
<fuso-data-logger-chart></fuso-data-logger-chart>
You don't need the <div id="DataLoggerChartContainer">. You can embed that in the directive definition as a template:
.directive("fusoDataLoggerChart", function() {
"use strict";
return {
scope: {},
restrict: 'E',
transclude: true,
template: '<div id="DataLoggerChartContainer"></div>'
link: function(scope) {
... your other code ...
}
}
});
I have figured out the problem. There were multiple errors but I'll leave this here so maybe someone else can find it useful:
Highcharts and my FusoDataLoggerChart.js were not loaded into index.html (<script src="modules/readVehicleData/FusoDataLoggerChart.js"></script>) meaning that they couldn't be seen by Angular.
In my directive, I was trying to access the local scope (scope.data) in the link() function instead of trying to access the parent scope in the controller where the data is set. To access the parent scope, scope.$parent.data worked for me (N.B: was only 'data' for me as that's the value I set)

Resources