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.
@@ -0,0 +1,218 @@
1
+ /**
2
+ * raChart Cordova v1.0.0 — TypeScript definitions
3
+ * RemoteApps UI Components
4
+ */
5
+
6
+ export type RaChartType =
7
+ | 'column' | 'bar' | 'line' | 'area' | 'lollipop'
8
+ | 'pie' | 'donut' | 'radar'
9
+ | 'treemap' | 'sankey' | 'wordcloud' | 'venn'
10
+ | 'candlestick' | 'timeline' | 'gantt'
11
+ | 'scatter' | 'bubble'
12
+ | 'funnel' | 'pyramid'
13
+ | 'gauge' | 'heatmap';
14
+
15
+ /** One plotted measure. For pie/donut/treemap/etc. only the first entry is used. */
16
+ export interface RaSeries {
17
+ /** Legend / tooltip label. */
18
+ name: string;
19
+ /** Property on each data row holding this series' value. */
20
+ field: string;
21
+ }
22
+
23
+ /** Remap non-standard column names per chart type. */
24
+ export interface RaFieldMap {
25
+ /** candlestick */
26
+ open?: string;
27
+ high?: string;
28
+ low?: string;
29
+ close?: string;
30
+ /** gantt */
31
+ start?: string;
32
+ end?: string;
33
+ progress?: string;
34
+ /** sankey */
35
+ from?: string;
36
+ to?: string;
37
+ value?: string;
38
+ }
39
+
40
+ /** A coloured zone on a gauge scale. */
41
+ export interface RaBand {
42
+ from?: number;
43
+ to?: number;
44
+ color?: string;
45
+ }
46
+
47
+ export interface RaAnimation {
48
+ /** Entrance duration in ms. */
49
+ duration?: number;
50
+ /** Per-mark stagger in ms. */
51
+ delay?: number;
52
+ }
53
+
54
+ export interface RaChartOptions {
55
+ type?: RaChartType;
56
+ /** Array of plain rows. */
57
+ data?: any[];
58
+ /** Row property used for labels / slices / tasks. */
59
+ category?: string;
60
+ series?: RaSeries[];
61
+ /** Hex colours assigned to series (or slices) in order. `null` = theme-aware default. */
62
+ colors?: string[] | null;
63
+
64
+ stacked?: boolean;
65
+ /** 100% stacked column/bar — values normalised per category, tooltips in %. */
66
+ fullStacked?: boolean;
67
+ /** Curved line/area interpolation. */
68
+ smooth?: boolean;
69
+ /** Stepped line/area interpolation. */
70
+ stepped?: boolean;
71
+ /** Half-circle pie/donut. */
72
+ semi?: boolean;
73
+ /** 3D extrusion depth in px (column, bar, pie, donut). 0 = flat. */
74
+ depth?: number;
75
+
76
+ fields?: RaFieldMap | null;
77
+ /** scatter/bubble numeric X field. */
78
+ xField?: string;
79
+ /** bubble size field. */
80
+ sizeField?: string;
81
+
82
+ /** Value-axis minimum. */
83
+ min?: number;
84
+ /** Gauge scale maximum. */
85
+ max?: number | null;
86
+ /** Gauge coloured zones. */
87
+ bands?: RaBand[] | null;
88
+
89
+ /** Candlestick bull colour. */
90
+ upColor?: string;
91
+ /** Candlestick bear colour. */
92
+ downColor?: string;
93
+
94
+ /** Range-slider zoom (XY types + candlestick). */
95
+ zoom?: boolean;
96
+ /** Pinch-to-zoom and drag-to-pan when `zoom` is on. Default true. */
97
+ pinchZoom?: boolean;
98
+
99
+ /** Clickable legend. Auto-hidden for single-series XY charts. */
100
+ legend?: boolean;
101
+ /** Plot height in px (legend and zoom bar flow outside it). */
102
+ height?: number;
103
+
104
+ /** Vibrate on touch-select via Capacitor Haptics or navigator.vibrate. */
105
+ haptics?: boolean;
106
+ /** Dock the tooltip to the bottom edge. `'auto'` = on coarse pointers under 480px. */
107
+ sheetTooltip?: boolean | 'auto';
108
+ /** ms a touch tooltip stays visible after the finger lifts. 0 = until next tap. */
109
+ tooltipHold?: number;
110
+
111
+ animation?: RaAnimation;
112
+ }
113
+
114
+ /** `raChartSelect` — a mark was tapped, hovered, or scrubbed. */
115
+ export interface RaSelectEvent {
116
+ seriesIndex?: number;
117
+ categoryIndex?: number;
118
+ index?: number;
119
+ series?: string;
120
+ category?: string;
121
+ value?: number;
122
+ percent?: number;
123
+ /** scatter/bubble */
124
+ x?: number;
125
+ y?: number;
126
+ size?: number;
127
+ /** candlestick */
128
+ ohlc?: { o: number; h: number; l: number; c: number };
129
+ /** gantt */
130
+ start?: number;
131
+ end?: number;
132
+ progress?: number | null;
133
+ /** sankey */
134
+ kind?: 'link' | 'node';
135
+ from?: string;
136
+ to?: string;
137
+ name?: string;
138
+ /** heatmap */
139
+ row?: any;
140
+ col?: number;
141
+ /** The original data row, when one applies. */
142
+ [key: string]: any;
143
+ }
144
+
145
+ /** `raChartZoom` — the visible window changed. */
146
+ export interface RaZoomEvent {
147
+ /** Window start as a fraction 0..1. */
148
+ from: number;
149
+ /** Window end as a fraction 0..1. */
150
+ to: number;
151
+ /** First visible data index. */
152
+ startIndex: number;
153
+ /** Last visible data index. */
154
+ endIndex: number;
155
+ }
156
+
157
+ /** `raChartToggle` — a legend entry was switched on or off. */
158
+ export interface RaToggleEvent {
159
+ index: number;
160
+ name: string;
161
+ hidden: boolean;
162
+ }
163
+
164
+ export declare class RaChart {
165
+ constructor(host: HTMLElement | string, options?: RaChartOptions);
166
+
167
+ readonly el: HTMLElement;
168
+ readonly opts: RaChartOptions;
169
+ readonly kind: string;
170
+ readonly dark: boolean;
171
+
172
+ /** Replace the data. Same-shape updates morph; shape changes rebuild. */
173
+ setData(data: any[]): this;
174
+ /** Switch chart type, resetting zoom and hidden series. */
175
+ setType(type: RaChartType): this;
176
+ /** Merge partial options and rebuild. */
177
+ update(partial: RaChartOptions): this;
178
+ /** Replay the entrance animation. */
179
+ replay(): this;
180
+ /** Re-measure and redraw (called automatically on resize/rotate). */
181
+ resize(): this;
182
+
183
+ /** Zoom to a 0..1 fraction window, or pass integers for a data index range. */
184
+ zoomTo(from: number, to: number): this;
185
+ resetZoom(): this;
186
+ getZoom(): RaZoomEvent;
187
+
188
+ /** Show/hide a series or slice by index. */
189
+ toggleSeries(index: number, hidden?: boolean): this;
190
+
191
+ /** Serialise the current chart to an SVG string, for share or export. */
192
+ toSVG(): string;
193
+
194
+ /** Tear down listeners and observers. Always call this on view destroy. */
195
+ destroy(): void;
196
+
197
+ static version: string;
198
+ static defaults: RaChartOptions;
199
+ static palette: string[];
200
+ static paletteDark: string[];
201
+ static types: RaChartType[];
202
+ static create(host: HTMLElement | string, options?: RaChartOptions): RaChart;
203
+ }
204
+
205
+ export default RaChart;
206
+
207
+ declare global {
208
+ interface Window {
209
+ RaChart: typeof RaChart;
210
+ }
211
+
212
+ interface HTMLElementEventMap {
213
+ raChartReady: CustomEvent<{ chart: RaChart }>;
214
+ raChartSelect: CustomEvent<RaSelectEvent>;
215
+ raChartZoom: CustomEvent<RaZoomEvent>;
216
+ raChartToggle: CustomEvent<RaToggleEvent>;
217
+ }
218
+ }
@@ -0,0 +1,324 @@
1
+ /*!
2
+ * raChart Cordova v1.0.0 — component styles
3
+ * RemoteApps UI Components
4
+ *
5
+ * Theming: every colour is a CSS custom property, so you can restyle
6
+ * charts from your Ionic theme file without touching JS. The engine
7
+ * reads these same variables at build time for SVG fills.
8
+ */
9
+
10
+ .ra-chart {
11
+ /* ---- palette hooks (override in your theme) ---- */
12
+ --ra-chart-scheme: light;
13
+ --ra-chart-surface: #ffffff;
14
+ --ra-chart-text: #1f2937;
15
+ --ra-chart-body: #4b5563;
16
+ --ra-chart-label: #898781;
17
+ --ra-chart-muted: #9ca3af;
18
+ --ra-chart-grid: #e1e0d9;
19
+ --ra-chart-baseline: #c3c2b7;
20
+
21
+ --ra-chart-tip-bg: #1f2937;
22
+ --ra-chart-tip-text: #f9fafb;
23
+ --ra-chart-tip-muted: #9ca3af;
24
+
25
+ --ra-chart-zoom-track: #eceff3;
26
+ --ra-chart-zoom-sel: #c7c2ee;
27
+ --ra-chart-zoom-handle: #ffffff;
28
+ --ra-chart-zoom-handle-border: #534ab7;
29
+
30
+ --ra-chart-radius: 12px;
31
+
32
+ position: relative;
33
+ display: block;
34
+ width: 100%;
35
+ font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
36
+ -webkit-tap-highlight-color: transparent;
37
+ }
38
+
39
+ /* ---- dark mode: OS preference, Ionic 8 palette, and legacy body.dark ---- */
40
+ @media (prefers-color-scheme: dark) {
41
+ .ra-chart:not(.ra-chart--light) {
42
+ --ra-chart-scheme: dark;
43
+ --ra-chart-surface: #1a1a19;
44
+ --ra-chart-text: #ffffff;
45
+ --ra-chart-body: #c3c2b7;
46
+ --ra-chart-label: #9d9c95;
47
+ --ra-chart-muted: #8a8a84;
48
+ --ra-chart-grid: #2c2c2a;
49
+ --ra-chart-baseline: #383835;
50
+ --ra-chart-tip-bg: #f4f4f2;
51
+ --ra-chart-tip-text: #16161a;
52
+ --ra-chart-tip-muted: #6b6b66;
53
+ --ra-chart-zoom-track: #2c2c2a;
54
+ --ra-chart-zoom-sel: #4a4494;
55
+ --ra-chart-zoom-handle: #1a1a19;
56
+ --ra-chart-zoom-handle-border: #9085e9;
57
+ }
58
+ }
59
+
60
+ .ion-palette-dark .ra-chart:not(.ra-chart--light),
61
+ body.dark .ra-chart:not(.ra-chart--light),
62
+ .ra-chart--dark {
63
+ --ra-chart-scheme: dark;
64
+ --ra-chart-surface: #1a1a19;
65
+ --ra-chart-text: #ffffff;
66
+ --ra-chart-body: #c3c2b7;
67
+ --ra-chart-label: #9d9c95;
68
+ --ra-chart-muted: #8a8a84;
69
+ --ra-chart-grid: #2c2c2a;
70
+ --ra-chart-baseline: #383835;
71
+ --ra-chart-tip-bg: #f4f4f2;
72
+ --ra-chart-tip-text: #16161a;
73
+ --ra-chart-tip-muted: #6b6b66;
74
+ --ra-chart-zoom-track: #2c2c2a;
75
+ --ra-chart-zoom-sel: #4a4494;
76
+ --ra-chart-zoom-handle: #1a1a19;
77
+ --ra-chart-zoom-handle-border: #9085e9;
78
+ }
79
+
80
+ /* ============ Stage ============ */
81
+ .ra-chart__stage {
82
+ position: relative;
83
+ width: 100%;
84
+ overflow: hidden;
85
+ }
86
+
87
+ .ra-chart__stage svg {
88
+ display: block;
89
+ width: 100%;
90
+ height: 100%;
91
+ overflow: visible;
92
+ user-select: none;
93
+ -webkit-user-select: none;
94
+ }
95
+
96
+ .ra-chart .ra-hit {
97
+ cursor: pointer;
98
+ }
99
+
100
+ /* ============ Tooltip ============ */
101
+ .ra-chart__tip {
102
+ position: absolute;
103
+ z-index: 5;
104
+ pointer-events: none;
105
+ max-width: 88%;
106
+ background: var(--ra-chart-tip-bg);
107
+ color: var(--ra-chart-tip-text);
108
+ font-size: 12px;
109
+ font-weight: 600;
110
+ line-height: 1.5;
111
+ border-radius: 10px;
112
+ padding: 8px 12px;
113
+ box-shadow: 0 6px 20px rgba(15, 23, 42, 0.28);
114
+ opacity: 0;
115
+ transform: translate(-50%, -112%) scale(.96);
116
+ transition: opacity .15s ease, transform .15s ease;
117
+ white-space: nowrap;
118
+ }
119
+
120
+ .ra-chart__tip.is-on {
121
+ opacity: 1;
122
+ transform: translate(-50%, -112%) scale(1);
123
+ }
124
+
125
+ /* phone: dock the tooltip to the bottom so a thumb never covers it */
126
+ .ra-chart__tip--sheet {
127
+ left: 50% !important;
128
+ top: auto !important;
129
+ bottom: 6px;
130
+ transform: translate(-50%, 8px);
131
+ white-space: normal;
132
+ text-align: center;
133
+ padding: 10px 16px;
134
+ border-radius: 12px;
135
+ font-size: 13px;
136
+ }
137
+
138
+ .ra-chart__tip--sheet.is-on {
139
+ transform: translate(-50%, 0);
140
+ }
141
+
142
+ .ra-chart__tip-dot {
143
+ display: inline-block;
144
+ width: 8px;
145
+ height: 8px;
146
+ border-radius: 50%;
147
+ margin-right: 6px;
148
+ vertical-align: baseline;
149
+ }
150
+
151
+ .ra-chart__tip-cat {
152
+ display: block;
153
+ color: var(--ra-chart-tip-muted);
154
+ font-weight: 500;
155
+ margin-bottom: 2px;
156
+ }
157
+
158
+ .ra-chart__tip-muted {
159
+ color: var(--ra-chart-tip-muted);
160
+ font-weight: 500;
161
+ }
162
+
163
+ /* ============ Zoom (range slider) ============ */
164
+ .ra-chart__zoom {
165
+ padding: 6px 0 14px;
166
+ touch-action: none;
167
+ }
168
+
169
+ .ra-chart__zoom-track {
170
+ position: relative;
171
+ height: 8px;
172
+ background: var(--ra-chart-zoom-track);
173
+ border-radius: 999px;
174
+ margin: 0 13px;
175
+ }
176
+
177
+ .ra-chart__zoom-sel {
178
+ position: absolute;
179
+ top: 0;
180
+ height: 100%;
181
+ background: var(--ra-chart-zoom-sel);
182
+ border-radius: 999px;
183
+ cursor: grab;
184
+ }
185
+
186
+ .ra-chart__zoom-sel:active {
187
+ cursor: grabbing;
188
+ }
189
+
190
+ /* 26px handles: Apple/Google both want >=24px touch targets */
191
+ .ra-chart__zoom-handle {
192
+ position: absolute;
193
+ top: 50%;
194
+ width: 26px;
195
+ height: 26px;
196
+ border-radius: 50%;
197
+ background: var(--ra-chart-zoom-handle);
198
+ border: 2px solid var(--ra-chart-zoom-handle-border);
199
+ box-shadow: 0 1px 5px rgba(15, 23, 42, 0.28);
200
+ transform: translate(-50%, -50%);
201
+ cursor: ew-resize;
202
+ touch-action: none;
203
+ }
204
+
205
+ .ra-chart__zoom-handle::after {
206
+ content: "";
207
+ position: absolute;
208
+ left: 50%;
209
+ top: 50%;
210
+ width: 8px;
211
+ height: 8px;
212
+ border-radius: 50%;
213
+ background: var(--ra-chart-zoom-handle-border);
214
+ transform: translate(-50%, -50%);
215
+ }
216
+
217
+ @media (pointer: fine) {
218
+ .ra-chart__zoom-handle {
219
+ width: 18px;
220
+ height: 18px;
221
+ }
222
+
223
+ .ra-chart__zoom-handle::after {
224
+ width: 5px;
225
+ height: 5px;
226
+ }
227
+ }
228
+
229
+ /* ============ Legend ============ */
230
+ .ra-chart__legend {
231
+ display: flex;
232
+ flex-wrap: wrap;
233
+ justify-content: center;
234
+ gap: 4px 14px;
235
+ padding-top: 10px;
236
+ font-size: 13px;
237
+ font-weight: 700;
238
+ color: var(--ra-chart-body);
239
+ }
240
+
241
+ .ra-chart__legend-item {
242
+ display: inline-flex;
243
+ align-items: center;
244
+ gap: 7px;
245
+ /* 44px tall hit target without visually growing the row */
246
+ padding: 7px 2px;
247
+ cursor: pointer;
248
+ user-select: none;
249
+ -webkit-user-select: none;
250
+ transition: opacity .18s;
251
+ }
252
+
253
+ .ra-chart__legend-item:active {
254
+ opacity: .6;
255
+ }
256
+
257
+ .ra-chart__legend-item.is-off {
258
+ opacity: .38;
259
+ }
260
+
261
+ .ra-chart__legend-item.is-off .ra-chart__legend-label {
262
+ text-decoration: line-through;
263
+ }
264
+
265
+ .ra-chart__legend-item:focus-visible {
266
+ outline: 2px solid var(--ra-chart-zoom-handle-border);
267
+ outline-offset: 2px;
268
+ border-radius: 6px;
269
+ }
270
+
271
+ .ra-chart__legend-swatch {
272
+ width: 11px;
273
+ height: 11px;
274
+ border-radius: 4px;
275
+ flex-shrink: 0;
276
+ }
277
+
278
+ .ra-chart__legend-value {
279
+ color: var(--ra-chart-muted);
280
+ font-weight: 600;
281
+ }
282
+
283
+ /* ============ States ============ */
284
+ .ra-chart__empty,
285
+ .ra-chart__loading {
286
+ display: flex;
287
+ align-items: center;
288
+ justify-content: center;
289
+ flex-direction: column;
290
+ gap: 8px;
291
+ color: var(--ra-chart-muted);
292
+ font-size: 13px;
293
+ font-weight: 600;
294
+ text-align: center;
295
+ padding: 24px 16px;
296
+ }
297
+
298
+ .ra-chart__spinner {
299
+ width: 26px;
300
+ height: 26px;
301
+ border-radius: 50%;
302
+ border: 2.5px solid var(--ra-chart-grid);
303
+ border-top-color: var(--ra-chart-zoom-handle-border);
304
+ animation: ra-chart-spin .8s linear infinite;
305
+ }
306
+
307
+ @keyframes ra-chart-spin {
308
+ to {
309
+ transform: rotate(360deg);
310
+ }
311
+ }
312
+
313
+ @media (prefers-reduced-motion: reduce) {
314
+
315
+ .ra-chart__tip,
316
+ .ra-chart__legend-item,
317
+ .ra-chart .ra-hit {
318
+ transition: none !important;
319
+ }
320
+
321
+ .ra-chart__spinner {
322
+ animation-duration: 2s;
323
+ }
324
+ }