1+ import { ModuleWithProviders , NgModule } from '@angular/core' ;
2+ import { CommonModule } from '@angular/common' ;
3+
4+ import { PlotlyService } from './plotly.service' ;
5+ import { PlotlyComponent } from './plotly.component' ;
6+
7+
8+ export type PlotlyBundleName = 'basic' | 'cartesian' | 'geo' | 'gl3d' | 'gl2d' | 'mapbox' | 'finance' ;
9+ export type PlotlyCDNProvider = 'plotly' | 'cloudflare' | 'custom' ;
10+
11+ export interface PlotlyModuleConfig {
12+ bundleName ?: PlotlyBundleName ;
13+ cdnProvider ?: PlotlyCDNProvider ;
14+ version ?: string ;
15+ customUrl ?: string ;
16+ }
17+
18+
19+ @NgModule ( {
20+ imports : [ CommonModule , PlotlyComponent ] ,
21+ providers : [ PlotlyService ] ,
22+ exports : [ PlotlyComponent ] ,
23+ } )
24+ export class PlotlyViaCDNModule {
25+ constructor ( public plotlyService : PlotlyService ) {
26+ PlotlyService . setModuleName ( 'ViaCDN' ) ;
27+ }
28+
29+ public static forRoot ( config : PlotlyModuleConfig ) : ModuleWithProviders < PlotlyViaCDNModule > {
30+ config = Object . assign ( {
31+ bundleName : null ,
32+ cdnProvider : 'plotly' ,
33+ version : 'latest' ,
34+ customUrl : ''
35+ } , config ) ;
36+
37+ let isOk = config . version === 'latest' || / ^ ( s t r i c t - ) ? \d \. \d { 1 , 2 } \. \d { 1 , 2 } $ / . test ( config . version ) ;
38+ if ( ! isOk ) {
39+ throw new Error ( `Invalid plotly version. Please set 'latest' or version number (i.e.: 1.4.3) or strict version number (i.e.: strict-1.4.3)` ) ;
40+ }
41+
42+ const plotlyBundleNames : PlotlyBundleName [ ] = [ 'basic' , 'cartesian' , 'geo' , 'gl3d' , 'gl2d' , 'mapbox' , 'finance' ]
43+ isOk = config . bundleName === null || ! plotlyBundleNames . includes ( config . bundleName ) ;
44+ if ( ! isOk ) {
45+ const names = plotlyBundleNames . map ( n => `"${ n } "` ) . join ( ', ' ) ;
46+ throw new Error ( `Invalid plotly bundle. Please set to null for full or ${ names } for a partial bundle.` ) ;
47+ }
48+
49+ isOk = [ 'plotly' , 'cloudflare' , 'custom' ] . includes ( config . cdnProvider ) ;
50+ if ( ! isOk ) {
51+ throw new Error ( `Invalid CDN provider. Please set to 'plotly', 'cloudflare' or 'custom'.` ) ;
52+ }
53+
54+ if ( config . cdnProvider === 'custom' && ! config . customUrl ) {
55+ throw new Error ( `Invalid or missing CDN URL. Please provide a CDN URL in case of custom provider.` ) ;
56+ }
57+
58+ PlotlyViaCDNModule . loadViaCDN ( config ) ;
59+
60+ return {
61+ ngModule : PlotlyViaCDNModule ,
62+ providers : [ PlotlyService ] ,
63+ } ;
64+ }
65+
66+ public static loadViaCDN ( config : PlotlyModuleConfig ) : void {
67+ PlotlyService . setPlotly ( 'waiting' ) ;
68+
69+ const init = ( ) => {
70+ let src : string = '' ;
71+ switch ( config . cdnProvider ) {
72+ case 'cloudflare' :
73+ if ( config . version == 'latest' ) {
74+ throw new Error ( `As cloudflare hosts version specific files, 'latest' as a version is not supported. Please specify a version or you can choose 'plotly' as a CDN provider.` ) ;
75+ }
76+ src = config . bundleName == null
77+ ? `https://cdnjs.cloudflare.com/ajax/libs/plotly.js/${ config . version } /plotly.min.js`
78+ : `https://cdnjs.cloudflare.com/ajax/libs/plotly.js/${ config . version } /plotly-${ config . bundleName } .min.js` ;
79+ break ;
80+ case 'custom' :
81+ src = config . customUrl ;
82+ break ;
83+ default :
84+ src = config . bundleName == null
85+ ? `https://cdn.plot.ly/plotly-${ config . version } .min.js`
86+ : `https://cdn.plot.ly/plotly-${ config . bundleName } -${ config . version } .min.js` ;
87+ break ;
88+ }
89+
90+ const script : HTMLScriptElement = document . createElement ( 'script' ) ;
91+ script . type = 'text/javascript' ;
92+ script . src = src ;
93+ script . onerror = ( ) => console . error ( `Error loading plotly.js library from ${ src } ` ) ;
94+
95+ const head : HTMLHeadElement = document . getElementsByTagName ( 'head' ) [ 0 ] ;
96+ head . appendChild ( script ) ;
97+
98+ let counter = 200 ; // equivalent of 10 seconds...
99+
100+ const fn = ( ) => {
101+ const plotly = ( window as any ) . Plotly ;
102+ if ( plotly ) {
103+ PlotlyService . setPlotly ( plotly ) ;
104+ } else if ( counter > 0 ) {
105+ counter -- ;
106+ setTimeout ( fn , 50 ) ;
107+ } else {
108+ throw new Error ( `Error loading plotly.js library from ${ src } . Timeout.` ) ;
109+ }
110+ } ;
111+
112+ fn ( ) ;
113+ } ;
114+
115+ setTimeout ( init ) ;
116+ }
117+ }
0 commit comments