I need to create a geo chart and I have installed the chartjs-chart-geo to implement a chart that simple show the total sales per state.
I got this error when trying to fetch the features from the topojson object and I got stack in here. Can any of you please help me ?
Error:
Property 'features' does not exist on type 'Feature<Point, GeoJsonProperties>'.
Here's my unfinish component code:
import { Component, OnInit } from '#angular/core';
import { DashboardService } from '../../../modules/dashboard.service';
import { Chart, registerables } from 'chart.js';
import { ChoroplethController, GeoFeature, ColorScale, ProjectionScale } from 'chartjs-chart-geo';
import * as ChartGeo from 'chartjs-chart-geo'
import ChartDataLabels from 'chartjs-plugin-datalabels';
// register controller in chart.js and ensure the defaults are set
Chart.register(ChoroplethController, GeoFeature, ColorScale, ProjectionScale);
Chart.register(...registerables);
Chart.register(ChartDataLabels);
// Get the topojson file examples
const url = 'https://unpkg.com/world-atlas#2.0.2/countries-50m.json';
// const url = 'https://unpkg.com/us-atlas/states-10m.json';
#Component({
selector: 'quotes-by-state',
templateUrl: './quotes-by-state.component.html',
styleUrls: ['./quotes-by-state.component.css']
})
export class QuotesByStateComponent implements OnInit {
chart:any;
constructor(private dashService: DashboardService) { }
ngOnInit(): void {
// Prepare chart
this.createChart();
}
// Create chart component
createChart() {
// fetch('https://unpkg.com/us-atlas/states-10m.json').then((r) => r.json()).then((us) => {
// const nation = ChartGeo.topojson.feature(us, us.objects.nation).features[0];
// const states = ChartGeo.topojson.feature(us, us.objects.states).features;
fetch(url).then((result) => result.json()).then((datapoint) => {
// Get ChartGeo features from json
const nation = ChartGeo.topojson.feature(datapoint, datapoint.objects.countries).features;
this.chart = new Chart('geo-chart', {
type: 'choropleth',
data: {
labels: ['a', 'b', 'c'],
datasets: [
{
label: 'Contries',
outline: nation,
data: null, //states.map(country => ({feature: country, value: Math.random() * 100})),
},
]
},
options: {
responsive: true,
}
});
});
}
}
Related
Hi Every one here
I face problem with fetching data to array but when I put data to array the editor said not defined array
Error Message:
Failed to compile.
src/app/customers/customers-list/customers-list.component.ts:111:14 - error TS2551: Property 'CUSTOMERS' does not exist on type 'CustomersListComponent'. Did you mean 'customers$'?
111 this.CUSTOMERS = posts;
~~~~~~~~~
src/app/customers/customers-list/customers-list.component.ts:64:3
64 customers$: Observable<Customer[]>;
~~~~~~~~~~
'customers$' is declared here.
This is the CODE
import {
Component,
OnInit,
PipeTransform, // table
} from '#angular/core';
import { DecimalPipe } from '#angular/common'; // table
import { FormControl } from '#angular/forms'; // table
import { Observable } from 'rxjs'; // table
import { map, startWith } from 'rxjs/operators'; // table
import {NgbModal} from '#ng-bootstrap/ng-bootstrap'; // modal
import {AddCustomerComponent} from '../add-customer/add-customer.component'; // modal
import { faFolderPlus, faPencilAlt, faTrashAlt } from '#fortawesome/free-solid-svg-icons'; // fontawsome icons
import {HttpClient} from '#angular/common/http';
// table
interface Customer {
id: number;
name: string;
company: string;
remaining: number;
email: string;
mobile: number;
whats_up: number;
}
let CUSTOMERS: Customer[] = [
{
id: 12,
name: 'jack',
company: 'SDTE',
remaining: 580,
email: 'test#test.com',
mobile: +456456456456,
whats_up: +456456456
}
];
function search(text: string, pipe: PipeTransform): Customer[] {
return CUSTOMERS.filter(customer => {
const term = text.toLowerCase();
return customer.name.toLowerCase().includes(term)
|| customer.company.toLowerCase().includes(term)
|| pipe.transform(customer.remaining).includes(term)
|| customer.email.toLowerCase().includes(term)
|| pipe.transform(customer.mobile).includes(term)
|| pipe.transform(customer.whats_up).includes(term);
});
}
#Component({
selector: 'app-customers-list',
templateUrl: './customers-list.component.html',
styleUrls: ['./customers-list.component.css'],
providers: [DecimalPipe] // table
})
export class CustomersListComponent implements OnInit {
// table
customers$: Observable<Customer[]>;
filter = new FormControl('');
faFolderPlus = faFolderPlus;
faPencilAlt = faPencilAlt;
faTrashAlt = faTrashAlt;
constructor(
pipe: DecimalPipe, // table
private modalService: NgbModal, // modal
private http: HttpClient // Get All Data
) {
// table
this.customers$ = this.filter.valueChanges.pipe(
startWith(''),
map(text => search(text, pipe))
);
}
ngOnInit(): void {
this.getAllData();
}
// modal
openPopupModal() {
const modalRef = this.modalService.open(AddCustomerComponent,{ centered: true, size: 'lg' });
modalRef.componentInstance.name = 'World';
}
private getAllData() {
this.http
.get('http://localhost:3000/customers')
.subscribe(
posts => {
console.log('GET all Data works');
this.CUSTOMERS = posts; // <<<<< Here is the problem ************ How can I to Fix it.
});
}
}
I
this.CUSTOMERS = posts; this refers to current class CustomersListComponent but your variable is outside the class so you need to assign directly CUSTOMERS = posts; :)
You need to specify the return type.
You could try using this:
private getAllData() {
this.http
.get<Customer[]>('http://localhost:3000/customers') // <<<<< Try using this.
.subscribe(
posts => {
console.log('GET all Data works');
CUSTOMERS = posts;
});
}
I try to make a pie highchart with data from Asp.Net and when i run the program the labels are not distributed individually,i use the same method for data array and i didn't have this issue there.
This is a representation of the graph : https://jsfiddle.net/rk0t4ghc/1/ ,i did the dataLabel array to reproduce the data from Asp.net.
Can you please help me?
import { Component, OnInit, Input } from '#angular/core';
import * as Highcharts from 'highcharts';
import { Order } from 'src/app/shared/order';
import {Customer} from 'src/app/shared/customer';
import {SalesDataService} from '../../services/sales-data.service';
import _ from 'lodash';
#Component({
selector: 'app-pie-chart',
templateUrl: './pie-chart.component.html',
styleUrls: ['./pie-chart.component.css']
})
export class PieChartComponent implements OnInit {
constructor(private _salesDataService:SalesDataService) { }
#Input() inputData:any;
#Input() limit:number;
ngOnInit() {
this.parseChartData(this.inputData,this.limit);
}
parseChartData(res:any,limit? :number){
console.log('response:',res);
const allData=res.slice(0,limit);
console.log('allData(slice):', allData);
Highcharts.chart('container2',{
chart:{
events:{
load(){
const chart=this;
chart.series[0].points.forEach((point)=>
point.update({
name:allData.map(x=>_.values(x)[0])
}),false);
chart.redraw();
}
}
},
tooltip:{
pointFormat: '{name}: <b>{point.percentage:.1f}%</b>'
},
series:[{
type:'pie',
showInLegend:true,
"data":allData.map(x=>_.values(x)[1])
}]
})
}
}
It is happening because you are assigning the entire array as a point name instead of a certain element of the array. (name: array, instead of a name: array[index])
Live demo:
https://jsfiddle.net/BlackLabel/yLfq207n/
load() {
dataLabels=['Name1','Name2','Name3','Name4']
const chart = this;
chart.series[0].points.forEach((point, index) => point.update({
name:dataLabels[index]
}), false);
chart.redraw();
}
I am using Angular 8
where I am facing error - -> ERROR in customer component **Cannot find module 'async_hooks'.**
ERROR in src/app/customer/customer.component.ts:7:27 - error TS2307: Cannot find module 'async_hooks'.
7 import { currentId } from 'async_hooks';
I tried to search on google about this error, But suggestions show the error is more related to Node
Well I tried to import { currentId } from 'async_hooks'; in my module but still showing same error
Just wanted to inform the I am using Angular material table
https://material.angular.io/components/table/overview
I am sharing my customer.component.ts have a look on it
import { Component, OnInit, ViewChild } from '#angular/core';
import { CustomerService } from '../_service/customer/customer.service';
import {MatTableDataSource} from '#angular/material/table';
import {MatPaginator} from '#angular/material/paginator';
import { MatSort } from '#angular/material';
import { trigger, state, transition, style, animate } from '#angular/animations';
import { currentId } from 'async_hooks';
#Component({
selector: 'app-customer',
templateUrl: './customer.component.html',
styleUrls: ['./customer.component.scss'],
animations: [
trigger('detailExpand', [
state('collapsed', style({height: '0px', minHeight: '0'})),
state('expanded', style({height: '*'})),
transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
]),
],
})
export class CustomerComponent implements OnInit {
columnsToDisplay: string[] = ['customerName', 'customerPhone', 'customerEmail', 'created_at'];
dataSource : any;
expandedElement : any;
addCustomer : boolean = false;
ProposalByCustomer : any;
constructor(public rest : CustomerService) { }
ngOnInit(){
this.getCustomer();
}
getCustomer() {
this.rest.getCustomers(localStorage.getItem('currentUser')).subscribe(result => {
console.log(result);
if(result['status'] == 1){
this.dataSource = result['value'];
}
});
}
applyFilter(filterValue: string) {
this.dataSource.filter = filterValue.trim().toLowerCase();
if (this.dataSource.paginator) {
this.dataSource.paginator.firstPage();
}
}
getProposalByCustomer(customer){
console.log(customer);
let token = localStorage.getItem('currentUser');
console.log(token);
let data = {customerId : customer.customerId};
console.log(data);
this.rest.getProposalByCustomer(data , token).subscribe(result => {
console.log(result);
if(result['status'] == 1){
this.ProposalByCustomer = result['data'];
}
})
}
addCustmr() {
this.addCustomer = !this.addCustomer;
}
}
[component.ts]
import { Component, style } from "#angular/core";
import { DataService } from '../data.service';
import d3 = require("d3-3");
import { Data } from "../data";
#Component({
selector: 'ts-graph',
templateUrl: './time-seriesG.component.html',
styles: [`
.graph: {padding-left: 20px !important; }
`]
})
export class timeSeriesComponent {
sym: string[] = [];
price: any[] = [];
tStamp: any[] = [];
data: any[]=[];
arr: any;
constructor(private dataService: DataService) { }
getData() {
let i: number;
this.dataService.getData()
.subscribe(data => {
for(i=0;i<Object.keys(data).length;i++){
this.data.push(data[i])
}
});
}
logV() {
this.arr = this.data.map((d,i) => ({
//time: d.time,
//sym: d.sym,
price: d.price,
index: i
}))
this.arr = this.arr.slice(0,25)
console.log(this.arr.slice(0,25))
}
lineGraph() {
var h=400;
var w=350;
var lineFun = d3.svg.line()
.x(function(d){return d.index*5})
.y(function(d){return d.price})
.interpolate('linear');
var svg = d3.select('div')
.append('svg')
.attr('id','LineGraph')
.attr('width',w)
.attr('height',h);
var viz = svg.append('path')
.attr('d',lineFun(this.arr))
.attr('stroke','white')
.attr('stroke-width',2)
.attr('fill','none');
}
ngOnInit() {
this.getData();
}
}
[component.html]
<h2>Time Series Graph</h2>
<div>{{logV()}}</div>
<div>{{lineGraph()}}</div>
I am trying to get a simple line graph of some data coming from a service. for some reason the svg component is created many times.
Also one of my arrays seems to be initiated many times as well.
I would really appreciate any suggestions, but please keep in mind that I do not have a lot of experience using angular.
The array format:
You call lineGraph from your view here <div>{{lineGraph()}}</div>. So everytime a changedetection is triggered, the function is called, resulting in many, many, many appended svgs.
Just call it once in after the data is received and you should only get one svg.
i,ve been pulling hair with what I tought was going to be a simple code. I admit that i am quite new to typescript and learning as I go but more familiar with javascript.
I am basically creating a SPA (Single Page Application) using AG-GRID as my maine component. I have a service which pulls data from a REST connection (currently using JSON server to mimick that) and will share that data across multiple components. AG-GRID seems to be the only component refusing to work correctly at the moment. I am getting the error below.
Ive been scavaging the internet for solution for a few weeks now but cant find an exmaple that matches my situation. Would anyone here know what to do with the error below?
Console Error:
error TS2345: Argument of type '(data: Incident_Model) => Incident_Model' is not assignable to parameter of type '(value: Incident_Model[]) => void'.
Types of parameters 'data' and 'value' are incompatible.
Type 'Incident_Model[]' is not assignable to type 'Incident_Model'.
Property 'id' is missing in type 'Incident_Model[]'.
Angular interface:
export class Incident_Model {
id: number;
Incident: string;
status: string;
}
Angular service:
import { Injectable } from '#angular/core';
import { environment } from '../../environments/environment';
import { HttpClient } from "#angular/common/http";
import { Observable } from 'rxjs/Observable';
import { Incident_Model } from './incident_model';
const BackEnd_URL = environment.BackEnd_URL;
#Injectable()
export class BackEndService {
constructor(private http: HttpClient ) { }
getAllIncidents(): Observable<Incident_Model[]> {
return this.http.get<Incident_Model[]>(BackEnd_URL + '/Incidents');
}
}
Angular Component:
ngOnInit() {this.backendservice.getAllIncidents().subscribe( data => this.gridOptions.api.setRowData = data )}
Updated with code in comment below - 11h37 - 2018-02-07:
Here is the full component code just in case someone can spot something im missing:
import { Component, OnInit } from '#angular/core';
import { GridOptions } from "ag-grid";
import { BackEndService } from '../../Shared/back-end.service';
import { Incident_Model } from '../../Shared/incident_model';
#Component({
selector: 'app-archive',
templateUrl: './archive.component.html',
styleUrls: ['./archive.component.css']
})
export class ArchiveComponent implements OnInit {
private gridOptions: GridOptions;
constructor(private backendservice: BackEndService) {
var gridSize = 8;
var rowHeight = gridSize * 6;
var headerHeight = gridSize * 7;
this.gridOptions = <GridOptions>{
enableFilter: true,
enableColResize: true,
enableSorting: true,
pagination: true,
paginationPageSize:25,
animateRows: true,
headerHeight: headerHeight,
rowHeight:rowHeight
};
this.gridOptions.columnDefs = [
{
headerName: "Headname here",
children:[
{
headerName: "id",
field: "id",
width: 165,
filterParams: { applyButton: true, clearButton:true }
},
{
headerName: "Incident",
field: "Incident",
width: 450,
filterParams: { applyButton: true, clearButton:true }
},
{
headerName: "status",
field: "status",
width: 110,
filterParams: { applyButton: true, clearButton:true }
}
];
}
ngOnInit() {this.backendservice.getAllIncidents().subscribe(data => this.gridOptions.api.setRowData(data)) }
}
For one, data for should be passed as a parameter instead of an assignement:
this.backendservice.getAllIncidents().subscribe(data => this.gridOptions.api.setRowData(data));