myio-js-library 0.1.211 → 0.1.213
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/dist/index.cjs +103 -34
- package/dist/index.js +103 -34
- package/dist/myio-js-library.umd.js +103 -34
- package/dist/myio-js-library.umd.min.js +1 -1
- package/package.json +1 -1
|
@@ -21099,9 +21099,14 @@
|
|
|
21099
21099
|
overlay = null;
|
|
21100
21100
|
modal = null;
|
|
21101
21101
|
i18n;
|
|
21102
|
+
chartDisplayMode = "water_level";
|
|
21103
|
+
// RFC-0107: Default to water_level (m.c.a)
|
|
21102
21104
|
constructor(config) {
|
|
21103
21105
|
this.config = config;
|
|
21104
21106
|
this.i18n = this.getI18n();
|
|
21107
|
+
if (config.params.displayKey) {
|
|
21108
|
+
this.chartDisplayMode = config.params.displayKey;
|
|
21109
|
+
}
|
|
21105
21110
|
}
|
|
21106
21111
|
/**
|
|
21107
21112
|
* Get i18n strings with defaults
|
|
@@ -21413,14 +21418,14 @@
|
|
|
21413
21418
|
`;
|
|
21414
21419
|
}
|
|
21415
21420
|
/**
|
|
21416
|
-
* Render chart section
|
|
21421
|
+
* RFC-0107: Render chart section with display mode selector
|
|
21422
|
+
* Shows water_level (m.c.a) or water_percentage (%) based on user selection
|
|
21417
21423
|
*/
|
|
21418
21424
|
renderChart() {
|
|
21419
21425
|
const { data } = this.config;
|
|
21420
|
-
const
|
|
21421
|
-
|
|
21422
|
-
|
|
21423
|
-
if (waterLevelPoints.length === 0) {
|
|
21426
|
+
const chartPoints = this.getChartDataPoints();
|
|
21427
|
+
if (chartPoints.length === 0) {
|
|
21428
|
+
const displayLabel = this.chartDisplayMode === "water_percentage" ? "%" : "m.c.a";
|
|
21424
21429
|
return `
|
|
21425
21430
|
<div style="
|
|
21426
21431
|
background: #f8f9fa;
|
|
@@ -21432,13 +21437,14 @@
|
|
|
21432
21437
|
<div style="font-size: 48px; margin-bottom: 16px; opacity: 0.3;">\u{1F4CA}</div>
|
|
21433
21438
|
<div style="color: #7f8c8d; font-size: 16px;">${this.i18n.noData}</div>
|
|
21434
21439
|
<div style="color: #bdc3c7; font-size: 13px; margin-top: 8px;">
|
|
21435
|
-
No
|
|
21440
|
+
No ${this.chartDisplayMode} (${displayLabel}) data available for this period
|
|
21436
21441
|
</div>
|
|
21437
21442
|
</div>
|
|
21438
21443
|
`;
|
|
21439
21444
|
}
|
|
21440
|
-
const firstTs =
|
|
21441
|
-
const lastTs =
|
|
21445
|
+
const firstTs = chartPoints[0]?.ts;
|
|
21446
|
+
const lastTs = chartPoints[chartPoints.length - 1]?.ts;
|
|
21447
|
+
const chartTitle = this.chartDisplayMode === "water_percentage" ? "Water Level History (%)" : this.i18n.levelChart;
|
|
21442
21448
|
return `
|
|
21443
21449
|
<div style="
|
|
21444
21450
|
background: white;
|
|
@@ -21446,12 +21452,38 @@
|
|
|
21446
21452
|
border-radius: 8px;
|
|
21447
21453
|
padding: 20px;
|
|
21448
21454
|
">
|
|
21449
|
-
<
|
|
21450
|
-
|
|
21451
|
-
|
|
21452
|
-
|
|
21453
|
-
|
|
21454
|
-
"
|
|
21455
|
+
<div style="
|
|
21456
|
+
display: flex;
|
|
21457
|
+
align-items: center;
|
|
21458
|
+
justify-content: space-between;
|
|
21459
|
+
margin-bottom: 16px;
|
|
21460
|
+
">
|
|
21461
|
+
<h3 style="
|
|
21462
|
+
margin: 0;
|
|
21463
|
+
font-size: 16px;
|
|
21464
|
+
font-weight: 600;
|
|
21465
|
+
color: #2c3e50;
|
|
21466
|
+
">${chartTitle}</h3>
|
|
21467
|
+
<div style="
|
|
21468
|
+
display: flex;
|
|
21469
|
+
align-items: center;
|
|
21470
|
+
gap: 8px;
|
|
21471
|
+
">
|
|
21472
|
+
<span style="font-size: 13px; color: #7f8c8d;">Display:</span>
|
|
21473
|
+
<select id="myio-water-tank-display-mode" style="
|
|
21474
|
+
padding: 6px 12px;
|
|
21475
|
+
border: 1px solid #ddd;
|
|
21476
|
+
border-radius: 6px;
|
|
21477
|
+
font-size: 13px;
|
|
21478
|
+
color: #2c3e50;
|
|
21479
|
+
background: white;
|
|
21480
|
+
cursor: pointer;
|
|
21481
|
+
">
|
|
21482
|
+
<option value="water_level" ${this.chartDisplayMode === "water_level" ? "selected" : ""}>Level (m.c.a)</option>
|
|
21483
|
+
<option value="water_percentage" ${this.chartDisplayMode === "water_percentage" ? "selected" : ""}>Percentage (%)</option>
|
|
21484
|
+
</select>
|
|
21485
|
+
</div>
|
|
21486
|
+
</div>
|
|
21455
21487
|
<canvas id="myio-water-tank-chart" style="width: 100%; height: 280px;"></canvas>
|
|
21456
21488
|
${firstTs && lastTs ? `
|
|
21457
21489
|
<div style="
|
|
@@ -21461,12 +21493,29 @@
|
|
|
21461
21493
|
text-align: center;
|
|
21462
21494
|
">
|
|
21463
21495
|
${this.formatDate(firstTs, false)} \u2014 ${this.formatDate(lastTs, false)}
|
|
21464
|
-
(${
|
|
21496
|
+
(${chartPoints.length} readings)
|
|
21465
21497
|
</div>
|
|
21466
21498
|
` : ""}
|
|
21467
21499
|
</div>
|
|
21468
21500
|
`;
|
|
21469
21501
|
}
|
|
21502
|
+
/**
|
|
21503
|
+
* RFC-0107: Get chart data points based on current display mode
|
|
21504
|
+
*/
|
|
21505
|
+
getChartDataPoints() {
|
|
21506
|
+
const { data } = this.config;
|
|
21507
|
+
if (this.chartDisplayMode === "water_percentage") {
|
|
21508
|
+
const percentagePoints = data.telemetry.filter((p) => p.key === "water_percentage");
|
|
21509
|
+
return percentagePoints.map((p) => ({
|
|
21510
|
+
...p,
|
|
21511
|
+
value: p.value <= 1.5 ? p.value * 100 : p.value
|
|
21512
|
+
}));
|
|
21513
|
+
} else {
|
|
21514
|
+
return data.telemetry.filter(
|
|
21515
|
+
(p) => p.key === "water_level" || p.key === "waterLevel" || p.key === "nivel" || p.key === "level"
|
|
21516
|
+
);
|
|
21517
|
+
}
|
|
21518
|
+
}
|
|
21470
21519
|
/**
|
|
21471
21520
|
* Render footer with actions
|
|
21472
21521
|
*/
|
|
@@ -21516,6 +21565,13 @@
|
|
|
21516
21565
|
if (applyDatesBtn) {
|
|
21517
21566
|
applyDatesBtn.addEventListener("click", () => this.handleDateRangeChange());
|
|
21518
21567
|
}
|
|
21568
|
+
const displayModeSelect = this.modal.querySelector("#myio-water-tank-display-mode");
|
|
21569
|
+
if (displayModeSelect) {
|
|
21570
|
+
displayModeSelect.addEventListener("change", () => {
|
|
21571
|
+
this.chartDisplayMode = displayModeSelect.value;
|
|
21572
|
+
this.refreshChart();
|
|
21573
|
+
});
|
|
21574
|
+
}
|
|
21519
21575
|
this.overlay.addEventListener("click", (e) => {
|
|
21520
21576
|
if (e.target === this.overlay) {
|
|
21521
21577
|
this.config.onClose();
|
|
@@ -21560,15 +21616,25 @@
|
|
|
21560
21616
|
}
|
|
21561
21617
|
}
|
|
21562
21618
|
/**
|
|
21563
|
-
*
|
|
21619
|
+
* RFC-0107: Refresh chart when display mode changes
|
|
21620
|
+
*/
|
|
21621
|
+
refreshChart() {
|
|
21622
|
+
if (!this.modal) return;
|
|
21623
|
+
const chartTitle = this.chartDisplayMode === "water_percentage" ? "Water Level History (%)" : this.i18n.levelChart;
|
|
21624
|
+
const titleEl = this.modal.querySelector(".myio-water-tank-modal-body h3:last-of-type");
|
|
21625
|
+
if (titleEl) {
|
|
21626
|
+
titleEl.textContent = chartTitle;
|
|
21627
|
+
}
|
|
21628
|
+
this.renderCanvasChart();
|
|
21629
|
+
}
|
|
21630
|
+
/**
|
|
21631
|
+
* RFC-0107: Render chart using Canvas API
|
|
21632
|
+
* Shows water_level (m.c.a) or water_percentage (%) based on display mode
|
|
21564
21633
|
*/
|
|
21565
21634
|
renderCanvasChart() {
|
|
21566
21635
|
const canvas = document.getElementById("myio-water-tank-chart");
|
|
21567
21636
|
if (!canvas) return;
|
|
21568
|
-
const
|
|
21569
|
-
const points = data.telemetry.filter(
|
|
21570
|
-
(p) => p.key === "water_level" || p.key === "waterLevel" || p.key === "nivel" || p.key === "level"
|
|
21571
|
-
);
|
|
21637
|
+
const points = this.getChartDataPoints();
|
|
21572
21638
|
if (points.length < 2) return;
|
|
21573
21639
|
const ctx = canvas.getContext("2d");
|
|
21574
21640
|
if (!ctx) return;
|
|
@@ -21605,13 +21671,14 @@
|
|
|
21605
21671
|
ctx.stroke();
|
|
21606
21672
|
ctx.fillText(`${value.toFixed(2)}`, padding.left - 8, y + 4);
|
|
21607
21673
|
}
|
|
21674
|
+
const yAxisLabel = this.chartDisplayMode === "water_percentage" ? "%" : "m.c.a";
|
|
21608
21675
|
ctx.save();
|
|
21609
21676
|
ctx.translate(15, height / 2);
|
|
21610
21677
|
ctx.rotate(-Math.PI / 2);
|
|
21611
21678
|
ctx.textAlign = "center";
|
|
21612
21679
|
ctx.fillStyle = "#666";
|
|
21613
21680
|
ctx.font = "12px Arial";
|
|
21614
|
-
ctx.fillText(
|
|
21681
|
+
ctx.fillText(yAxisLabel, 0, 0);
|
|
21615
21682
|
ctx.restore();
|
|
21616
21683
|
ctx.strokeStyle = "#ccc";
|
|
21617
21684
|
ctx.lineWidth = 1;
|
|
@@ -21697,6 +21764,13 @@
|
|
|
21697
21764
|
if (applyDatesBtn) {
|
|
21698
21765
|
applyDatesBtn.addEventListener("click", () => this.handleDateRangeChange());
|
|
21699
21766
|
}
|
|
21767
|
+
const displayModeSelect = this.modal.querySelector("#myio-water-tank-display-mode");
|
|
21768
|
+
if (displayModeSelect) {
|
|
21769
|
+
displayModeSelect.addEventListener("change", () => {
|
|
21770
|
+
this.chartDisplayMode = displayModeSelect.value;
|
|
21771
|
+
this.refreshChart();
|
|
21772
|
+
});
|
|
21773
|
+
}
|
|
21700
21774
|
requestAnimationFrame(() => {
|
|
21701
21775
|
this.renderCanvasChart();
|
|
21702
21776
|
});
|
|
@@ -21869,13 +21943,12 @@
|
|
|
21869
21943
|
}
|
|
21870
21944
|
/**
|
|
21871
21945
|
* Transform raw ThingsBoard response to our data points
|
|
21872
|
-
* RFC-0107:
|
|
21946
|
+
* RFC-0107: Keep ALL data points with their original keys (no deduplication)
|
|
21947
|
+
* This allows the chart to switch between water_level and water_percentage dynamically
|
|
21873
21948
|
*/
|
|
21874
21949
|
transformTelemetryData(rawData, keys) {
|
|
21875
21950
|
const allPoints = [];
|
|
21876
|
-
const
|
|
21877
|
-
const prioritizedKeys = rawData[displayKey] ? [displayKey, ...keys.filter((k) => k !== displayKey)] : keys;
|
|
21878
|
-
for (const key of prioritizedKeys) {
|
|
21951
|
+
for (const key of keys) {
|
|
21879
21952
|
if (rawData[key] && Array.isArray(rawData[key])) {
|
|
21880
21953
|
const keyPoints = rawData[key].map((point) => {
|
|
21881
21954
|
let value = typeof point.value === "string" ? parseFloat(point.value) : point.value;
|
|
@@ -21892,16 +21965,12 @@
|
|
|
21892
21965
|
}
|
|
21893
21966
|
}
|
|
21894
21967
|
allPoints.sort((a, b) => a.ts - b.ts);
|
|
21895
|
-
const
|
|
21896
|
-
const
|
|
21897
|
-
|
|
21898
|
-
if (!seenTimestamps.has(point.ts)) {
|
|
21899
|
-
seenTimestamps.add(point.ts);
|
|
21900
|
-
uniquePoints.push(point);
|
|
21901
|
-
}
|
|
21968
|
+
const keyCounts = {};
|
|
21969
|
+
for (const p of allPoints) {
|
|
21970
|
+
keyCounts[p.key || "unknown"] = (keyCounts[p.key || "unknown"] || 0) + 1;
|
|
21902
21971
|
}
|
|
21903
|
-
console.log(`[WaterTankModal] Transformed ${
|
|
21904
|
-
return
|
|
21972
|
+
console.log(`[WaterTankModal] Transformed ${allPoints.length} total points:`, keyCounts);
|
|
21973
|
+
return allPoints;
|
|
21905
21974
|
}
|
|
21906
21975
|
/**
|
|
21907
21976
|
* Calculate summary statistics from telemetry data
|