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