Использовать внешнюю библиотеку JavaScript в приложении Angular 8 - PullRequest
5 голосов
/ 30 сентября 2019

Я новичок в 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"
]

Вот ошибка, которую я получаю enter image description here

Ответы [ 2 ]

2 голосов
/ 01 октября 2019

Пока вы связали файл javascript в html, он будет работать нормально.

РЕДАКТИРОВАТЬ:

Лучший способ добавить файл javascript для добавленияпоместить его в раздел «скрипты» в файле angular.json . Вы также можете добавить

declare const FunnelGraph: any

, чтобы компилировать без ошибок. Это было взято из ответа на вопрос переполнения стека и этого руководства . Не забудьте включить файлы css в этот json!

EDIT END

Вы получаете эту ошибку, потому что код пытается найти элемент HTML с классом с именем "воронка ", но не могу ее найти. Поскольку это директива, было бы лучше, если бы она была немного более обобщенной.

Прежде всего, вам следует переместить код, генерирующий графы, в конструктор, поскольку именно в нем находится логика директивы. Чтобы лучше обобщить эту директиву, было бы лучше, если бы вы дали уникальный идентификатор этому элементу и соответственно изменили код. Вот как я бы это сделал:

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 голос
/ 01 октября 2019

В итоге я создал 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...