-
-
Notifications
You must be signed in to change notification settings - Fork 80
Expand file tree
/
Copy pathplotly.service.ts
More file actions
148 lines (121 loc) · 4.92 KB
/
Copy pathplotly.service.ts
File metadata and controls
148 lines (121 loc) · 4.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import { Injectable } from '@angular/core';
import { Plotly } from './plotly.interface';
type PlotlyName = 'PlotlyJS' | 'ViaCDN' | 'ViaWindow' | undefined;
@Injectable({
providedIn: 'root'
})
export class PlotlyService {
protected static instances: Plotly.PlotlyHTMLElement[] = [];
public static plotly?: any = undefined;
protected static moduleName?: PlotlyName = undefined;
protected static loadError?: Error;
public static setModuleName(moduleName: PlotlyName): void {
PlotlyService.moduleName = moduleName;
}
public static getModuleName(): PlotlyName {
return PlotlyService.moduleName;
}
public static setPlotly(plotly: any): void {
if (typeof plotly === 'object' && typeof plotly.react !== 'function') {
throw new Error('Invalid plotly.js version. Please, use any version above 1.40.0');
}
PlotlyService.moduleName = 'PlotlyJS';
PlotlyService.plotly = plotly;
PlotlyService.loadError = undefined;
}
public static setPlotlyError(error: Error): void {
PlotlyService.plotly = undefined;
PlotlyService.loadError = error;
}
public static insert(instance: Plotly.PlotlyHTMLElement): Plotly.PlotlyHTMLElement {
const index = PlotlyService.instances.indexOf(instance);
if (index === -1) {
PlotlyService.instances.push(instance);
}
return instance;
}
public static remove(div: Plotly.PlotlyHTMLElement): void {
const index = PlotlyService.instances.indexOf(div);
if (index >= 0) {
PlotlyService.instances.splice(index, 1);
PlotlyService.plotly.purge(div);
}
}
public getInstanceByDivId(id: string): Plotly.PlotlyHTMLElement | undefined {
for (const instance of PlotlyService.instances) {
if (instance && instance.id === id) {
return instance;
}
}
return undefined;
}
public async getPlotly(): Promise<any> {
await this.waitForPlotly();
return this._getPlotly();
}
protected _getPlotly(): any {
if (typeof PlotlyService.plotly === 'undefined') {
const msg = PlotlyService.moduleName === 'ViaCDN'
? `Error loading Peer dependency plotly.js from CDN url`
: `Peer dependency plotly.js isn't installed`;
throw new Error(msg);
}
return PlotlyService.plotly;
}
protected waitFor(fn: () => boolean): Promise<void> {
return new Promise((resolve) => {
const localFn = () => {
if (fn()) {
resolve();
} else {
setTimeout(localFn, 10);
}
};
localFn();
});
}
protected waitForPlotly(): Promise<void> {
return new Promise((resolve, reject) => {
const check = () => {
if (PlotlyService.loadError) {
reject(PlotlyService.loadError);
} else if (PlotlyService.plotly === 'waiting') {
setTimeout(check, 10);
} else {
try {
this._getPlotly();
resolve();
} catch (error) {
reject(error);
}
}
};
check();
});
}
public async newPlot(div: HTMLDivElement, data: Plotly.Data[], layout?: Partial<Plotly.Layout>, config?: Partial<Plotly.Config>, frames?: Partial<Plotly.Config>[]): Promise<any> {
await this.waitForPlotly();
if (frames) {
const obj = { data, layout, config, frames };
return this._getPlotly().newPlot(div, obj).then(() => PlotlyService.insert(div as any)) as Promise<any>;
}
return this._getPlotly().newPlot(div, data, layout, config).then(() => PlotlyService.insert(div as any)) as Promise<any>;
}
public plot(div: Plotly.PlotlyHTMLElement, data: Plotly.Data[], layout?: Partial<Plotly.Layout>, config?: Partial<Plotly.Config>, frames?: Partial<Plotly.Config>[]): Promise<any> {
if (frames) {
const obj = { data, layout, config, frames };
return this._getPlotly().newPlot(div, obj) as Promise<any>;
}
return this._getPlotly().newPlot(div, data, layout, config) as Promise<any>;
}
public update(div: Plotly.PlotlyHTMLElement, data: Plotly.Data[], layout?: Partial<Plotly.Layout>, config?: Partial<Plotly.Config>, frames?: Partial<Plotly.Config>[]): Promise<any> {
if (frames) {
const obj = { data, layout, config, frames };
return this._getPlotly().react(div, obj) as Promise<any>;
}
return this._getPlotly().react(div, data, layout, config) as Promise<any>;
}
public resize(div: Plotly.PlotlyHTMLElement): void {
return this._getPlotly().Plots.resize(div);
}
}