myio-js-library 0.1.210 → 0.1.212
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 +95 -21
- package/dist/index.js +95 -21
- package/dist/myio-js-library.umd.js +95 -21
- package/dist/myio-js-library.umd.min.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -21457,9 +21457,14 @@ var WaterTankModalView = class {
|
|
|
21457
21457
|
overlay = null;
|
|
21458
21458
|
modal = null;
|
|
21459
21459
|
i18n;
|
|
21460
|
+
chartDisplayMode = "water_level";
|
|
21461
|
+
// RFC-0107: Default to water_level (m.c.a)
|
|
21460
21462
|
constructor(config) {
|
|
21461
21463
|
this.config = config;
|
|
21462
21464
|
this.i18n = this.getI18n();
|
|
21465
|
+
if (config.params.displayKey) {
|
|
21466
|
+
this.chartDisplayMode = config.params.displayKey;
|
|
21467
|
+
}
|
|
21463
21468
|
}
|
|
21464
21469
|
/**
|
|
21465
21470
|
* Get i18n strings with defaults
|
|
@@ -21771,14 +21776,14 @@ var WaterTankModalView = class {
|
|
|
21771
21776
|
`;
|
|
21772
21777
|
}
|
|
21773
21778
|
/**
|
|
21774
|
-
* Render chart section
|
|
21779
|
+
* RFC-0107: Render chart section with display mode selector
|
|
21780
|
+
* Shows water_level (m.c.a) or water_percentage (%) based on user selection
|
|
21775
21781
|
*/
|
|
21776
21782
|
renderChart() {
|
|
21777
21783
|
const { data } = this.config;
|
|
21778
|
-
const
|
|
21779
|
-
|
|
21780
|
-
|
|
21781
|
-
if (waterLevelPoints.length === 0) {
|
|
21784
|
+
const chartPoints = this.getChartDataPoints();
|
|
21785
|
+
if (chartPoints.length === 0) {
|
|
21786
|
+
const displayLabel = this.chartDisplayMode === "water_percentage" ? "%" : "m.c.a";
|
|
21782
21787
|
return `
|
|
21783
21788
|
<div style="
|
|
21784
21789
|
background: #f8f9fa;
|
|
@@ -21790,13 +21795,14 @@ var WaterTankModalView = class {
|
|
|
21790
21795
|
<div style="font-size: 48px; margin-bottom: 16px; opacity: 0.3;">\u{1F4CA}</div>
|
|
21791
21796
|
<div style="color: #7f8c8d; font-size: 16px;">${this.i18n.noData}</div>
|
|
21792
21797
|
<div style="color: #bdc3c7; font-size: 13px; margin-top: 8px;">
|
|
21793
|
-
No
|
|
21798
|
+
No ${this.chartDisplayMode} (${displayLabel}) data available for this period
|
|
21794
21799
|
</div>
|
|
21795
21800
|
</div>
|
|
21796
21801
|
`;
|
|
21797
21802
|
}
|
|
21798
|
-
const firstTs =
|
|
21799
|
-
const lastTs =
|
|
21803
|
+
const firstTs = chartPoints[0]?.ts;
|
|
21804
|
+
const lastTs = chartPoints[chartPoints.length - 1]?.ts;
|
|
21805
|
+
const chartTitle = this.chartDisplayMode === "water_percentage" ? "Water Level History (%)" : this.i18n.levelChart;
|
|
21800
21806
|
return `
|
|
21801
21807
|
<div style="
|
|
21802
21808
|
background: white;
|
|
@@ -21804,12 +21810,38 @@ var WaterTankModalView = class {
|
|
|
21804
21810
|
border-radius: 8px;
|
|
21805
21811
|
padding: 20px;
|
|
21806
21812
|
">
|
|
21807
|
-
<
|
|
21808
|
-
|
|
21809
|
-
|
|
21810
|
-
|
|
21811
|
-
|
|
21812
|
-
"
|
|
21813
|
+
<div style="
|
|
21814
|
+
display: flex;
|
|
21815
|
+
align-items: center;
|
|
21816
|
+
justify-content: space-between;
|
|
21817
|
+
margin-bottom: 16px;
|
|
21818
|
+
">
|
|
21819
|
+
<h3 style="
|
|
21820
|
+
margin: 0;
|
|
21821
|
+
font-size: 16px;
|
|
21822
|
+
font-weight: 600;
|
|
21823
|
+
color: #2c3e50;
|
|
21824
|
+
">${chartTitle}</h3>
|
|
21825
|
+
<div style="
|
|
21826
|
+
display: flex;
|
|
21827
|
+
align-items: center;
|
|
21828
|
+
gap: 8px;
|
|
21829
|
+
">
|
|
21830
|
+
<span style="font-size: 13px; color: #7f8c8d;">Display:</span>
|
|
21831
|
+
<select id="myio-water-tank-display-mode" style="
|
|
21832
|
+
padding: 6px 12px;
|
|
21833
|
+
border: 1px solid #ddd;
|
|
21834
|
+
border-radius: 6px;
|
|
21835
|
+
font-size: 13px;
|
|
21836
|
+
color: #2c3e50;
|
|
21837
|
+
background: white;
|
|
21838
|
+
cursor: pointer;
|
|
21839
|
+
">
|
|
21840
|
+
<option value="water_level" ${this.chartDisplayMode === "water_level" ? "selected" : ""}>Level (m.c.a)</option>
|
|
21841
|
+
<option value="water_percentage" ${this.chartDisplayMode === "water_percentage" ? "selected" : ""}>Percentage (%)</option>
|
|
21842
|
+
</select>
|
|
21843
|
+
</div>
|
|
21844
|
+
</div>
|
|
21813
21845
|
<canvas id="myio-water-tank-chart" style="width: 100%; height: 280px;"></canvas>
|
|
21814
21846
|
${firstTs && lastTs ? `
|
|
21815
21847
|
<div style="
|
|
@@ -21819,12 +21851,29 @@ var WaterTankModalView = class {
|
|
|
21819
21851
|
text-align: center;
|
|
21820
21852
|
">
|
|
21821
21853
|
${this.formatDate(firstTs, false)} \u2014 ${this.formatDate(lastTs, false)}
|
|
21822
|
-
(${
|
|
21854
|
+
(${chartPoints.length} readings)
|
|
21823
21855
|
</div>
|
|
21824
21856
|
` : ""}
|
|
21825
21857
|
</div>
|
|
21826
21858
|
`;
|
|
21827
21859
|
}
|
|
21860
|
+
/**
|
|
21861
|
+
* RFC-0107: Get chart data points based on current display mode
|
|
21862
|
+
*/
|
|
21863
|
+
getChartDataPoints() {
|
|
21864
|
+
const { data } = this.config;
|
|
21865
|
+
if (this.chartDisplayMode === "water_percentage") {
|
|
21866
|
+
const percentagePoints = data.telemetry.filter((p) => p.key === "water_percentage");
|
|
21867
|
+
return percentagePoints.map((p) => ({
|
|
21868
|
+
...p,
|
|
21869
|
+
value: p.value <= 1.5 ? p.value * 100 : p.value
|
|
21870
|
+
}));
|
|
21871
|
+
} else {
|
|
21872
|
+
return data.telemetry.filter(
|
|
21873
|
+
(p) => p.key === "water_level" || p.key === "waterLevel" || p.key === "nivel" || p.key === "level"
|
|
21874
|
+
);
|
|
21875
|
+
}
|
|
21876
|
+
}
|
|
21828
21877
|
/**
|
|
21829
21878
|
* Render footer with actions
|
|
21830
21879
|
*/
|
|
@@ -21874,6 +21923,13 @@ var WaterTankModalView = class {
|
|
|
21874
21923
|
if (applyDatesBtn) {
|
|
21875
21924
|
applyDatesBtn.addEventListener("click", () => this.handleDateRangeChange());
|
|
21876
21925
|
}
|
|
21926
|
+
const displayModeSelect = this.modal.querySelector("#myio-water-tank-display-mode");
|
|
21927
|
+
if (displayModeSelect) {
|
|
21928
|
+
displayModeSelect.addEventListener("change", () => {
|
|
21929
|
+
this.chartDisplayMode = displayModeSelect.value;
|
|
21930
|
+
this.refreshChart();
|
|
21931
|
+
});
|
|
21932
|
+
}
|
|
21877
21933
|
this.overlay.addEventListener("click", (e) => {
|
|
21878
21934
|
if (e.target === this.overlay) {
|
|
21879
21935
|
this.config.onClose();
|
|
@@ -21918,15 +21974,25 @@ var WaterTankModalView = class {
|
|
|
21918
21974
|
}
|
|
21919
21975
|
}
|
|
21920
21976
|
/**
|
|
21921
|
-
*
|
|
21977
|
+
* RFC-0107: Refresh chart when display mode changes
|
|
21978
|
+
*/
|
|
21979
|
+
refreshChart() {
|
|
21980
|
+
if (!this.modal) return;
|
|
21981
|
+
const chartTitle = this.chartDisplayMode === "water_percentage" ? "Water Level History (%)" : this.i18n.levelChart;
|
|
21982
|
+
const titleEl = this.modal.querySelector(".myio-water-tank-modal-body h3:last-of-type");
|
|
21983
|
+
if (titleEl) {
|
|
21984
|
+
titleEl.textContent = chartTitle;
|
|
21985
|
+
}
|
|
21986
|
+
this.renderCanvasChart();
|
|
21987
|
+
}
|
|
21988
|
+
/**
|
|
21989
|
+
* RFC-0107: Render chart using Canvas API
|
|
21990
|
+
* Shows water_level (m.c.a) or water_percentage (%) based on display mode
|
|
21922
21991
|
*/
|
|
21923
21992
|
renderCanvasChart() {
|
|
21924
21993
|
const canvas = document.getElementById("myio-water-tank-chart");
|
|
21925
21994
|
if (!canvas) return;
|
|
21926
|
-
const
|
|
21927
|
-
const points = data.telemetry.filter(
|
|
21928
|
-
(p) => p.key === "water_level" || p.key === "waterLevel" || p.key === "nivel" || p.key === "level"
|
|
21929
|
-
);
|
|
21995
|
+
const points = this.getChartDataPoints();
|
|
21930
21996
|
if (points.length < 2) return;
|
|
21931
21997
|
const ctx = canvas.getContext("2d");
|
|
21932
21998
|
if (!ctx) return;
|
|
@@ -21963,13 +22029,14 @@ var WaterTankModalView = class {
|
|
|
21963
22029
|
ctx.stroke();
|
|
21964
22030
|
ctx.fillText(`${value.toFixed(2)}`, padding.left - 8, y + 4);
|
|
21965
22031
|
}
|
|
22032
|
+
const yAxisLabel = this.chartDisplayMode === "water_percentage" ? "%" : "m.c.a";
|
|
21966
22033
|
ctx.save();
|
|
21967
22034
|
ctx.translate(15, height / 2);
|
|
21968
22035
|
ctx.rotate(-Math.PI / 2);
|
|
21969
22036
|
ctx.textAlign = "center";
|
|
21970
22037
|
ctx.fillStyle = "#666";
|
|
21971
22038
|
ctx.font = "12px Arial";
|
|
21972
|
-
ctx.fillText(
|
|
22039
|
+
ctx.fillText(yAxisLabel, 0, 0);
|
|
21973
22040
|
ctx.restore();
|
|
21974
22041
|
ctx.strokeStyle = "#ccc";
|
|
21975
22042
|
ctx.lineWidth = 1;
|
|
@@ -22055,6 +22122,13 @@ var WaterTankModalView = class {
|
|
|
22055
22122
|
if (applyDatesBtn) {
|
|
22056
22123
|
applyDatesBtn.addEventListener("click", () => this.handleDateRangeChange());
|
|
22057
22124
|
}
|
|
22125
|
+
const displayModeSelect = this.modal.querySelector("#myio-water-tank-display-mode");
|
|
22126
|
+
if (displayModeSelect) {
|
|
22127
|
+
displayModeSelect.addEventListener("change", () => {
|
|
22128
|
+
this.chartDisplayMode = displayModeSelect.value;
|
|
22129
|
+
this.refreshChart();
|
|
22130
|
+
});
|
|
22131
|
+
}
|
|
22058
22132
|
requestAnimationFrame(() => {
|
|
22059
22133
|
this.renderCanvasChart();
|
|
22060
22134
|
});
|
package/dist/index.js
CHANGED
|
@@ -21285,9 +21285,14 @@ var WaterTankModalView = class {
|
|
|
21285
21285
|
overlay = null;
|
|
21286
21286
|
modal = null;
|
|
21287
21287
|
i18n;
|
|
21288
|
+
chartDisplayMode = "water_level";
|
|
21289
|
+
// RFC-0107: Default to water_level (m.c.a)
|
|
21288
21290
|
constructor(config) {
|
|
21289
21291
|
this.config = config;
|
|
21290
21292
|
this.i18n = this.getI18n();
|
|
21293
|
+
if (config.params.displayKey) {
|
|
21294
|
+
this.chartDisplayMode = config.params.displayKey;
|
|
21295
|
+
}
|
|
21291
21296
|
}
|
|
21292
21297
|
/**
|
|
21293
21298
|
* Get i18n strings with defaults
|
|
@@ -21599,14 +21604,14 @@ var WaterTankModalView = class {
|
|
|
21599
21604
|
`;
|
|
21600
21605
|
}
|
|
21601
21606
|
/**
|
|
21602
|
-
* Render chart section
|
|
21607
|
+
* RFC-0107: Render chart section with display mode selector
|
|
21608
|
+
* Shows water_level (m.c.a) or water_percentage (%) based on user selection
|
|
21603
21609
|
*/
|
|
21604
21610
|
renderChart() {
|
|
21605
21611
|
const { data } = this.config;
|
|
21606
|
-
const
|
|
21607
|
-
|
|
21608
|
-
|
|
21609
|
-
if (waterLevelPoints.length === 0) {
|
|
21612
|
+
const chartPoints = this.getChartDataPoints();
|
|
21613
|
+
if (chartPoints.length === 0) {
|
|
21614
|
+
const displayLabel = this.chartDisplayMode === "water_percentage" ? "%" : "m.c.a";
|
|
21610
21615
|
return `
|
|
21611
21616
|
<div style="
|
|
21612
21617
|
background: #f8f9fa;
|
|
@@ -21618,13 +21623,14 @@ var WaterTankModalView = class {
|
|
|
21618
21623
|
<div style="font-size: 48px; margin-bottom: 16px; opacity: 0.3;">\u{1F4CA}</div>
|
|
21619
21624
|
<div style="color: #7f8c8d; font-size: 16px;">${this.i18n.noData}</div>
|
|
21620
21625
|
<div style="color: #bdc3c7; font-size: 13px; margin-top: 8px;">
|
|
21621
|
-
No
|
|
21626
|
+
No ${this.chartDisplayMode} (${displayLabel}) data available for this period
|
|
21622
21627
|
</div>
|
|
21623
21628
|
</div>
|
|
21624
21629
|
`;
|
|
21625
21630
|
}
|
|
21626
|
-
const firstTs =
|
|
21627
|
-
const lastTs =
|
|
21631
|
+
const firstTs = chartPoints[0]?.ts;
|
|
21632
|
+
const lastTs = chartPoints[chartPoints.length - 1]?.ts;
|
|
21633
|
+
const chartTitle = this.chartDisplayMode === "water_percentage" ? "Water Level History (%)" : this.i18n.levelChart;
|
|
21628
21634
|
return `
|
|
21629
21635
|
<div style="
|
|
21630
21636
|
background: white;
|
|
@@ -21632,12 +21638,38 @@ var WaterTankModalView = class {
|
|
|
21632
21638
|
border-radius: 8px;
|
|
21633
21639
|
padding: 20px;
|
|
21634
21640
|
">
|
|
21635
|
-
<
|
|
21636
|
-
|
|
21637
|
-
|
|
21638
|
-
|
|
21639
|
-
|
|
21640
|
-
"
|
|
21641
|
+
<div style="
|
|
21642
|
+
display: flex;
|
|
21643
|
+
align-items: center;
|
|
21644
|
+
justify-content: space-between;
|
|
21645
|
+
margin-bottom: 16px;
|
|
21646
|
+
">
|
|
21647
|
+
<h3 style="
|
|
21648
|
+
margin: 0;
|
|
21649
|
+
font-size: 16px;
|
|
21650
|
+
font-weight: 600;
|
|
21651
|
+
color: #2c3e50;
|
|
21652
|
+
">${chartTitle}</h3>
|
|
21653
|
+
<div style="
|
|
21654
|
+
display: flex;
|
|
21655
|
+
align-items: center;
|
|
21656
|
+
gap: 8px;
|
|
21657
|
+
">
|
|
21658
|
+
<span style="font-size: 13px; color: #7f8c8d;">Display:</span>
|
|
21659
|
+
<select id="myio-water-tank-display-mode" style="
|
|
21660
|
+
padding: 6px 12px;
|
|
21661
|
+
border: 1px solid #ddd;
|
|
21662
|
+
border-radius: 6px;
|
|
21663
|
+
font-size: 13px;
|
|
21664
|
+
color: #2c3e50;
|
|
21665
|
+
background: white;
|
|
21666
|
+
cursor: pointer;
|
|
21667
|
+
">
|
|
21668
|
+
<option value="water_level" ${this.chartDisplayMode === "water_level" ? "selected" : ""}>Level (m.c.a)</option>
|
|
21669
|
+
<option value="water_percentage" ${this.chartDisplayMode === "water_percentage" ? "selected" : ""}>Percentage (%)</option>
|
|
21670
|
+
</select>
|
|
21671
|
+
</div>
|
|
21672
|
+
</div>
|
|
21641
21673
|
<canvas id="myio-water-tank-chart" style="width: 100%; height: 280px;"></canvas>
|
|
21642
21674
|
${firstTs && lastTs ? `
|
|
21643
21675
|
<div style="
|
|
@@ -21647,12 +21679,29 @@ var WaterTankModalView = class {
|
|
|
21647
21679
|
text-align: center;
|
|
21648
21680
|
">
|
|
21649
21681
|
${this.formatDate(firstTs, false)} \u2014 ${this.formatDate(lastTs, false)}
|
|
21650
|
-
(${
|
|
21682
|
+
(${chartPoints.length} readings)
|
|
21651
21683
|
</div>
|
|
21652
21684
|
` : ""}
|
|
21653
21685
|
</div>
|
|
21654
21686
|
`;
|
|
21655
21687
|
}
|
|
21688
|
+
/**
|
|
21689
|
+
* RFC-0107: Get chart data points based on current display mode
|
|
21690
|
+
*/
|
|
21691
|
+
getChartDataPoints() {
|
|
21692
|
+
const { data } = this.config;
|
|
21693
|
+
if (this.chartDisplayMode === "water_percentage") {
|
|
21694
|
+
const percentagePoints = data.telemetry.filter((p) => p.key === "water_percentage");
|
|
21695
|
+
return percentagePoints.map((p) => ({
|
|
21696
|
+
...p,
|
|
21697
|
+
value: p.value <= 1.5 ? p.value * 100 : p.value
|
|
21698
|
+
}));
|
|
21699
|
+
} else {
|
|
21700
|
+
return data.telemetry.filter(
|
|
21701
|
+
(p) => p.key === "water_level" || p.key === "waterLevel" || p.key === "nivel" || p.key === "level"
|
|
21702
|
+
);
|
|
21703
|
+
}
|
|
21704
|
+
}
|
|
21656
21705
|
/**
|
|
21657
21706
|
* Render footer with actions
|
|
21658
21707
|
*/
|
|
@@ -21702,6 +21751,13 @@ var WaterTankModalView = class {
|
|
|
21702
21751
|
if (applyDatesBtn) {
|
|
21703
21752
|
applyDatesBtn.addEventListener("click", () => this.handleDateRangeChange());
|
|
21704
21753
|
}
|
|
21754
|
+
const displayModeSelect = this.modal.querySelector("#myio-water-tank-display-mode");
|
|
21755
|
+
if (displayModeSelect) {
|
|
21756
|
+
displayModeSelect.addEventListener("change", () => {
|
|
21757
|
+
this.chartDisplayMode = displayModeSelect.value;
|
|
21758
|
+
this.refreshChart();
|
|
21759
|
+
});
|
|
21760
|
+
}
|
|
21705
21761
|
this.overlay.addEventListener("click", (e) => {
|
|
21706
21762
|
if (e.target === this.overlay) {
|
|
21707
21763
|
this.config.onClose();
|
|
@@ -21746,15 +21802,25 @@ var WaterTankModalView = class {
|
|
|
21746
21802
|
}
|
|
21747
21803
|
}
|
|
21748
21804
|
/**
|
|
21749
|
-
*
|
|
21805
|
+
* RFC-0107: Refresh chart when display mode changes
|
|
21806
|
+
*/
|
|
21807
|
+
refreshChart() {
|
|
21808
|
+
if (!this.modal) return;
|
|
21809
|
+
const chartTitle = this.chartDisplayMode === "water_percentage" ? "Water Level History (%)" : this.i18n.levelChart;
|
|
21810
|
+
const titleEl = this.modal.querySelector(".myio-water-tank-modal-body h3:last-of-type");
|
|
21811
|
+
if (titleEl) {
|
|
21812
|
+
titleEl.textContent = chartTitle;
|
|
21813
|
+
}
|
|
21814
|
+
this.renderCanvasChart();
|
|
21815
|
+
}
|
|
21816
|
+
/**
|
|
21817
|
+
* RFC-0107: Render chart using Canvas API
|
|
21818
|
+
* Shows water_level (m.c.a) or water_percentage (%) based on display mode
|
|
21750
21819
|
*/
|
|
21751
21820
|
renderCanvasChart() {
|
|
21752
21821
|
const canvas = document.getElementById("myio-water-tank-chart");
|
|
21753
21822
|
if (!canvas) return;
|
|
21754
|
-
const
|
|
21755
|
-
const points = data.telemetry.filter(
|
|
21756
|
-
(p) => p.key === "water_level" || p.key === "waterLevel" || p.key === "nivel" || p.key === "level"
|
|
21757
|
-
);
|
|
21823
|
+
const points = this.getChartDataPoints();
|
|
21758
21824
|
if (points.length < 2) return;
|
|
21759
21825
|
const ctx = canvas.getContext("2d");
|
|
21760
21826
|
if (!ctx) return;
|
|
@@ -21791,13 +21857,14 @@ var WaterTankModalView = class {
|
|
|
21791
21857
|
ctx.stroke();
|
|
21792
21858
|
ctx.fillText(`${value.toFixed(2)}`, padding.left - 8, y + 4);
|
|
21793
21859
|
}
|
|
21860
|
+
const yAxisLabel = this.chartDisplayMode === "water_percentage" ? "%" : "m.c.a";
|
|
21794
21861
|
ctx.save();
|
|
21795
21862
|
ctx.translate(15, height / 2);
|
|
21796
21863
|
ctx.rotate(-Math.PI / 2);
|
|
21797
21864
|
ctx.textAlign = "center";
|
|
21798
21865
|
ctx.fillStyle = "#666";
|
|
21799
21866
|
ctx.font = "12px Arial";
|
|
21800
|
-
ctx.fillText(
|
|
21867
|
+
ctx.fillText(yAxisLabel, 0, 0);
|
|
21801
21868
|
ctx.restore();
|
|
21802
21869
|
ctx.strokeStyle = "#ccc";
|
|
21803
21870
|
ctx.lineWidth = 1;
|
|
@@ -21883,6 +21950,13 @@ var WaterTankModalView = class {
|
|
|
21883
21950
|
if (applyDatesBtn) {
|
|
21884
21951
|
applyDatesBtn.addEventListener("click", () => this.handleDateRangeChange());
|
|
21885
21952
|
}
|
|
21953
|
+
const displayModeSelect = this.modal.querySelector("#myio-water-tank-display-mode");
|
|
21954
|
+
if (displayModeSelect) {
|
|
21955
|
+
displayModeSelect.addEventListener("change", () => {
|
|
21956
|
+
this.chartDisplayMode = displayModeSelect.value;
|
|
21957
|
+
this.refreshChart();
|
|
21958
|
+
});
|
|
21959
|
+
}
|
|
21886
21960
|
requestAnimationFrame(() => {
|
|
21887
21961
|
this.renderCanvasChart();
|
|
21888
21962
|
});
|
|
@@ -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
|
});
|