cordova-plugin-ra-chart 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +543 -0
- package/ionic/index.ts +16 -0
- package/ionic/ra-chart.component.html +15 -0
- package/ionic/ra-chart.component.ts +254 -0
- package/ionic/ra-chart.loader.ts +63 -0
- package/ionic/ra-chart.module.ts +23 -0
- package/ionic/ra-chart.types.ts +136 -0
- package/package.json +54 -0
- package/plugin.xml +45 -0
- package/types/index.d.ts +218 -0
- package/www/ra-chart.css +324 -0
- package/www/ra-chart.js +2838 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef,
|
|
3
|
+
EventEmitter, Inject, Input, NgZone, OnChanges, OnDestroy, Output, SimpleChanges, ViewChild
|
|
4
|
+
} from '@angular/core';
|
|
5
|
+
import { CommonModule } from '@angular/common';
|
|
6
|
+
|
|
7
|
+
import { RA_CHART_SCRIPT_URL, ensureRaChart } from './ra-chart.loader';
|
|
8
|
+
import type {
|
|
9
|
+
RaAnimation, RaBand, RaChartInstance, RaChartOptions, RaChartType,
|
|
10
|
+
RaFieldMap, RaSelectEvent, RaSeries, RaToggleEvent, RaZoomEvent
|
|
11
|
+
} from './ra-chart.types';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* `<ra-chart>` — Ionic/Angular wrapper around the raChart engine.
|
|
15
|
+
*
|
|
16
|
+
* <ra-chart type="column" category="month"
|
|
17
|
+
* [series]="series" [data]="rows" [zoom]="true"
|
|
18
|
+
* (select)="onSelect($event)"></ra-chart>
|
|
19
|
+
*
|
|
20
|
+
* The engine runs entirely outside Angular's zone, so touch scrubbing and
|
|
21
|
+
* entrance animations never trigger change detection. Events are re-entered
|
|
22
|
+
* into the zone before they reach your handlers.
|
|
23
|
+
*/
|
|
24
|
+
@Component({
|
|
25
|
+
selector: 'ra-chart',
|
|
26
|
+
standalone: true,
|
|
27
|
+
imports: [CommonModule],
|
|
28
|
+
templateUrl: './ra-chart.component.html',
|
|
29
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
30
|
+
styles: [`
|
|
31
|
+
:host { display: block; position: relative; }
|
|
32
|
+
:host .ra-chart--busy { display: none; }
|
|
33
|
+
`]
|
|
34
|
+
})
|
|
35
|
+
export class RaChartComponent implements AfterViewInit, OnChanges, OnDestroy {
|
|
36
|
+
@ViewChild('host', { static: true }) hostRef!: ElementRef<HTMLDivElement>;
|
|
37
|
+
|
|
38
|
+
// ---- data ----
|
|
39
|
+
@Input() type: RaChartType = 'column';
|
|
40
|
+
@Input() data: any[] = [];
|
|
41
|
+
@Input() category = 'category';
|
|
42
|
+
@Input() series: RaSeries[] = [];
|
|
43
|
+
@Input() colors: string[] | null = null;
|
|
44
|
+
|
|
45
|
+
// ---- shape ----
|
|
46
|
+
@Input() stacked = false;
|
|
47
|
+
@Input() fullStacked = false;
|
|
48
|
+
@Input() smooth = false;
|
|
49
|
+
@Input() stepped = false;
|
|
50
|
+
@Input() semi = false;
|
|
51
|
+
@Input() depth = 0;
|
|
52
|
+
|
|
53
|
+
// ---- field mapping ----
|
|
54
|
+
@Input() fields: RaFieldMap | null = null;
|
|
55
|
+
@Input() xField = 'x';
|
|
56
|
+
@Input() sizeField = 'size';
|
|
57
|
+
|
|
58
|
+
// ---- scale ----
|
|
59
|
+
@Input() min = 0;
|
|
60
|
+
@Input() max: number | null = null;
|
|
61
|
+
@Input() bands: RaBand[] | null = null;
|
|
62
|
+
@Input() upColor?: string;
|
|
63
|
+
@Input() downColor?: string;
|
|
64
|
+
|
|
65
|
+
// ---- interaction ----
|
|
66
|
+
@Input() zoom = false;
|
|
67
|
+
@Input() pinchZoom = true;
|
|
68
|
+
@Input() legend = true;
|
|
69
|
+
@Input() haptics = true;
|
|
70
|
+
@Input() sheetTooltip: boolean | 'auto' = 'auto';
|
|
71
|
+
@Input() tooltipHold = 2600;
|
|
72
|
+
|
|
73
|
+
// ---- presentation ----
|
|
74
|
+
@Input() height = 260;
|
|
75
|
+
@Input() animation: RaAnimation = { duration: 800, delay: 70 };
|
|
76
|
+
@Input() loading = false;
|
|
77
|
+
@Input() emptyText = 'No data to display';
|
|
78
|
+
@Input() loadingText = 'Loading…';
|
|
79
|
+
|
|
80
|
+
// ---- events ----
|
|
81
|
+
@Output() select = new EventEmitter<RaSelectEvent>();
|
|
82
|
+
@Output() zoomChange = new EventEmitter<RaZoomEvent>();
|
|
83
|
+
@Output() toggle = new EventEmitter<RaToggleEvent>();
|
|
84
|
+
@Output() ready = new EventEmitter<RaChartInstance>();
|
|
85
|
+
|
|
86
|
+
/** Set when the engine script cannot be loaded, so the template can say so. */
|
|
87
|
+
error: string | null = null;
|
|
88
|
+
|
|
89
|
+
private chart: RaChartInstance | null = null;
|
|
90
|
+
private booted = false;
|
|
91
|
+
private listeners: Array<[string, EventListener]> = [];
|
|
92
|
+
|
|
93
|
+
constructor(
|
|
94
|
+
private zone: NgZone,
|
|
95
|
+
private cdr: ChangeDetectorRef,
|
|
96
|
+
@Inject(RA_CHART_SCRIPT_URL) private scriptUrl: string
|
|
97
|
+
) { }
|
|
98
|
+
|
|
99
|
+
/** True when the current type has nothing to draw. */
|
|
100
|
+
get isEmpty(): boolean {
|
|
101
|
+
if (this.loading || this.error) return false;
|
|
102
|
+
if (!this.data || this.data.length === 0) return true;
|
|
103
|
+
// sankey carries its own from/to/value rows; every other type needs a series
|
|
104
|
+
if (this.type === 'sankey') return false;
|
|
105
|
+
return this.series.length === 0;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
ngAfterViewInit(): void {
|
|
109
|
+
this.boot();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
ngOnChanges(changes: SimpleChanges): void {
|
|
113
|
+
if (!this.chart) return;
|
|
114
|
+
|
|
115
|
+
// data-only change on a stable shape → let the engine morph the values
|
|
116
|
+
const keys = Object.keys(changes);
|
|
117
|
+
if (keys.length === 1 && keys[0] === 'data' && !changes['data'].firstChange) {
|
|
118
|
+
if (this.isEmpty) { this.teardownChart(); this.cdr.markForCheck(); return; }
|
|
119
|
+
this.zone.runOutsideAngular(() => this.chart!.setData(this.data || []));
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
if (keys.length === 1 && keys[0] === 'loading') { this.cdr.markForCheck(); return; }
|
|
123
|
+
|
|
124
|
+
if (this.isEmpty) { this.teardownChart(); this.cdr.markForCheck(); return; }
|
|
125
|
+
this.zone.runOutsideAngular(() => this.chart!.update(this.buildOptions()));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
ngOnDestroy(): void {
|
|
129
|
+
this.teardownChart();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// ---------------------------------------------------------------
|
|
133
|
+
// imperative API — grab the component with @ViewChild and call these
|
|
134
|
+
// ---------------------------------------------------------------
|
|
135
|
+
|
|
136
|
+
/** The live engine instance, or null before first render. */
|
|
137
|
+
get instance(): RaChartInstance | null {
|
|
138
|
+
return this.chart;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
replay(): void {
|
|
142
|
+
this.zone.runOutsideAngular(() => this.chart?.replay());
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
resize(): void {
|
|
146
|
+
this.zone.runOutsideAngular(() => this.chart?.resize());
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
zoomTo(from: number, to: number): void {
|
|
150
|
+
this.zone.runOutsideAngular(() => this.chart?.zoomTo(from, to));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
resetZoom(): void {
|
|
154
|
+
this.zone.runOutsideAngular(() => this.chart?.resetZoom());
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
toggleSeries(index: number, hidden?: boolean): void {
|
|
158
|
+
this.zone.runOutsideAngular(() => this.chart?.toggleSeries(index, hidden));
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** SVG markup of the current chart — handy for share sheets and exports. */
|
|
162
|
+
toSVG(): string {
|
|
163
|
+
return this.chart ? this.chart.toSVG() : '';
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// ---------------------------------------------------------------
|
|
167
|
+
// internals
|
|
168
|
+
// ---------------------------------------------------------------
|
|
169
|
+
|
|
170
|
+
private buildOptions(): RaChartOptions {
|
|
171
|
+
const o: RaChartOptions = {
|
|
172
|
+
type: this.type,
|
|
173
|
+
data: this.data || [],
|
|
174
|
+
category: this.category,
|
|
175
|
+
series: this.series || [],
|
|
176
|
+
colors: this.colors,
|
|
177
|
+
stacked: this.stacked,
|
|
178
|
+
fullStacked: this.fullStacked,
|
|
179
|
+
smooth: this.smooth,
|
|
180
|
+
stepped: this.stepped,
|
|
181
|
+
semi: this.semi,
|
|
182
|
+
depth: this.depth,
|
|
183
|
+
fields: this.fields,
|
|
184
|
+
xField: this.xField,
|
|
185
|
+
sizeField: this.sizeField,
|
|
186
|
+
min: this.min,
|
|
187
|
+
max: this.max,
|
|
188
|
+
bands: this.bands,
|
|
189
|
+
zoom: this.zoom,
|
|
190
|
+
pinchZoom: this.pinchZoom,
|
|
191
|
+
legend: this.legend,
|
|
192
|
+
height: this.height,
|
|
193
|
+
haptics: this.haptics,
|
|
194
|
+
sheetTooltip: this.sheetTooltip,
|
|
195
|
+
tooltipHold: this.tooltipHold,
|
|
196
|
+
animation: this.animation
|
|
197
|
+
};
|
|
198
|
+
if (this.upColor) o.upColor = this.upColor;
|
|
199
|
+
if (this.downColor) o.downColor = this.downColor;
|
|
200
|
+
return o;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
private boot(): void {
|
|
204
|
+
if (this.booted || this.isEmpty) return;
|
|
205
|
+
this.booted = true;
|
|
206
|
+
|
|
207
|
+
ensureRaChart(this.scriptUrl).then(Ctor => {
|
|
208
|
+
if (!this.hostRef) return;
|
|
209
|
+
this.zone.runOutsideAngular(() => {
|
|
210
|
+
this.bindEvents();
|
|
211
|
+
this.chart = new Ctor(this.hostRef.nativeElement, this.buildOptions());
|
|
212
|
+
});
|
|
213
|
+
this.zone.run(() => {
|
|
214
|
+
this.error = null;
|
|
215
|
+
this.ready.emit(this.chart!);
|
|
216
|
+
this.cdr.markForCheck();
|
|
217
|
+
});
|
|
218
|
+
}).catch((err: Error) => {
|
|
219
|
+
this.zone.run(() => {
|
|
220
|
+
this.error = 'Chart engine failed to load';
|
|
221
|
+
this.booted = false;
|
|
222
|
+
this.cdr.markForCheck();
|
|
223
|
+
});
|
|
224
|
+
console.error('[ra-chart]', err.message, '— expected at:', this.scriptUrl);
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
private bindEvents(): void {
|
|
229
|
+
const host = this.hostRef.nativeElement;
|
|
230
|
+
const bridge = (name: string, out: EventEmitter<any>) => {
|
|
231
|
+
const fn = ((e: CustomEvent) => {
|
|
232
|
+
// only surface to Angular if somebody is actually listening
|
|
233
|
+
if (out.observers.length === 0) return;
|
|
234
|
+
this.zone.run(() => out.emit(e.detail));
|
|
235
|
+
}) as EventListener;
|
|
236
|
+
host.addEventListener(name, fn);
|
|
237
|
+
this.listeners.push([name, fn]);
|
|
238
|
+
};
|
|
239
|
+
bridge('raChartSelect', this.select);
|
|
240
|
+
bridge('raChartZoom', this.zoomChange);
|
|
241
|
+
bridge('raChartToggle', this.toggle);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
private teardownChart(): void {
|
|
245
|
+
const host = this.hostRef?.nativeElement;
|
|
246
|
+
if (host) {
|
|
247
|
+
this.listeners.forEach(([name, fn]) => host.removeEventListener(name, fn));
|
|
248
|
+
}
|
|
249
|
+
this.listeners = [];
|
|
250
|
+
this.chart?.destroy();
|
|
251
|
+
this.chart = null;
|
|
252
|
+
this.booted = false;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { InjectionToken } from '@angular/core';
|
|
2
|
+
import type { RaChartConstructor } from './ra-chart.types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Where `ra-chart.js` lives when it is NOT bundled via angular.json "scripts".
|
|
6
|
+
* Override in your app config to change the path:
|
|
7
|
+
*
|
|
8
|
+
* providers: [{ provide: RA_CHART_SCRIPT_URL, useValue: 'assets/vendor/ra-chart.js' }]
|
|
9
|
+
*/
|
|
10
|
+
export const RA_CHART_SCRIPT_URL = new InjectionToken<string>('RA_CHART_SCRIPT_URL', {
|
|
11
|
+
providedIn: 'root',
|
|
12
|
+
factory: () => 'assets/ra-chart/ra-chart.js'
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
let pending: Promise<RaChartConstructor> | null = null;
|
|
16
|
+
|
|
17
|
+
/** The engine attaches itself to `window`; grab it if it is already there. */
|
|
18
|
+
function fromWindow(): RaChartConstructor | null {
|
|
19
|
+
const w = window as any;
|
|
20
|
+
return w && w.RaChart ? (w.RaChart as RaChartConstructor) : null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Resolve the engine, lazy-injecting the script the first time if needed.
|
|
25
|
+
* Repeat calls share one in-flight promise, so many charts on one page
|
|
26
|
+
* trigger exactly one network request.
|
|
27
|
+
*/
|
|
28
|
+
export function ensureRaChart(scriptUrl: string): Promise<RaChartConstructor> {
|
|
29
|
+
const existing = fromWindow();
|
|
30
|
+
if (existing) return Promise.resolve(existing);
|
|
31
|
+
if (pending) return pending;
|
|
32
|
+
|
|
33
|
+
pending = new Promise<RaChartConstructor>((resolve, reject) => {
|
|
34
|
+
// another loader may have injected the same tag already
|
|
35
|
+
const selector = `script[data-ra-chart="1"]`;
|
|
36
|
+
let tag = document.querySelector<HTMLScriptElement>(selector);
|
|
37
|
+
|
|
38
|
+
const done = () => {
|
|
39
|
+
const ctor = fromWindow();
|
|
40
|
+
if (ctor) resolve(ctor);
|
|
41
|
+
else reject(new Error('ra-chart.js loaded but window.RaChart is missing'));
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
if (tag) {
|
|
45
|
+
tag.addEventListener('load', done);
|
|
46
|
+
tag.addEventListener('error', () => reject(new Error('Failed to load ' + scriptUrl)));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
tag = document.createElement('script');
|
|
51
|
+
tag.src = scriptUrl;
|
|
52
|
+
tag.async = true;
|
|
53
|
+
tag.dataset['raChart'] = '1';
|
|
54
|
+
tag.onload = done;
|
|
55
|
+
tag.onerror = () => {
|
|
56
|
+
pending = null;
|
|
57
|
+
reject(new Error('Failed to load ' + scriptUrl));
|
|
58
|
+
};
|
|
59
|
+
document.head.appendChild(tag);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
return pending;
|
|
63
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { NgModule, ModuleWithProviders } from '@angular/core';
|
|
2
|
+
import { RaChartComponent } from './ra-chart.component';
|
|
3
|
+
import { RA_CHART_SCRIPT_URL } from './ra-chart.loader';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Compatibility module for apps that are not on standalone components yet.
|
|
7
|
+
* Standalone apps can import `RaChartComponent` directly instead.
|
|
8
|
+
*/
|
|
9
|
+
@NgModule({
|
|
10
|
+
imports: [RaChartComponent],
|
|
11
|
+
exports: [RaChartComponent]
|
|
12
|
+
})
|
|
13
|
+
export class RaChartModule {
|
|
14
|
+
/** Point the lazy loader at a custom script path. */
|
|
15
|
+
static forRoot(config: { scriptUrl?: string } = {}): ModuleWithProviders<RaChartModule> {
|
|
16
|
+
return {
|
|
17
|
+
ngModule: RaChartModule,
|
|
18
|
+
providers: config.scriptUrl
|
|
19
|
+
? [{ provide: RA_CHART_SCRIPT_URL, useValue: config.scriptUrl }]
|
|
20
|
+
: []
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* raChart Cordova — types re-exported for Ionic/Angular consumers.
|
|
3
|
+
*
|
|
4
|
+
* These mirror `types/index.d.ts`; they live here as plain source so the
|
|
5
|
+
* Ionic app can import them without a package build step.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export type RaChartType =
|
|
9
|
+
| 'column' | 'bar' | 'line' | 'area' | 'lollipop'
|
|
10
|
+
| 'pie' | 'donut' | 'radar'
|
|
11
|
+
| 'treemap' | 'sankey' | 'wordcloud' | 'venn'
|
|
12
|
+
| 'candlestick' | 'timeline' | 'gantt'
|
|
13
|
+
| 'scatter' | 'bubble'
|
|
14
|
+
| 'funnel' | 'pyramid'
|
|
15
|
+
| 'gauge' | 'heatmap';
|
|
16
|
+
|
|
17
|
+
export interface RaSeries {
|
|
18
|
+
name: string;
|
|
19
|
+
field: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface RaFieldMap {
|
|
23
|
+
open?: string;
|
|
24
|
+
high?: string;
|
|
25
|
+
low?: string;
|
|
26
|
+
close?: string;
|
|
27
|
+
start?: string;
|
|
28
|
+
end?: string;
|
|
29
|
+
progress?: string;
|
|
30
|
+
from?: string;
|
|
31
|
+
to?: string;
|
|
32
|
+
value?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface RaBand {
|
|
36
|
+
from?: number;
|
|
37
|
+
to?: number;
|
|
38
|
+
color?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface RaAnimation {
|
|
42
|
+
duration?: number;
|
|
43
|
+
delay?: number;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface RaChartOptions {
|
|
47
|
+
type?: RaChartType;
|
|
48
|
+
data?: any[];
|
|
49
|
+
category?: string;
|
|
50
|
+
series?: RaSeries[];
|
|
51
|
+
colors?: string[] | null;
|
|
52
|
+
stacked?: boolean;
|
|
53
|
+
fullStacked?: boolean;
|
|
54
|
+
smooth?: boolean;
|
|
55
|
+
stepped?: boolean;
|
|
56
|
+
semi?: boolean;
|
|
57
|
+
depth?: number;
|
|
58
|
+
fields?: RaFieldMap | null;
|
|
59
|
+
xField?: string;
|
|
60
|
+
sizeField?: string;
|
|
61
|
+
min?: number;
|
|
62
|
+
max?: number | null;
|
|
63
|
+
bands?: RaBand[] | null;
|
|
64
|
+
upColor?: string;
|
|
65
|
+
downColor?: string;
|
|
66
|
+
zoom?: boolean;
|
|
67
|
+
pinchZoom?: boolean;
|
|
68
|
+
legend?: boolean;
|
|
69
|
+
height?: number;
|
|
70
|
+
haptics?: boolean;
|
|
71
|
+
sheetTooltip?: boolean | 'auto';
|
|
72
|
+
tooltipHold?: number;
|
|
73
|
+
animation?: RaAnimation;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface RaSelectEvent {
|
|
77
|
+
seriesIndex?: number;
|
|
78
|
+
categoryIndex?: number;
|
|
79
|
+
index?: number;
|
|
80
|
+
series?: string;
|
|
81
|
+
category?: string;
|
|
82
|
+
value?: number;
|
|
83
|
+
percent?: number;
|
|
84
|
+
x?: number;
|
|
85
|
+
y?: number;
|
|
86
|
+
size?: number;
|
|
87
|
+
ohlc?: { o: number; h: number; l: number; c: number };
|
|
88
|
+
start?: number;
|
|
89
|
+
end?: number;
|
|
90
|
+
progress?: number | null;
|
|
91
|
+
kind?: 'link' | 'node';
|
|
92
|
+
from?: string;
|
|
93
|
+
to?: string;
|
|
94
|
+
name?: string;
|
|
95
|
+
row?: any;
|
|
96
|
+
col?: number;
|
|
97
|
+
[key: string]: any;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface RaZoomEvent {
|
|
101
|
+
from: number;
|
|
102
|
+
to: number;
|
|
103
|
+
startIndex: number;
|
|
104
|
+
endIndex: number;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface RaToggleEvent {
|
|
108
|
+
index: number;
|
|
109
|
+
name: string;
|
|
110
|
+
hidden: boolean;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Runtime handle returned by the engine. */
|
|
114
|
+
export interface RaChartInstance {
|
|
115
|
+
setData(data: any[]): RaChartInstance;
|
|
116
|
+
setType(type: RaChartType): RaChartInstance;
|
|
117
|
+
update(partial: RaChartOptions): RaChartInstance;
|
|
118
|
+
replay(): RaChartInstance;
|
|
119
|
+
resize(): RaChartInstance;
|
|
120
|
+
zoomTo(from: number, to: number): RaChartInstance;
|
|
121
|
+
resetZoom(): RaChartInstance;
|
|
122
|
+
getZoom(): RaZoomEvent;
|
|
123
|
+
toggleSeries(index: number, hidden?: boolean): RaChartInstance;
|
|
124
|
+
toSVG(): string;
|
|
125
|
+
destroy(): void;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface RaChartConstructor {
|
|
129
|
+
new(host: HTMLElement | string, options?: RaChartOptions): RaChartInstance;
|
|
130
|
+
version: string;
|
|
131
|
+
defaults: RaChartOptions;
|
|
132
|
+
palette: string[];
|
|
133
|
+
paletteDark: string[];
|
|
134
|
+
types: RaChartType[];
|
|
135
|
+
create(host: HTMLElement | string, options?: RaChartOptions): RaChartInstance;
|
|
136
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cordova-plugin-ra-chart",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Dependency-free SVG chart engine for Cordova and Ionic — 21 chart types with touch gestures, pinch-to-zoom, haptics and dark-mode theming. No native code, no build step.",
|
|
5
|
+
"main": "www/ra-chart.js",
|
|
6
|
+
"types": "types/index.d.ts",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"author": "RemoteApps",
|
|
9
|
+
"cordova": {
|
|
10
|
+
"id": "cordova-plugin-ra-chart",
|
|
11
|
+
"platforms": [
|
|
12
|
+
"android",
|
|
13
|
+
"ios",
|
|
14
|
+
"browser",
|
|
15
|
+
"electron"
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"ecosystem:cordova",
|
|
20
|
+
"cordova-android",
|
|
21
|
+
"cordova-ios",
|
|
22
|
+
"cordova-browser",
|
|
23
|
+
"ionic",
|
|
24
|
+
"angular",
|
|
25
|
+
"chart",
|
|
26
|
+
"charts",
|
|
27
|
+
"svg",
|
|
28
|
+
"graph",
|
|
29
|
+
"dashboard",
|
|
30
|
+
"mobile",
|
|
31
|
+
"offline",
|
|
32
|
+
"no-dependencies"
|
|
33
|
+
],
|
|
34
|
+
"files": [
|
|
35
|
+
"www/",
|
|
36
|
+
"types/",
|
|
37
|
+
"ionic/",
|
|
38
|
+
"plugin.xml",
|
|
39
|
+
"README.md"
|
|
40
|
+
],
|
|
41
|
+
"engines": {
|
|
42
|
+
"cordovaDependencies": {
|
|
43
|
+
"1.0.0": {
|
|
44
|
+
"cordova": ">=9.0.0"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {},
|
|
49
|
+
"peerDependencies": {},
|
|
50
|
+
"sideEffects": [
|
|
51
|
+
"www/ra-chart.js",
|
|
52
|
+
"www/ra-chart.css"
|
|
53
|
+
]
|
|
54
|
+
}
|
package/plugin.xml
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!--
|
|
3
|
+
raChart Cordova plugin descriptor.
|
|
4
|
+
|
|
5
|
+
Install: cordova plugin add ./ra-chart-cordova
|
|
6
|
+
After install, `window.RaChart` is available on deviceready.
|
|
7
|
+
|
|
8
|
+
This is a pure web-asset plugin: it ships JS + CSS only, so it works on
|
|
9
|
+
every Cordova platform (and in the browser) with no native compilation.
|
|
10
|
+
-->
|
|
11
|
+
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
|
12
|
+
id="cordova-plugin-ra-chart"
|
|
13
|
+
version="1.0.0">
|
|
14
|
+
|
|
15
|
+
<name>raChart</name>
|
|
16
|
+
<description>
|
|
17
|
+
Dependency-free SVG chart engine for Cordova and Ionic. 21 chart types with
|
|
18
|
+
touch gestures, pinch-to-zoom, haptics and dark-mode theming. No native code.
|
|
19
|
+
</description>
|
|
20
|
+
<license>MIT</license>
|
|
21
|
+
<keywords>cordova,ionic,chart,charts,svg,graph,dashboard,mobile,offline</keywords>
|
|
22
|
+
<author>RemoteApps</author>
|
|
23
|
+
|
|
24
|
+
<engines>
|
|
25
|
+
<engine name="cordova" version=">=9.0.0" />
|
|
26
|
+
</engines>
|
|
27
|
+
|
|
28
|
+
<!-- window.RaChart -->
|
|
29
|
+
<js-module src="www/ra-chart.js" name="RaChart">
|
|
30
|
+
<clobbers target="RaChart" />
|
|
31
|
+
</js-module>
|
|
32
|
+
|
|
33
|
+
<!--
|
|
34
|
+
Cordova does not inject stylesheets, so link the CSS yourself in index.html:
|
|
35
|
+
<link rel="stylesheet" href="plugins/cordova-plugin-ra-chart/www/ra-chart.css">
|
|
36
|
+
Ionic apps normally add it to angular.json "styles" instead.
|
|
37
|
+
-->
|
|
38
|
+
<asset src="www/ra-chart.css" target="css/ra-chart.css" />
|
|
39
|
+
|
|
40
|
+
<platform name="android" />
|
|
41
|
+
<platform name="ios" />
|
|
42
|
+
<platform name="browser" />
|
|
43
|
+
<platform name="electron" />
|
|
44
|
+
|
|
45
|
+
</plugin>
|