I'm using angular 4+ and trying to integrate cesium. I have the globe working, and I'm trying to add overlays that have been built by another dev in pure js. I installed npm angular-cesium to get the map running, and i'm trying to include the js file to manipulate it (the angular-cesium devs said this was possible, but did not explain how)
I put the file globe.js in my component folder, and included it in the component like this:
import { Component, OnInit, ViewEncapsulation } from '#angular/core';
require('./globe.js')
declare var Cesium: any;
#Component({
selector: 'app-globe',
templateUrl: './globe.component.html',
styleUrls: ['./globe.component.css'],
encapsulation: ViewEncapsulation.None
})
export class GlobeComponent implements OnInit {
startup: any;
constructor() {
}
ngOnInit() {
startup()
}
}
it is clear that the globe.js file and function are imported and accessable in my component,
but i'm getting the error
globe.js
Module not found: Error: Can't resolve 'Cesium' in 'globe'
Somehow Cesium is not getting imported to globe. How do I fix this? is this the wrong way to integrate js with cesium angular?
Related
i am building an app with angular but found a problem I don't know how to solve.
I need to import a js script and it has to be imported from the internet. (because these are their rules, so that they can do hotfixes)
The problem is, when I import the script into my index.html I can only use it in js files not in the typescript files. How can i use the libary in my ts files?
I can't install it via npm and i also can't download the file and add it to my project folder.
The libary is the airconsole API (https://developers.airconsole.com/#!/api)
Thanks for your help
it's only add in your component declare var AirConsole to use it, a fool Component
import { Component, VERSION } from '#angular/core';
declare var AirConsole //<--this is the "magic"
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular ' + VERSION.major;
airConsole=new AirConsole() //<--now you can use airConsole in your component
}
Update Well, generally we can use a service to mannage the airConsole, this allow us that all components that inject the service can use the functions,variables,...
Disclamer: I don't know about "AirConsole", so I imagine control it like we can control others .js like Cordova)
As we need that Angular know when a function is executed in .js, our service can be like
import { Injectable,NgZone } from '#angular/core';
declare var AirConsole;
#Injectable({
providedIn: 'root',
})
export class AirConsoleService implements OnInit {
airConsole=new AirConsole()
message:Subject=new Subject<any>();
constructor(private ngZone: NgZone) { }
ngOnInit(){
this.airconsole.onMessage = (from, data)=>{
this.ngZone.run(() => {
this.message.next({from:from,data:data})
});
})
}
message(device:any,message:any){
this.ngZone.run(() => {
this.airConsole.message(device,message);
});
}
}
So, e.g. you can subscribe to airConsoleService.message
Trying to use geomap and build a map of USA that I can colour in based on values, but I can't get the map to draw, but it is there (well, the hook workers and data is put in the DIV, can even see the states, but its 0 size.
Started by installing the library
npm install d3-geomap
Then created an empty new component (TestDraw.component)
Only thing in the html is a div to point d3 to, so my test-draw.componenet.html looks like this
<div class="d3-geomap" id="map"></div>
Moved the USA.json from node modules to assets (so the browser can get hold of the file)
Added the code to draw the map in ngOnInit
import { Component, OnInit } from '#angular/core';
import { select } from 'd3-selection';
import { geomap } from 'd3-geomap';
#Component({
selector: 'app-test-draw',
templateUrl: './test-draw.component.html',
styleUrls: ['./test-draw.component.css']
})
export class TestDrawComponent implements OnInit {
constructor() { }
ngOnInit(): void {
const USAMap=geomap();
USAMap.geofile('/assets/USA.json');
USAMap.scale('1000');
USAMap.draw(select('#map'));
}
}
And added the CSS to the components CSS
#import "../../../node_modules/d3-geomap/dist/d3-geomap.css"
It seems happy, it does not complain about the code, and looking at the SVG object, there is data there and I can see state names. But it looks like it hasn't actually drawn it, or maybe drawn it 1px by 1px.
Any ideas
I want to use jquery and easypiechart js file's functions in typescript.
It doesn't work this way.
How to define these script what i specified in code as typescript ?
index.component.ts
import { Component, OnInit } from '#angular/core';
import * as $ from "../../../../../assets/plugins/jquery/jquery.min.js";
import { easyPieChart } from "../../../../../assets/plugins/easypiechart/jquery.easypiechart.min.js";
// these above 2 js files are defined in angular.json script section
#Component({
selector: 'app-index',
templateUrl: './index.component.html',
styleUrls: ['./index.component.scss']
})
export class IndexComponent implements OnInit {
constructor() {}
ngOnInit() {
//$(function(){
// $('.easypiechart').easyPieChart();
//});
// How to write this above script as typescript ?????????????????????
}
}
From the above question,it looks like jquery.easypiechart.min.js is the one that you need to use in your angular application as external js.
Put the js under assets folder say /assets/js/jquery.easypiechart.min.js
Goto your projects angular.json file and under scripts node of architect node put as an entry in the array.
"scripts": [
"./node_modules/jquery/dist/jquery.min.js",
"./src/assets/js/jquery.easypiechart.min.js" ]
Now you can refer the external js in any of your projects components
declare var $: any;// referencing jQuery library
#Component({
selector: 'app-index',
templateUrl: './index.component.html',
styleUrls: ['./index.component.scss']
})
export class IndexComponent implements OnInit {
constructor() {}
ngOnInit() {
$(document).ready(function () {
//accessing easypiechart.min.js.
$('.easypiechart').easyPieChart();
});
}
}
If you have included them in the scripts or index.html, you don't have to import them to the .TS file again
Use declare instead and it should work
What does 'declare' do in 'export declare class Actions'?
Instead of putting it in asset folder you should use it as node_modules dependency
For easy pie chart run this npm i easy-pie-chart --save & for jquery run npm i jquery
Normally you don't want to use jquery in Angular, because it usually implies to modify directly the DOM, which is a bad practice, but there is the way to do it: https://medium.com/all-is-web/angular-5-using-jquery-plugins-5edf4e642969
If you wanna plot a pie chart or other types of charts, you could use ng2-charts instead, it will allow you to use charts.js with Angular and Typescript.
I have a legacy script that I need to include in my angular application.
The thing about this script is that it relates to a specific component, and it has to be loaded only after the view of the component is loaded.
As for today, I succeeded to include it on OnInit function but sometimes (not always for some reason) the CLI throws an error about it.
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-player-page',
templateUrl: './player-page.component.html',
styleUrls: ['./player-page.component.scss']
})
export class PlayerPageComponent implements OnInit {
public itemId: string;
constructor() {}
ngOnInit() {
//We loading the player srcript on after view is loaded
require('assets/scripts/player/player.js');
}
}
The script assumes that elements in the UI exists and it searches them by the id.
When adding it on top of the page, it doesn't work.
What is the best way to achieve the desired behavior?
There are multiple solutions to this issue.
declare the require const on top of your component
declare const require: any;
import { Component, OnInit } from '#angular/core';
#Component({})
...
use the dynamic import() function from typescript
ngAfterViewInit() {
//We loading the player script on after view is loaded
import('assets/scripts/player/player.js');
}
change the library to only start running after you call a function from the component, this way you can add it to the scripts array of your angular.json
We have some legacy regular HTML5 apps that use our own dataviz module (javascript lib based on d3.js).
We started a new app written in typescript on angluar2 which also need to include the same dataviz component.
I have rewritten the dataviz module as a brand new lib in typescript based on react that nicely fits in the angular2 app. I have taken the rewrite opportunity to better architecture the dataviz module by better centralising generic code and make the web service an angular service based on a new web service typescript class.
The issue I am facing now is that I have the same dataviz module written in two different langages (and tech support) and this situation oblige us to maintain two different sources codes.
In other words, is it possible to inject the typescript version into the legacy HTML5/javascript app?
So far, I imagine I can include the typescript langage straight into the legacy app by using the javascript angular2 has generated.
But how can I address the angular2 decoration command such as #Injectable, #Component, #ViewChild etC. and the imports?
For instance, when I include the js generated file of the following typescript, I got the error TypeError: undefined is not an object (evaluating 'core_1.ViewChild') which appears here :
}; // drawChartTraffic(force)
__decorate([
core_1.ViewChild('chart'),
__metadata('design:type', core_1.ElementRef)
], DatavizComponent.prototype, "chartContainer", void 0);
__decorate([
core_1.Input(),
__metadata('design:type', String)
], DatavizComponent.prototype, "graphId", void 0);
My understanding is that I should include angular2/core and all used libs, which makes no sense because what I want to achieve is simplicity…
Should I turn to iframe inclusion of the Dataviz? Any idea?
The typescript excerpt:
import { Component, OnInit, OnChanges, ViewChild, ElementRef, Input, ViewEncapsulation } from '#angular/core';
import * as d3 from 'd3';
import { Observable } from 'rxjs/Observable';
import { ZEENSMetricsService } from './zeensmetrics.service'
#Component({
selector: 'dataviz-offers-volumes',
templateUrl: 'app/dataviz.component.html',
styleUrls: ['app/dataviz.component.css'],
encapsulation: ViewEncapsulation.None,
providers: [
{provide: 'wsAuthKey', useValue: 'abc'},
{provide: 'wsHost', useValue: 'efg'},
],
})
export class DatavizComponent implements OnInit, OnChanges {
#ViewChild('chart') private chartContainer: ElementRef;
#Input() private graphId:string;
#Input() private wsAuthKey:string;
#Input() private wsHost:string;
#Input() private maxSamples=12;
private graph: any; // chartContainer native element
// …
}
Since your DatavizComponent is a Angular 2 component, you cannot include it in a legacy app without including the whole Angular 2 framework.
So, I think you should split your core Dataviz module as a framework-agnostic library. Put in this lib all the code that is not dependent on Angular. Import this library and encapsulate it in your Angular component.
import {template, styles, Dataviz} from 'my-dataviz-lib';
#Component({
selector: 'dataviz-offers-volumes',
template: template,
styles: styles,
//...
})
export class DatavizComponent implements OnInit, OnChanges {
private viz: Dataviz; // Your library object
// …
}