cordova-plugin-ra-chart 1.0.1 → 1.0.2

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
@@ -544,6 +544,36 @@ Run it from your Cordova project root, and point at wherever the folder actually
544
544
 
545
545
  **In an Ionic/Angular app, prefer Option B over the plugin.** The Cordova route only sets `window.RaChart` after `deviceready`, which means charts do not render in `ionic serve` or in unit tests. Copying to `src/assets/` works everywhere.
546
546
 
547
+ ### No data showing / blank chart
548
+
549
+ Work down this list — the first two cover almost every case.
550
+
551
+ **1. Check the console.** Since v1.0.1 the engine reports naming mismatches itself:
552
+
553
+ ```
554
+ [raChart] nothing to plot — series "Revenue" field "revenue" not found in the data.
555
+ Your rows have: month, total. Check the `field`/`category` names against your data keys.
556
+ ```
557
+
558
+ That means `field: 'revenue'` does not match your rows, so every value read as 0. The `field` in `series` and the `category` string must match your data object keys **exactly**, including case. An API returning `Total` will not bind to `field: 'total'`.
559
+
560
+ **2. Async data with `<ra-chart>`** — fixed in v1.0.1. On v1.0.0 a chart whose `data` was still `[]` when the view initialised never built once the API responded, leaving it permanently blank. Update to v1.0.1. There is no workaround on v1.0.0 other than `*ngIf`-ing the chart until data arrives.
561
+
562
+ **3. Mutating the array instead of replacing it.** The component is `OnPush`, so `push()` is invisible to it:
563
+
564
+ ```ts
565
+ this.rows = [...this.rows, row]; // ✅
566
+ this.rows.push(row); // ❌ nothing redraws
567
+ ```
568
+
569
+ **4. Values are strings.** `"42"` from JSON coerces fine, but `"1,234"` or `"42%"` becomes 0. Parse before binding.
570
+
571
+ **5. Zero-width container.** A chart built inside a hidden tab, collapsed accordion or `display:none` parent measures 0 and draws nothing. Call `resize()` when it becomes visible.
572
+
573
+ **6. Plain Cordova: building before `deviceready`.** `window.RaChart` does not exist until the plugin bootstraps. Wrap construction in a `deviceready` listener.
574
+
575
+ To silence the diagnostics in production: `RaChart.warnings = false;`
576
+
547
577
  ### Runtime issues
548
578
 
549
579
  **"Chart engine failed to load"** — `ra-chart.js` is not on any path the loader tries. It attempts your `RA_CHART_SCRIPT_URL` first, then `assets/ra-chart/ra-chart.js`, `assets/js/ra-chart.js`, `assets/ra-chart.js`, and `plugins/cordova-plugin-ra-chart/www/ra-chart.js`. Confirm the file is in one of those, that `angular.json` copies `src/assets`, and check the browser Network tab for a 404.
@@ -88,6 +88,8 @@ export class RaChartComponent implements AfterViewInit, OnChanges, OnDestroy {
88
88
 
89
89
  private chart: RaChartInstance | null = null;
90
90
  private booted = false;
91
+ /** Guards against building before the host div has been measured. */
92
+ private viewReady = false;
91
93
  private listeners: Array<[string, EventListener]> = [];
92
94
 
93
95
  constructor(
@@ -106,11 +108,20 @@ export class RaChartComponent implements AfterViewInit, OnChanges, OnDestroy {
106
108
  }
107
109
 
108
110
  ngAfterViewInit(): void {
111
+ this.viewReady = true;
109
112
  this.boot();
110
113
  }
111
114
 
112
115
  ngOnChanges(changes: SimpleChanges): void {
113
- if (!this.chart) return;
116
+ if (!this.chart) {
117
+ // No chart yet. This is the normal async case: the component rendered
118
+ // while `data` was still an empty array, so boot() bailed out as empty.
119
+ // Now that inputs have arrived, build it — otherwise the chart would
120
+ // stay blank forever.
121
+ if (this.viewReady && !this.isEmpty) this.boot();
122
+ else this.cdr.markForCheck();
123
+ return;
124
+ }
114
125
 
115
126
  // data-only change on a stable shape → let the engine morph the values
116
127
  const keys = Object.keys(changes);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cordova-plugin-ra-chart",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
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",
@@ -39,4 +39,4 @@
39
39
  "www/ra-chart.js",
40
40
  "www/ra-chart.css"
41
41
  ]
42
- }
42
+ }
package/www/ra-chart.js CHANGED
@@ -527,11 +527,54 @@
527
527
  this.kind = KINDS[o.type] || "xy";
528
528
  this.zoomable = !!o.zoom && (this.kind === "xy" || this.kind === "candle");
529
529
 
530
+ this._validate();
530
531
  if (this.zoomable) this._buildZoomBar();
531
532
  this._scaffoldBody();
532
533
  this._dispatchBuild(entrance);
533
534
  };
534
535
 
536
+ /**
537
+ * A blank chart is almost always a naming mismatch rather than a rendering
538
+ * fault: `field` or `category` pointing at keys the rows do not have reads
539
+ * every value as 0 and draws nothing. Say so instead of failing silently.
540
+ * Warns once per chart, and never in production-silent mode.
541
+ */
542
+ RaChart.prototype._validate = function () {
543
+ if (this._validated || !RaChart.warnings) return;
544
+ this._validated = true;
545
+
546
+ var o = this.opts;
547
+ var rows = o.data || [];
548
+ if (!rows.length || !rows[0] || typeof rows[0] !== "object") return;
549
+ var keys = Object.keys(rows[0]);
550
+ var problems = [];
551
+
552
+ if (this.kind === "sankey") {
553
+ var F = merge({ from: "from", to: "to", value: "value" }, o.fields || {});
554
+ ["from", "to", "value"].forEach(function (k) {
555
+ if (keys.indexOf(F[k]) < 0) problems.push('sankey ' + k + ' field "' + F[k] + '"');
556
+ });
557
+ } else {
558
+ (o.series || []).forEach(function (s) {
559
+ if (!s || !s.field) { problems.push("a series with no `field`"); return; }
560
+ var found = rows.some(function (r) { return r && r[s.field] !== undefined; });
561
+ if (!found) problems.push('series "' + (s.name || s.field) + '" field "' + s.field + '"');
562
+ });
563
+ if (this.kind !== "scatter" && this.kind !== "gauge" &&
564
+ rows[0][o.category] === undefined) {
565
+ problems.push('category "' + o.category + '"');
566
+ }
567
+ }
568
+
569
+ if (problems.length) {
570
+ console.warn(
571
+ "[raChart] nothing to plot — " + problems.join(", ") +
572
+ " not found in the data. Your rows have: " + keys.join(", ") +
573
+ ". Check the `field`/`category` names against your data keys."
574
+ );
575
+ }
576
+ };
577
+
535
578
  RaChart.prototype._scaffoldBody = function () {
536
579
  var o = this.opts;
537
580
  this.stage = el("div", "ra-chart__stage", this.el);
@@ -2804,6 +2847,8 @@
2804
2847
  /* ---------- statics ---------- */
2805
2848
 
2806
2849
  RaChart.version = VERSION;
2850
+ /** Set false to silence the "nothing to plot" console diagnostics. */
2851
+ RaChart.warnings = true;
2807
2852
  RaChart.defaults = DEFAULTS;
2808
2853
  RaChart.palette = PALETTE_LIGHT;
2809
2854
  RaChart.paletteDark = PALETTE_DARK;