我是Angular的新手,我想开发一个漏斗图。我喜欢funnel-graph-js库。我尝试了很多,但没有成功。
这是我的funnel-graph-directive.ts
import { Directive, ElementRef } from '@angular/core';
// import * as graph from '../../../assets/js/funnel-graph.js';
import * as graph from 'funnel-graph-js/dist/js/funnel-graph.js';
var graph = new FunnelGraph({
container: '.funnel',
gradientDirection: 'horizontal',
data: {
labels: ['Impressions', 'Add To Cart', 'Buy'],
subLabels: ['Direct', 'Social Media', 'Ads'],
colors: [
['#FFB178', '#FF78B1', '#FF3C8E'],
['#A0BBFF', '#EC77FF'],
['#A0F9FF', '#7795FF']
],
values: [
[3500, 2500, 6500],
[3300, 1400, 1000],
[600, 200, 130]
]
},
displayPercent: true,
direction: 'horizontal'
});
graph.draw();
@Directive({
selector: '[appFunnelGraph]'
})
export class FunnelGraphDirective {
style: any;
constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = 'yellow';
}
}
我已在我的angular.json
"styles": [
"src/styles.scss",
"./node_modules/funnel-graph-js/dist/css/main.css",
"./node_modules/funnel-graph-js/dist/css/theme.css"
],
"scripts": [
"./node_modules/funnel-graph-js/dist/js/funnel-graph.js"
]
答案 0 :(得分:2)
只要您在html中链接了javascript文件,它就可以正常工作。
编辑:
包含附加的javascript文件的一种更好的方法是将其放入 angular.json 文件的“脚本”部分。您也可以添加
declare const FunnelGraph: any
以便编译没有错误。取自an answer to a stackoverflow question和this guide。记住也要在该json中包含css文件!
编辑结束
您会收到此错误,因为代码试图使用名为“ funnel”的类查找HTML元素,但找不到它。由于这是一条指令,因此如果将其更概括一点会更好。
首先,应该将图形生成代码移到构造函数中,因为这就是指令逻辑所在的位置。为了更好地概括该指令,最好是给该元素一个唯一的ID,然后相应地更改代码。这就是我的方法:
HTML:
<div id="funnel-graph-1" appFunnelGraph></div>
JS:
import { Directive, ElementRef } from '@angular/core';
// It should be fine to just import this in the html with a script tag
// import * as graph from 'funnel-graph-js/dist/js/funnel-graph.js';
@Directive({
selector: '[appFunnelGraph]'
})
export class FunnelGraphDirective {
style: any;
constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = 'yellow';
var graph = new FunnelGraph({
// Generalize the container selector with the element id
container: '#' + el.nativeElement.id,
gradientDirection: 'horizontal',
data: {
labels: ['Impressions', 'Add To Cart', 'Buy'],
subLabels: ['Direct', 'Social Media', 'Ads'],
colors: [
['#FFB178', '#FF78B1', '#FF3C8E'],
['#A0BBFF', '#EC77FF'],
['#A0F9FF', '#7795FF']
],
values: [
[3500, 2500, 6500],
[3300, 1400, 1000],
[600, 200, 130]
]
},
displayPercent: true,
direction: 'horizontal'
});
graph.draw();
}
}
答案 1 :(得分:1)
最后我创建了service
而不是使用directive
方法。
dynamic-script-loader-service
的服务
我的dashboard
模块。dynamic-service-loader.service.service.ts
import { Injectable } from '@angular/core';
interface Scripts {
name: string;
src: string;
}
export const ScriptStore: Scripts[] = [
{ name: 'chartjs', src: 'https://unpkg.com/funnel-graph-js@1.3.9/dist/js/funnel-graph.min.js' },
];
declare var document: any;
@Injectable()
export class DynamicScriptLoaderServiceService {
private scripts: any = {};
constructor() {
ScriptStore.forEach((script: any) => {
this.scripts[script.name] = {
loaded: false,
src: script.src
};
});
}
load(...scripts: string[]) {
const promises: any[] = [];
scripts.forEach((script) => promises.push(this.loadScript(script)));
return Promise.all(promises);
}
loadScript(name: string) {
return new Promise((resolve, reject) => {
if (!this.scripts[name].loaded) {
//load script
let script = document.createElement('script');
script.type = 'text/javascript';
script.src = this.scripts[name].src;
if (script.readyState) { //IE
script.onreadystatechange = () => {
if (script.readyState === 'loaded' || script.readyState === 'complete') {
script.onreadystatechange = null;
this.scripts[name].loaded = true;
resolve({ script: name, loaded: true, status: 'Loaded' });
}
};
} else { //Others
script.onload = () => {
this.scripts[name].loaded = true;
resolve({ script: name, loaded: true, status: 'Loaded' });
};
}
script.onerror = (error: any) => resolve({ script: name, loaded: false, status: 'Loaded' });
document.getElementsByTagName('head')[0].appendChild(script);
} else {
resolve({ script: name, loaded: true, status: 'Already Loaded' });
}
});
}
}
dashboard.component.ts
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { DynamicScriptLoaderServiceService } from '../dynamic-script-loader-service.service';
import * as FunnelGraph from 'funnel-graph-js';
function dashboardFunnel() {
const graph = new FunnelGraph({
container: '.funnel',
// gradientDirection: 'horizontal',
data: {
labels: ['Label 7', 'Label 1', 'Label 2', 'Label 3', 'Label 4', 'Label 5', 'Label 6'],
colors: ['#00A8FF', '#00A8FF', '#00A8FF', '#00A8FF', '#00A8FF', '#00A8FF', '#00A8FF'],
// color: '#00A8FF',
values: [12000, 11000, 10000, 9000, 8000, 7000, 6000]
},
displayPercent: true,
direction: 'horizontal',
});
graph.draw();
}
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class DashboardComponent implements OnInit {
constructor(
private dynamicScriptLoader: DynamicScriptLoaderServiceService
) {}
ngOnInit() {
this.loadScripts();
dashboardFunnel();
}
private loadScripts() {
// You can load multiple scripts by just providing the key as argument into load method of the service
this.dynamicScriptLoader.load('chartjs', 'random-num').then(data => {
// Script Loaded Successfully
}).catch(error => console.log(error));
}
}
在我的
providers
中添加了dashboard.module.ts
providers: [DynamicScriptLoaderServiceService],
在我的
css
中添加了angular.json
"styles": [
"src/styles.scss",
"./node_modules/funnel-graph-js/dist/css/main.css",
"./node_modules/funnel-graph-js/dist/css/theme.css"
],
在div
中为funnel
添加了类dashboard.component.html
<div class="funnel"></div>