cordova-plugin-ra-chart 1.0.3 → 1.0.4

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 CHANGED
@@ -82,6 +82,14 @@ Add the stylesheet to `angular.json`:
82
82
  ]
83
83
  ```
84
84
 
85
+ > **`ra-chart.css` must be global — never a component's `styleUrls`.** Angular's
86
+ > view encapsulation scopes those rules to `[_ngcontent-*]`, which never matches
87
+ > the legend, tooltip and zoom bar because the engine creates them at runtime.
88
+ > The classic symptom is a legend that reads `RevenueTarget` with no colour
89
+ > swatches. Since v1.0.3 the engine injects its own structural styles so this
90
+ > renders correctly regardless, and `ra-chart.css` is optional — it only supplies
91
+ > theming. Load it globally to theme; skip it entirely and charts still look right.
92
+
85
93
  The component lazy-loads `ra-chart.js` from `assets/ra-chart/ra-chart.js` on first use. To bundle it eagerly instead, add it to `angular.json` → `"scripts"`; the loader will detect `window.RaChart` and skip the fetch.
86
94
 
87
95
  To load it from somewhere else:
@@ -621,6 +629,8 @@ To silence the diagnostics in production: `RaChart.warnings = false;`
621
629
 
622
630
  **Labels are cut off** — increase `height`, or shorten category labels. Horizontal `bar` and `gantt` cap the label gutter at about a third of the width.
623
631
 
632
+ **Legend reads "RevenueTarget" with no colour swatches** — the legend HTML is unstyled, meaning `ra-chart.css` did not reach it. Almost always because it was added to a component's `styleUrls` instead of `angular.json` → `styles`; view encapsulation scopes it to `[_ngcontent-*]` and the runtime-created legend has no such attribute. Fixed by default in v1.0.3 (the engine injects its own structural CSS), so updating the engine resolves it. To theme, move `ra-chart.css` to the global styles array.
633
+
624
634
  **Tooltip is clipped inside `ion-card`** — the tooltip is absolutely positioned inside the chart element; give the card content enough padding, or set `sheetTooltip: true` to dock it.
625
635
 
626
636
  **No haptics on device** — install `@capacitor/haptics`, or rely on the `navigator.vibrate` fallback (Android only; iOS Safari does not support it).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cordova-plugin-ra-chart",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
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
5
  "main": "www/ra-chart.js",
6
6
  "types": "types/index.d.ts",
package/plugin.xml CHANGED
@@ -15,7 +15,7 @@
15
15
  -->
16
16
  <plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
17
17
  id="cordova-plugin-ra-chart"
18
- version="1.0.2">
18
+ version="1.0.3">
19
19
 
20
20
  <name>raChart</name>
21
21
  <description>
package/www/ra-chart.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * raChart Cordova v1.0.2 — mobile SVG chart engine
2
+ * raChart Cordova v1.0.3 — mobile SVG chart engine
3
3
  * RemoteApps UI Components
4
4
  *
5
5
  * Zero dependencies. No jQuery, no chart library, no build step.
@@ -20,7 +20,7 @@
20
20
  "use strict";
21
21
 
22
22
  var NS = "http://www.w3.org/2000/svg";
23
- var VERSION = "1.0.2";
23
+ var VERSION = "1.0.3";
24
24
 
25
25
  /* ============================================================
26
26
  Palettes — CVD-validated order, do not shuffle
@@ -351,6 +351,60 @@
351
351
  gauge: "gauge", heatmap: "heat"
352
352
  };
353
353
 
354
+ /* ============================================================
355
+ Base stylesheet
356
+
357
+ The SVG gets its colours from inline attributes, but the legend, tooltip
358
+ and zoom bar are real HTML and would collapse into unstyled inline text
359
+ without CSS — the classic "legend reads RevenueTarget" symptom. Angular
360
+ makes that easy to hit: ra-chart.css dropped into a component's styleUrls
361
+ is scoped to [_ngcontent-*], which never matches nodes the engine creates
362
+ at runtime.
363
+
364
+ So the structural rules ship in JS and are injected once, at the TOP of
365
+ <head>, leaving ra-chart.css (and any app CSS) free to override them.
366
+ Colours defer to the same custom properties, with fallbacks.
367
+ ============================================================ */
368
+
369
+ var BASE_STYLE_ID = "ra-chart-base-styles";
370
+ var BASE_CSS = [
371
+ 'ra-chart{display:block;position:relative;width:100%}',
372
+ '.ra-chart{position:relative;display:block;width:100%;font-family:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;-webkit-tap-highlight-color:transparent}',
373
+ '.ra-chart__stage{position:relative;width:100%;overflow:hidden}',
374
+ '.ra-chart__stage svg{display:block;width:100%;height:100%;overflow:visible;user-select:none;-webkit-user-select:none}',
375
+ '.ra-chart .ra-hit{cursor:pointer}',
376
+ '.ra-chart__legend{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:4px 14px;padding-top:10px;font-size:13px;font-weight:700;line-height:1.4;color:var(--ra-chart-body,#4b5563)}',
377
+ '.ra-chart__legend-item{display:inline-flex;align-items:center;gap:7px;padding:7px 2px;cursor:pointer;user-select:none;-webkit-user-select:none;transition:opacity .18s}',
378
+ '.ra-chart__legend-item.is-off{opacity:.38}',
379
+ '.ra-chart__legend-item.is-off .ra-chart__legend-label{text-decoration:line-through}',
380
+ '.ra-chart__legend-swatch{display:inline-block;width:11px;height:11px;border-radius:4px;flex:0 0 auto}',
381
+ '.ra-chart__legend-value{color:var(--ra-chart-muted,#9ca3af);font-weight:600}',
382
+ '.ra-chart__tip{position:absolute;z-index:5;pointer-events:none;max-width:88%;background:var(--ra-chart-tip-bg,#1f2937);color:var(--ra-chart-tip-text,#f9fafb);font-size:12px;font-weight:600;line-height:1.5;border-radius:10px;padding:8px 12px;box-shadow:0 6px 20px rgba(15,23,42,.28);opacity:0;transform:translate(-50%,-112%) scale(.96);transition:opacity .15s,transform .15s;white-space:nowrap}',
383
+ '.ra-chart__tip.is-on{opacity:1;transform:translate(-50%,-112%) scale(1)}',
384
+ '.ra-chart__tip--sheet{left:50%!important;top:auto!important;bottom:6px;transform:translate(-50%,8px);white-space:normal;text-align:center;padding:10px 16px;border-radius:12px;font-size:13px}',
385
+ '.ra-chart__tip--sheet.is-on{transform:translate(-50%,0)}',
386
+ '.ra-chart__tip-dot{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:6px}',
387
+ '.ra-chart__tip-cat{display:block;color:var(--ra-chart-tip-muted,#9ca3af);font-weight:500;margin-bottom:2px}',
388
+ '.ra-chart__tip-muted{color:var(--ra-chart-tip-muted,#9ca3af);font-weight:500}',
389
+ '.ra-chart__zoom{padding:6px 0 14px;touch-action:none}',
390
+ '.ra-chart__zoom-track{position:relative;height:8px;background:var(--ra-chart-zoom-track,#eceff3);border-radius:999px;margin:0 13px}',
391
+ '.ra-chart__zoom-sel{position:absolute;top:0;height:100%;background:var(--ra-chart-zoom-sel,#c7c2ee);border-radius:999px;cursor:grab}',
392
+ '.ra-chart__zoom-handle{position:absolute;top:50%;width:26px;height:26px;border-radius:50%;background:var(--ra-chart-zoom-handle,#fff);border:2px solid var(--ra-chart-zoom-handle-border,#534ab7);box-shadow:0 1px 5px rgba(15,23,42,.28);transform:translate(-50%,-50%);cursor:ew-resize;touch-action:none}',
393
+ '@media (pointer:fine){.ra-chart__zoom-handle{width:18px;height:18px}}'
394
+ ].join("");
395
+
396
+ function ensureBaseStyles() {
397
+ if (typeof document === "undefined") return;
398
+ if (document.getElementById(BASE_STYLE_ID)) return;
399
+ var head = document.head || document.getElementsByTagName("head")[0];
400
+ if (!head) return;
401
+ var st = document.createElement("style");
402
+ st.id = BASE_STYLE_ID;
403
+ st.appendChild(document.createTextNode(BASE_CSS));
404
+ // first in <head> so ra-chart.css and app styles win on equal specificity
405
+ head.insertBefore(st, head.firstChild);
406
+ }
407
+
354
408
  var UID = 0;
355
409
 
356
410
  /* ============================================================
@@ -362,6 +416,7 @@
362
416
  if (typeof host === "string") host = document.querySelector(host);
363
417
  if (!host) throw new Error("raChart: host element not found");
364
418
 
419
+ ensureBaseStyles();
365
420
  this.el = host;
366
421
  this.uid = ++UID;
367
422
  this.opts = merge(merge({}, DEFAULTS), options || {});
@@ -3018,6 +3073,8 @@
3018
3073
  }
3019
3074
 
3020
3075
  RaChart.defineElement = defineElement;
3076
+ /** Inject the built-in structural stylesheet (called automatically). */
3077
+ RaChart.injectStyles = ensureBaseStyles;
3021
3078
 
3022
3079
  // Auto-register so the tag works with no setup. Harmless when a framework
3023
3080
  // component already owns the element — the stand-down guard handles it.