myio-js-library 0.1.164 → 0.1.166
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 +876 -88
- package/dist/index.d.cts +229 -9
- package/dist/index.js +865 -88
- package/dist/myio-js-library.umd.js +863 -88
- package/dist/myio-js-library.umd.min.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -574,6 +574,10 @@ __export(index_exports, {
|
|
|
574
574
|
CONSUMPTION_THEME_COLORS: () => THEME_COLORS,
|
|
575
575
|
ConnectionStatusType: () => ConnectionStatusType,
|
|
576
576
|
DEFAULT_CLAMP_RANGE: () => DEFAULT_CLAMP_RANGE,
|
|
577
|
+
DEFAULT_ENERGY_GROUP_COLORS: () => DEFAULT_ENERGY_GROUP_COLORS,
|
|
578
|
+
DEFAULT_GAS_GROUP_COLORS: () => DEFAULT_GAS_GROUP_COLORS,
|
|
579
|
+
DEFAULT_SHOPPING_COLORS: () => DEFAULT_SHOPPING_COLORS,
|
|
580
|
+
DEFAULT_WATER_GROUP_COLORS: () => DEFAULT_WATER_GROUP_COLORS,
|
|
577
581
|
DeviceStatusType: () => DeviceStatusType,
|
|
578
582
|
EXPORT_DEFAULT_COLORS: () => EXPORT_DEFAULT_COLORS,
|
|
579
583
|
EXPORT_DOMAIN_ICONS: () => EXPORT_DOMAIN_ICONS,
|
|
@@ -587,6 +591,7 @@ __export(index_exports, {
|
|
|
587
591
|
addDetectionContext: () => addDetectionContext,
|
|
588
592
|
addNamespace: () => addNamespace,
|
|
589
593
|
aggregateByDay: () => aggregateByDay,
|
|
594
|
+
assignShoppingColors: () => assignShoppingColors,
|
|
590
595
|
averageByDay: () => averageByDay,
|
|
591
596
|
buildListItemsThingsboardByUniqueDatasource: () => buildListItemsThingsboardByUniqueDatasource,
|
|
592
597
|
buildMyioIngestionAuth: () => buildMyioIngestionAuth,
|
|
@@ -608,6 +613,7 @@ __export(index_exports, {
|
|
|
608
613
|
createConsumptionChartWidget: () => createConsumptionChartWidget,
|
|
609
614
|
createConsumptionModal: () => createConsumptionModal,
|
|
610
615
|
createDateRangePicker: () => createDateRangePicker2,
|
|
616
|
+
createDistributionChartWidget: () => createDistributionChartWidget,
|
|
611
617
|
createInputDateRangePickerInsideDIV: () => createInputDateRangePickerInsideDIV,
|
|
612
618
|
createModalHeader: () => createModalHeader,
|
|
613
619
|
decodePayload: () => decodePayload,
|
|
@@ -646,11 +652,16 @@ __export(index_exports, {
|
|
|
646
652
|
getAvailableContexts: () => getAvailableContexts,
|
|
647
653
|
getConnectionStatusIcon: () => getConnectionStatusIcon,
|
|
648
654
|
getDateRangeArray: () => getDateRangeArray,
|
|
655
|
+
getDefaultGroupColors: () => getDefaultGroupColors,
|
|
649
656
|
getDeviceStatusIcon: () => getDeviceStatusIcon,
|
|
650
657
|
getDeviceStatusInfo: () => getDeviceStatusInfo,
|
|
658
|
+
getDistributionThemeColors: () => getThemeColors2,
|
|
659
|
+
getGroupColor: () => getGroupColor,
|
|
660
|
+
getHashColor: () => getHashColor,
|
|
651
661
|
getModalHeaderStyles: () => getModalHeaderStyles,
|
|
652
662
|
getSaoPauloISOString: () => getSaoPauloISOString,
|
|
653
663
|
getSaoPauloISOStringFixed: () => getSaoPauloISOStringFixed,
|
|
664
|
+
getShoppingColor: () => getShoppingColor,
|
|
654
665
|
getValueByDatakey: () => getValueByDatakey,
|
|
655
666
|
getValueByDatakeyLegacy: () => getValueByDatakeyLegacy,
|
|
656
667
|
getWaterCategories: () => getWaterCategories,
|
|
@@ -20657,7 +20668,7 @@ function renderModal(container, state, modalId, error) {
|
|
|
20657
20668
|
const contentMaxHeight = isMaximized ? "100vh" : "95vh";
|
|
20658
20669
|
const contentBorderRadius = isMaximized ? "0" : "10px";
|
|
20659
20670
|
container.innerHTML = `
|
|
20660
|
-
<div class="myio-temp-modal-overlay" style="
|
|
20671
|
+
<div class="myio-temp-modal-overlay myio-modal-scope" style="
|
|
20661
20672
|
position: fixed; top: 0; left: 0; width: 100%; height: 100%;
|
|
20662
20673
|
background: rgba(0, 0, 0, 0.5); z-index: 9998;
|
|
20663
20674
|
display: flex; justify-content: center; align-items: center;
|
|
@@ -20912,6 +20923,22 @@ function renderModal(container, state, modalId, error) {
|
|
|
20912
20923
|
background: rgba(255, 255, 255, 0.1) !important;
|
|
20913
20924
|
color: white !important;
|
|
20914
20925
|
}
|
|
20926
|
+
|
|
20927
|
+
/* DateRangePicker styles */
|
|
20928
|
+
${CSS_TOKENS}
|
|
20929
|
+
${DATERANGEPICKER_STYLES}
|
|
20930
|
+
|
|
20931
|
+
/* Fix DateRangePicker buttons alignment */
|
|
20932
|
+
.myio-modal-scope .daterangepicker .drp-buttons {
|
|
20933
|
+
display: flex;
|
|
20934
|
+
justify-content: flex-end;
|
|
20935
|
+
align-items: center;
|
|
20936
|
+
gap: 8px;
|
|
20937
|
+
}
|
|
20938
|
+
.myio-modal-scope .daterangepicker .drp-buttons .btn {
|
|
20939
|
+
display: inline-block;
|
|
20940
|
+
margin-left: 0;
|
|
20941
|
+
}
|
|
20915
20942
|
</style>
|
|
20916
20943
|
`;
|
|
20917
20944
|
}
|
|
@@ -23707,11 +23734,16 @@ function createConsumptionModal(config) {
|
|
|
23707
23734
|
let isMaximized = false;
|
|
23708
23735
|
const domainCfg = DOMAIN_CONFIG3[config.domain] || { name: config.domain, icon: "\u{1F4CA}" };
|
|
23709
23736
|
const title = config.title || `${domainCfg.name} - Hist\xF3rico de Consumo`;
|
|
23710
|
-
function
|
|
23737
|
+
function getThemeColors3() {
|
|
23711
23738
|
return THEME_COLORS[currentTheme];
|
|
23712
23739
|
}
|
|
23740
|
+
const consolidadoIcon = `<svg viewBox="0 0 16 16" fill="currentColor" style="width:14px;height:14px;pointer-events:none"><rect x="3" y="3" width="10" height="10" rx="2"/></svg>`;
|
|
23741
|
+
const porShoppingIcon = `<svg viewBox="0 0 16 16" fill="currentColor" style="width:14px;height:14px;pointer-events:none"><rect x="1" y="1" width="6" height="6" rx="1"/><rect x="9" y="1" width="6" height="6" rx="1"/><rect x="1" y="9" width="6" height="6" rx="1"/><rect x="9" y="9" width="6" height="6" rx="1"/></svg>`;
|
|
23742
|
+
const lineChartIcon = `<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:14px;height:14px;pointer-events:none"><polyline points="2,12 5,7 9,9 14,3"/></svg>`;
|
|
23743
|
+
const barChartIcon = `<svg viewBox="0 0 16 16" fill="currentColor" style="width:14px;height:14px;pointer-events:none"><rect x="1" y="9" width="3" height="6" rx="0.5"/><rect x="6" y="5" width="3" height="10" rx="0.5"/><rect x="11" y="7" width="3" height="8" rx="0.5"/></svg>`;
|
|
23744
|
+
const showSettingsButton = config.showSettingsButton ?? true;
|
|
23713
23745
|
function renderModal4() {
|
|
23714
|
-
const colors =
|
|
23746
|
+
const colors = getThemeColors3();
|
|
23715
23747
|
const exportFormats = config.exportFormats || ["csv"];
|
|
23716
23748
|
headerInstance = createModalHeader({
|
|
23717
23749
|
id: modalId,
|
|
@@ -23744,7 +23776,55 @@ function createConsumptionModal(config) {
|
|
|
23744
23776
|
instance.close();
|
|
23745
23777
|
}
|
|
23746
23778
|
});
|
|
23779
|
+
const btnBaseStyle = `
|
|
23780
|
+
display: flex;
|
|
23781
|
+
align-items: center;
|
|
23782
|
+
justify-content: center;
|
|
23783
|
+
gap: 6px;
|
|
23784
|
+
padding: 6px 12px;
|
|
23785
|
+
border: none;
|
|
23786
|
+
border-radius: 6px;
|
|
23787
|
+
font-size: 12px;
|
|
23788
|
+
font-weight: 500;
|
|
23789
|
+
cursor: pointer;
|
|
23790
|
+
transition: all 0.2s;
|
|
23791
|
+
white-space: nowrap;
|
|
23792
|
+
`.replace(/\s+/g, " ").trim();
|
|
23793
|
+
const tabBgColor = currentTheme === "dark" ? "#4b5563" : "#e5e7eb";
|
|
23794
|
+
const activeColor = "#3e1a7d";
|
|
23795
|
+
const inactiveTextColor = colors.text;
|
|
23747
23796
|
return `
|
|
23797
|
+
<style>
|
|
23798
|
+
.myio-modal-tab-btn {
|
|
23799
|
+
${btnBaseStyle}
|
|
23800
|
+
}
|
|
23801
|
+
.myio-modal-tab-btn:hover {
|
|
23802
|
+
opacity: 0.85;
|
|
23803
|
+
}
|
|
23804
|
+
.myio-modal-tab-btn.active {
|
|
23805
|
+
background: ${activeColor} !important;
|
|
23806
|
+
color: white !important;
|
|
23807
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
|
23808
|
+
}
|
|
23809
|
+
.myio-modal-tab-btn svg {
|
|
23810
|
+
pointer-events: none;
|
|
23811
|
+
}
|
|
23812
|
+
.myio-modal-settings-btn {
|
|
23813
|
+
background: transparent;
|
|
23814
|
+
border: 1px solid ${colors.border};
|
|
23815
|
+
font-size: 16px;
|
|
23816
|
+
cursor: pointer;
|
|
23817
|
+
padding: 6px 10px;
|
|
23818
|
+
border-radius: 6px;
|
|
23819
|
+
transition: all 0.2s;
|
|
23820
|
+
color: ${colors.text};
|
|
23821
|
+
}
|
|
23822
|
+
.myio-modal-settings-btn:hover {
|
|
23823
|
+
background: ${activeColor};
|
|
23824
|
+
border-color: ${activeColor};
|
|
23825
|
+
color: white;
|
|
23826
|
+
}
|
|
23827
|
+
</style>
|
|
23748
23828
|
<div class="myio-consumption-modal-overlay" style="
|
|
23749
23829
|
position: fixed;
|
|
23750
23830
|
top: 0;
|
|
@@ -23775,59 +23855,44 @@ function createConsumptionModal(config) {
|
|
|
23775
23855
|
<!-- Controls Bar -->
|
|
23776
23856
|
<div class="myio-consumption-modal-controls" style="
|
|
23777
23857
|
display: flex;
|
|
23778
|
-
gap:
|
|
23858
|
+
gap: 12px;
|
|
23779
23859
|
padding: 12px 16px;
|
|
23780
23860
|
background: ${currentTheme === "dark" ? "#374151" : "#f7f7f7"};
|
|
23781
23861
|
border-bottom: 1px solid ${colors.border};
|
|
23782
23862
|
align-items: center;
|
|
23783
23863
|
flex-wrap: wrap;
|
|
23784
23864
|
">
|
|
23865
|
+
<!-- Settings Button -->
|
|
23866
|
+
${showSettingsButton ? `
|
|
23867
|
+
<button id="${modalId}-settings-btn" class="myio-modal-settings-btn" title="Configura\xE7\xF5es">\u2699\uFE0F</button>
|
|
23868
|
+
` : ""}
|
|
23869
|
+
|
|
23785
23870
|
<!-- Viz Mode Tabs -->
|
|
23786
|
-
<div style="display: flex; gap: 2px; background: ${
|
|
23787
|
-
<button id="${modalId}-viz-total"
|
|
23788
|
-
|
|
23789
|
-
|
|
23790
|
-
|
|
23791
|
-
|
|
23792
|
-
|
|
23793
|
-
|
|
23794
|
-
background: ${currentVizMode === "
|
|
23795
|
-
|
|
23796
|
-
|
|
23797
|
-
<button id="${modalId}-viz-separate" style="
|
|
23798
|
-
padding: 6px 12px;
|
|
23799
|
-
border: none;
|
|
23800
|
-
border-radius: 6px;
|
|
23801
|
-
font-size: 13px;
|
|
23802
|
-
cursor: pointer;
|
|
23803
|
-
transition: all 0.2s;
|
|
23804
|
-
background: ${currentVizMode === "separate" ? "#3e1a7d" : "transparent"};
|
|
23805
|
-
color: ${currentVizMode === "separate" ? "white" : colors.text};
|
|
23806
|
-
">Por Shopping</button>
|
|
23871
|
+
<div style="display: flex; gap: 2px; background: ${tabBgColor}; border-radius: 8px; padding: 3px;">
|
|
23872
|
+
<button id="${modalId}-viz-total" class="myio-modal-tab-btn ${currentVizMode === "total" ? "active" : ""}"
|
|
23873
|
+
data-viz="total" title="Consolidado"
|
|
23874
|
+
style="background: ${currentVizMode === "total" ? activeColor : "transparent"}; color: ${currentVizMode === "total" ? "white" : inactiveTextColor};">
|
|
23875
|
+
${consolidadoIcon}
|
|
23876
|
+
</button>
|
|
23877
|
+
<button id="${modalId}-viz-separate" class="myio-modal-tab-btn ${currentVizMode === "separate" ? "active" : ""}"
|
|
23878
|
+
data-viz="separate" title="Por Shopping"
|
|
23879
|
+
style="background: ${currentVizMode === "separate" ? activeColor : "transparent"}; color: ${currentVizMode === "separate" ? "white" : inactiveTextColor};">
|
|
23880
|
+
${porShoppingIcon}
|
|
23881
|
+
</button>
|
|
23807
23882
|
</div>
|
|
23808
23883
|
|
|
23809
23884
|
<!-- Chart Type Tabs -->
|
|
23810
|
-
<div style="display: flex; gap: 2px; background: ${
|
|
23811
|
-
<button id="${modalId}-type-line"
|
|
23812
|
-
|
|
23813
|
-
|
|
23814
|
-
|
|
23815
|
-
|
|
23816
|
-
|
|
23817
|
-
|
|
23818
|
-
background: ${currentChartType === "
|
|
23819
|
-
|
|
23820
|
-
|
|
23821
|
-
<button id="${modalId}-type-bar" style="
|
|
23822
|
-
padding: 6px 12px;
|
|
23823
|
-
border: none;
|
|
23824
|
-
border-radius: 6px;
|
|
23825
|
-
font-size: 13px;
|
|
23826
|
-
cursor: pointer;
|
|
23827
|
-
transition: all 0.2s;
|
|
23828
|
-
background: ${currentChartType === "bar" ? "#3e1a7d" : "transparent"};
|
|
23829
|
-
color: ${currentChartType === "bar" ? "white" : colors.text};
|
|
23830
|
-
">Barras</button>
|
|
23885
|
+
<div style="display: flex; gap: 2px; background: ${tabBgColor}; border-radius: 8px; padding: 3px;">
|
|
23886
|
+
<button id="${modalId}-type-line" class="myio-modal-tab-btn ${currentChartType === "line" ? "active" : ""}"
|
|
23887
|
+
data-type="line" title="Gr\xE1fico de Linhas"
|
|
23888
|
+
style="background: ${currentChartType === "line" ? activeColor : "transparent"}; color: ${currentChartType === "line" ? "white" : inactiveTextColor};">
|
|
23889
|
+
${lineChartIcon}
|
|
23890
|
+
</button>
|
|
23891
|
+
<button id="${modalId}-type-bar" class="myio-modal-tab-btn ${currentChartType === "bar" ? "active" : ""}"
|
|
23892
|
+
data-type="bar" title="Gr\xE1fico de Barras"
|
|
23893
|
+
style="background: ${currentChartType === "bar" ? activeColor : "transparent"}; color: ${currentChartType === "bar" ? "white" : inactiveTextColor};">
|
|
23894
|
+
${barChartIcon}
|
|
23895
|
+
</button>
|
|
23831
23896
|
</div>
|
|
23832
23897
|
</div>
|
|
23833
23898
|
|
|
@@ -23848,6 +23913,11 @@ function createConsumptionModal(config) {
|
|
|
23848
23913
|
function setupListeners() {
|
|
23849
23914
|
if (!modalElement) return;
|
|
23850
23915
|
headerInstance?.attachListeners();
|
|
23916
|
+
if (showSettingsButton) {
|
|
23917
|
+
document.getElementById(`${modalId}-settings-btn`)?.addEventListener("click", () => {
|
|
23918
|
+
config.onSettingsClick?.();
|
|
23919
|
+
});
|
|
23920
|
+
}
|
|
23851
23921
|
document.getElementById(`${modalId}-viz-total`)?.addEventListener("click", () => {
|
|
23852
23922
|
currentVizMode = "total";
|
|
23853
23923
|
chartInstance?.setVizMode("total");
|
|
@@ -23882,25 +23952,30 @@ function createConsumptionModal(config) {
|
|
|
23882
23952
|
modalElement.__handleKeydown = handleKeydown;
|
|
23883
23953
|
}
|
|
23884
23954
|
function updateControlStyles() {
|
|
23885
|
-
const colors =
|
|
23955
|
+
const colors = getThemeColors3();
|
|
23956
|
+
const activeColor = "#3e1a7d";
|
|
23886
23957
|
const vizTotalBtn = document.getElementById(`${modalId}-viz-total`);
|
|
23887
23958
|
const vizSeparateBtn = document.getElementById(`${modalId}-viz-separate`);
|
|
23888
23959
|
if (vizTotalBtn) {
|
|
23889
|
-
vizTotalBtn.
|
|
23960
|
+
vizTotalBtn.classList.toggle("active", currentVizMode === "total");
|
|
23961
|
+
vizTotalBtn.style.background = currentVizMode === "total" ? activeColor : "transparent";
|
|
23890
23962
|
vizTotalBtn.style.color = currentVizMode === "total" ? "white" : colors.text;
|
|
23891
23963
|
}
|
|
23892
23964
|
if (vizSeparateBtn) {
|
|
23893
|
-
vizSeparateBtn.
|
|
23965
|
+
vizSeparateBtn.classList.toggle("active", currentVizMode === "separate");
|
|
23966
|
+
vizSeparateBtn.style.background = currentVizMode === "separate" ? activeColor : "transparent";
|
|
23894
23967
|
vizSeparateBtn.style.color = currentVizMode === "separate" ? "white" : colors.text;
|
|
23895
23968
|
}
|
|
23896
23969
|
const typeLineBtn = document.getElementById(`${modalId}-type-line`);
|
|
23897
23970
|
const typeBarBtn = document.getElementById(`${modalId}-type-bar`);
|
|
23898
23971
|
if (typeLineBtn) {
|
|
23899
|
-
typeLineBtn.
|
|
23972
|
+
typeLineBtn.classList.toggle("active", currentChartType === "line");
|
|
23973
|
+
typeLineBtn.style.background = currentChartType === "line" ? activeColor : "transparent";
|
|
23900
23974
|
typeLineBtn.style.color = currentChartType === "line" ? "white" : colors.text;
|
|
23901
23975
|
}
|
|
23902
23976
|
if (typeBarBtn) {
|
|
23903
|
-
typeBarBtn.
|
|
23977
|
+
typeBarBtn.classList.toggle("active", currentChartType === "bar");
|
|
23978
|
+
typeBarBtn.style.background = currentChartType === "bar" ? activeColor : "transparent";
|
|
23904
23979
|
typeBarBtn.style.color = currentChartType === "bar" ? "white" : colors.text;
|
|
23905
23980
|
}
|
|
23906
23981
|
}
|
|
@@ -24026,18 +24101,11 @@ function getWidgetStyles(theme, primaryColor) {
|
|
|
24026
24101
|
|
|
24027
24102
|
.myio-chart-widget-title {
|
|
24028
24103
|
margin: 0;
|
|
24029
|
-
font-size:
|
|
24104
|
+
font-size: 14px;
|
|
24030
24105
|
font-weight: 600;
|
|
24031
24106
|
color: ${colors.text};
|
|
24032
24107
|
}
|
|
24033
24108
|
|
|
24034
|
-
.myio-chart-widget-controls {
|
|
24035
|
-
display: flex;
|
|
24036
|
-
align-items: center;
|
|
24037
|
-
gap: 12px;
|
|
24038
|
-
flex-wrap: wrap;
|
|
24039
|
-
}
|
|
24040
|
-
|
|
24041
24109
|
.myio-chart-widget-tabs {
|
|
24042
24110
|
display: flex;
|
|
24043
24111
|
gap: 2px;
|
|
@@ -24057,6 +24125,20 @@ function getWidgetStyles(theme, primaryColor) {
|
|
|
24057
24125
|
border-radius: 6px;
|
|
24058
24126
|
transition: all 0.2s;
|
|
24059
24127
|
white-space: nowrap;
|
|
24128
|
+
display: flex;
|
|
24129
|
+
align-items: center;
|
|
24130
|
+
justify-content: center;
|
|
24131
|
+
gap: 4px;
|
|
24132
|
+
}
|
|
24133
|
+
|
|
24134
|
+
.myio-chart-widget-tab.icon-only {
|
|
24135
|
+
padding: 6px 10px;
|
|
24136
|
+
}
|
|
24137
|
+
|
|
24138
|
+
.myio-chart-widget-tab svg {
|
|
24139
|
+
width: 16px;
|
|
24140
|
+
height: 16px;
|
|
24141
|
+
pointer-events: none;
|
|
24060
24142
|
}
|
|
24061
24143
|
|
|
24062
24144
|
.myio-chart-widget-tab:hover {
|
|
@@ -24190,7 +24272,7 @@ function getWidgetStyles(theme, primaryColor) {
|
|
|
24190
24272
|
background: ${colors.chartBackground};
|
|
24191
24273
|
border-radius: 10px;
|
|
24192
24274
|
width: 90%;
|
|
24193
|
-
max-width:
|
|
24275
|
+
max-width: 860px;
|
|
24194
24276
|
max-height: 90vh;
|
|
24195
24277
|
display: flex;
|
|
24196
24278
|
flex-direction: column;
|
|
@@ -24207,7 +24289,7 @@ function getWidgetStyles(theme, primaryColor) {
|
|
|
24207
24289
|
overflow-y: auto;
|
|
24208
24290
|
display: flex;
|
|
24209
24291
|
flex-direction: column;
|
|
24210
|
-
gap:
|
|
24292
|
+
gap: 12px;
|
|
24211
24293
|
}
|
|
24212
24294
|
|
|
24213
24295
|
.myio-settings-section {
|
|
@@ -24250,10 +24332,10 @@ function getWidgetStyles(theme, primaryColor) {
|
|
|
24250
24332
|
|
|
24251
24333
|
.myio-settings-input,
|
|
24252
24334
|
.myio-settings-select {
|
|
24253
|
-
padding:
|
|
24335
|
+
padding: 8px 12px;
|
|
24254
24336
|
border: 1px solid ${colors.border};
|
|
24255
24337
|
border-radius: 8px;
|
|
24256
|
-
font-size:
|
|
24338
|
+
font-size: 12px;
|
|
24257
24339
|
background: ${colors.chartBackground};
|
|
24258
24340
|
color: ${colors.text};
|
|
24259
24341
|
width: 100%;
|
|
@@ -24285,6 +24367,10 @@ function getWidgetStyles(theme, primaryColor) {
|
|
|
24285
24367
|
border-radius: 6px;
|
|
24286
24368
|
transition: all 0.2s;
|
|
24287
24369
|
white-space: nowrap;
|
|
24370
|
+
display: flex;
|
|
24371
|
+
align-items: center;
|
|
24372
|
+
justify-content: center;
|
|
24373
|
+
gap: 6px;
|
|
24288
24374
|
}
|
|
24289
24375
|
|
|
24290
24376
|
.myio-settings-tab:hover {
|
|
@@ -24342,13 +24428,17 @@ function getWidgetStyles(theme, primaryColor) {
|
|
|
24342
24428
|
}
|
|
24343
24429
|
|
|
24344
24430
|
.myio-settings-context-group {
|
|
24345
|
-
margin-bottom:
|
|
24431
|
+
margin-bottom: 12px;
|
|
24346
24432
|
}
|
|
24347
24433
|
|
|
24348
24434
|
.myio-settings-context-group:last-child {
|
|
24349
24435
|
margin-bottom: 0;
|
|
24350
24436
|
}
|
|
24351
24437
|
|
|
24438
|
+
.myio-settings-section + .myio-settings-section {
|
|
24439
|
+
margin-top: 12px;
|
|
24440
|
+
}
|
|
24441
|
+
|
|
24352
24442
|
/* Dropdown styles */
|
|
24353
24443
|
.myio-settings-dropdown-container {
|
|
24354
24444
|
position: relative;
|
|
@@ -24452,6 +24542,23 @@ function getWidgetStyles(theme, primaryColor) {
|
|
|
24452
24542
|
opacity: 1 !important;
|
|
24453
24543
|
transform: scale(1.2);
|
|
24454
24544
|
}
|
|
24545
|
+
|
|
24546
|
+
/* DateRangePicker styles (CSS tokens + premium styling) */
|
|
24547
|
+
${CSS_TOKENS}
|
|
24548
|
+
${DATERANGEPICKER_STYLES}
|
|
24549
|
+
|
|
24550
|
+
/* Fix DateRangePicker buttons alignment */
|
|
24551
|
+
.myio-modal-scope .daterangepicker .drp-buttons {
|
|
24552
|
+
display: flex;
|
|
24553
|
+
justify-content: flex-end;
|
|
24554
|
+
align-items: center;
|
|
24555
|
+
gap: 8px;
|
|
24556
|
+
}
|
|
24557
|
+
|
|
24558
|
+
.myio-modal-scope .daterangepicker .drp-buttons .btn {
|
|
24559
|
+
display: inline-block;
|
|
24560
|
+
margin-left: 0;
|
|
24561
|
+
}
|
|
24455
24562
|
`;
|
|
24456
24563
|
}
|
|
24457
24564
|
function createConsumptionChartWidget(config) {
|
|
@@ -24461,6 +24568,7 @@ function createConsumptionChartWidget(config) {
|
|
|
24461
24568
|
let styleElement = null;
|
|
24462
24569
|
let settingsModalElement = null;
|
|
24463
24570
|
let settingsHeaderInstance = null;
|
|
24571
|
+
let dateRangePickerInstance = null;
|
|
24464
24572
|
let currentTheme = config.theme ?? "light";
|
|
24465
24573
|
let currentChartType = config.defaultChartType ?? "line";
|
|
24466
24574
|
let currentVizMode = config.defaultVizMode ?? "total";
|
|
@@ -24472,6 +24580,8 @@ function createConsumptionChartWidget(config) {
|
|
|
24472
24580
|
let tempVizMode = currentVizMode;
|
|
24473
24581
|
let tempTheme = currentTheme;
|
|
24474
24582
|
let tempIdealRange = currentIdealRange;
|
|
24583
|
+
let tempStartDate = null;
|
|
24584
|
+
let tempEndDate = null;
|
|
24475
24585
|
let currentSuggestion = null;
|
|
24476
24586
|
const domainCfg = DOMAIN_CONFIG4[config.domain] || DOMAIN_CONFIG4.energy;
|
|
24477
24587
|
const primaryColor = config.colors?.primary || domainCfg.color;
|
|
@@ -24487,6 +24597,10 @@ function createConsumptionChartWidget(config) {
|
|
|
24487
24597
|
return `${domainName} dos \xFAltimos ${currentPeriod} dias`;
|
|
24488
24598
|
}
|
|
24489
24599
|
function renderHTML() {
|
|
24600
|
+
const consolidadoIcon = `<svg viewBox="0 0 16 16" fill="currentColor"><rect x="3" y="3" width="10" height="10" rx="2"/></svg>`;
|
|
24601
|
+
const porShoppingIcon = `<svg viewBox="0 0 16 16" fill="currentColor"><rect x="1" y="1" width="6" height="6" rx="1"/><rect x="9" y="1" width="6" height="6" rx="1"/><rect x="1" y="9" width="6" height="6" rx="1"/><rect x="9" y="9" width="6" height="6" rx="1"/></svg>`;
|
|
24602
|
+
const lineChartIcon = `<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="2,12 5,7 9,9 14,3"/></svg>`;
|
|
24603
|
+
const barChartIcon = `<svg viewBox="0 0 16 16" fill="currentColor"><rect x="1" y="9" width="3" height="6" rx="0.5"/><rect x="6" y="5" width="3" height="10" rx="0.5"/><rect x="11" y="7" width="3" height="8" rx="0.5"/></svg>`;
|
|
24490
24604
|
return `
|
|
24491
24605
|
<div id="${widgetId}" class="myio-chart-widget ${currentTheme === "dark" ? "dark" : ""} ${config.className || ""}">
|
|
24492
24606
|
<div class="myio-chart-widget-header">
|
|
@@ -24495,18 +24609,16 @@ function createConsumptionChartWidget(config) {
|
|
|
24495
24609
|
<button id="${widgetId}-settings-btn" class="myio-chart-widget-btn" title="Configura\xE7\xF5es">\u2699\uFE0F</button>
|
|
24496
24610
|
` : ""}
|
|
24497
24611
|
<h4 id="${widgetId}-title" class="myio-chart-widget-title">${getTitle()}</h4>
|
|
24498
|
-
</div>
|
|
24499
|
-
<div class="myio-chart-widget-controls">
|
|
24500
24612
|
${showVizModeTabs ? `
|
|
24501
24613
|
<div class="myio-chart-widget-tabs" id="${widgetId}-viz-tabs">
|
|
24502
|
-
<button class="myio-chart-widget-tab ${currentVizMode === "total" ? "active" : ""}" data-viz="total"
|
|
24503
|
-
<button class="myio-chart-widget-tab ${currentVizMode === "separate" ? "active" : ""}" data-viz="separate"
|
|
24614
|
+
<button class="myio-chart-widget-tab icon-only ${currentVizMode === "total" ? "active" : ""}" data-viz="total" title="Consolidado">${consolidadoIcon}</button>
|
|
24615
|
+
<button class="myio-chart-widget-tab icon-only ${currentVizMode === "separate" ? "active" : ""}" data-viz="separate" title="Por Shopping">${porShoppingIcon}</button>
|
|
24504
24616
|
</div>
|
|
24505
24617
|
` : ""}
|
|
24506
24618
|
${showChartTypeTabs ? `
|
|
24507
24619
|
<div class="myio-chart-widget-tabs" id="${widgetId}-type-tabs">
|
|
24508
|
-
<button class="myio-chart-widget-tab ${currentChartType === "line" ? "active" : ""}" data-type="line"
|
|
24509
|
-
<button class="myio-chart-widget-tab ${currentChartType === "bar" ? "active" : ""}" data-type="bar"
|
|
24620
|
+
<button class="myio-chart-widget-tab icon-only ${currentChartType === "line" ? "active" : ""}" data-type="line" title="Gr\xE1fico de Linhas">${lineChartIcon}</button>
|
|
24621
|
+
<button class="myio-chart-widget-tab icon-only ${currentChartType === "bar" ? "active" : ""}" data-type="bar" title="Gr\xE1fico de Barras">${barChartIcon}</button>
|
|
24510
24622
|
</div>
|
|
24511
24623
|
` : ""}
|
|
24512
24624
|
${showMaximizeButton ? `
|
|
@@ -24543,19 +24655,22 @@ function createConsumptionChartWidget(config) {
|
|
|
24543
24655
|
function renderSettingsModal() {
|
|
24544
24656
|
const unit = config.unit ?? "";
|
|
24545
24657
|
const isTemperature = config.domain === "temperature";
|
|
24658
|
+
const consolidadoIcon = `<svg viewBox="0 0 16 16" fill="currentColor" style="width:14px;height:14px;pointer-events:none"><rect x="3" y="3" width="10" height="10" rx="2"/></svg>`;
|
|
24659
|
+
const porShoppingIcon = `<svg viewBox="0 0 16 16" fill="currentColor" style="width:14px;height:14px;pointer-events:none"><rect x="1" y="1" width="6" height="6" rx="1"/><rect x="9" y="1" width="6" height="6" rx="1"/><rect x="1" y="9" width="6" height="6" rx="1"/><rect x="9" y="9" width="6" height="6" rx="1"/></svg>`;
|
|
24660
|
+
const lineChartIcon = `<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:14px;height:14px;pointer-events:none"><polyline points="2,12 5,7 9,9 14,3"/></svg>`;
|
|
24661
|
+
const barChartIcon = `<svg viewBox="0 0 16 16" fill="currentColor" style="width:14px;height:14px;pointer-events:none"><rect x="1" y="9" width="3" height="6" rx="0.5"/><rect x="6" y="5" width="3" height="10" rx="0.5"/><rect x="11" y="7" width="3" height="8" rx="0.5"/></svg>`;
|
|
24546
24662
|
settingsHeaderInstance = createModalHeader({
|
|
24547
24663
|
id: `${widgetId}-settings`,
|
|
24548
24664
|
title: "Configura\xE7\xF5es",
|
|
24549
24665
|
icon: "\u2699\uFE0F",
|
|
24550
24666
|
theme: tempTheme,
|
|
24551
|
-
backgroundColor: primaryColor,
|
|
24552
24667
|
showThemeToggle: false,
|
|
24553
24668
|
showMaximize: false,
|
|
24554
24669
|
showClose: true,
|
|
24555
24670
|
onClose: () => closeSettingsModal()
|
|
24556
24671
|
});
|
|
24557
24672
|
return `
|
|
24558
|
-
<div id="${widgetId}-settings-overlay" class="myio-settings-overlay hidden">
|
|
24673
|
+
<div id="${widgetId}-settings-overlay" class="myio-settings-overlay myio-modal-scope hidden">
|
|
24559
24674
|
<div class="myio-settings-card">
|
|
24560
24675
|
${settingsHeaderInstance.render()}
|
|
24561
24676
|
<div class="myio-settings-body">
|
|
@@ -24566,13 +24681,8 @@ function createConsumptionChartWidget(config) {
|
|
|
24566
24681
|
<div class="myio-settings-section-label">\u{1F4C5} Per\xEDodo</div>
|
|
24567
24682
|
<div class="myio-settings-row">
|
|
24568
24683
|
<div class="myio-settings-field" style="flex: 1;">
|
|
24569
|
-
<
|
|
24570
|
-
|
|
24571
|
-
<option value="14" ${tempPeriod === 14 ? "selected" : ""}>\xDAltimos 14 dias</option>
|
|
24572
|
-
<option value="30" ${tempPeriod === 30 ? "selected" : ""}>\xDAltimos 30 dias</option>
|
|
24573
|
-
<option value="60" ${tempPeriod === 60 ? "selected" : ""}>\xDAltimos 60 dias</option>
|
|
24574
|
-
<option value="90" ${tempPeriod === 90 ? "selected" : ""}>\xDAltimos 90 dias</option>
|
|
24575
|
-
</select>
|
|
24684
|
+
<input type="text" id="${widgetId}-settings-daterange" class="myio-settings-input"
|
|
24685
|
+
readonly placeholder="Selecione o per\xEDodo..." style="cursor: pointer;">
|
|
24576
24686
|
</div>
|
|
24577
24687
|
</div>
|
|
24578
24688
|
</div>
|
|
@@ -24701,8 +24811,8 @@ function createConsumptionChartWidget(config) {
|
|
|
24701
24811
|
<div class="myio-settings-field" style="flex: 1; min-width: 180px;">
|
|
24702
24812
|
<label class="myio-settings-field-label">Tipo de Gr\xE1fico</label>
|
|
24703
24813
|
<div class="myio-settings-tabs" id="${widgetId}-settings-chart-type">
|
|
24704
|
-
<button class="myio-settings-tab ${tempChartType === "line" ? "active" : ""}" data-type="line"
|
|
24705
|
-
<button class="myio-settings-tab ${tempChartType === "bar" ? "active" : ""}" data-type="bar"
|
|
24814
|
+
<button class="myio-settings-tab ${tempChartType === "line" ? "active" : ""}" data-type="line">${lineChartIcon} Linhas</button>
|
|
24815
|
+
<button class="myio-settings-tab ${tempChartType === "bar" ? "active" : ""}" data-type="bar">${barChartIcon} Barras</button>
|
|
24706
24816
|
</div>
|
|
24707
24817
|
</div>
|
|
24708
24818
|
|
|
@@ -24710,8 +24820,8 @@ function createConsumptionChartWidget(config) {
|
|
|
24710
24820
|
<div class="myio-settings-field" style="flex: 1; min-width: 200px;">
|
|
24711
24821
|
<label class="myio-settings-field-label">Agrupamento</label>
|
|
24712
24822
|
<div class="myio-settings-tabs" id="${widgetId}-settings-viz-mode">
|
|
24713
|
-
<button class="myio-settings-tab ${tempVizMode === "total" ? "active" : ""}" data-viz="total"
|
|
24714
|
-
<button class="myio-settings-tab ${tempVizMode === "separate" ? "active" : ""}" data-viz="separate"
|
|
24823
|
+
<button class="myio-settings-tab ${tempVizMode === "total" ? "active" : ""}" data-viz="total">${consolidadoIcon} Consolidado</button>
|
|
24824
|
+
<button class="myio-settings-tab ${tempVizMode === "separate" ? "active" : ""}" data-viz="separate">${porShoppingIcon} Por Shopping</button>
|
|
24715
24825
|
</div>
|
|
24716
24826
|
</div>
|
|
24717
24827
|
|
|
@@ -24853,18 +24963,21 @@ function createConsumptionChartWidget(config) {
|
|
|
24853
24963
|
peakDateEl.textContent = peakDate;
|
|
24854
24964
|
}
|
|
24855
24965
|
}
|
|
24856
|
-
function openSettingsModal() {
|
|
24966
|
+
async function openSettingsModal() {
|
|
24857
24967
|
tempPeriod = currentPeriod;
|
|
24858
24968
|
tempChartType = currentChartType;
|
|
24859
24969
|
tempVizMode = currentVizMode;
|
|
24860
24970
|
tempTheme = currentTheme;
|
|
24861
24971
|
tempIdealRange = currentIdealRange ? { ...currentIdealRange } : null;
|
|
24972
|
+
dateRangePickerInstance = null;
|
|
24862
24973
|
if (!settingsModalElement) {
|
|
24863
24974
|
settingsModalElement = document.createElement("div");
|
|
24864
24975
|
settingsModalElement.innerHTML = renderSettingsModal();
|
|
24865
24976
|
document.body.appendChild(settingsModalElement.firstElementChild);
|
|
24866
24977
|
settingsModalElement = document.getElementById(`${widgetId}-settings-overlay`);
|
|
24867
|
-
setupSettingsModalListeners();
|
|
24978
|
+
await setupSettingsModalListeners();
|
|
24979
|
+
} else {
|
|
24980
|
+
await setupSettingsModalListeners();
|
|
24868
24981
|
}
|
|
24869
24982
|
updateSettingsModalValues();
|
|
24870
24983
|
updateIdealRangeSuggestionTooltip();
|
|
@@ -24872,6 +24985,10 @@ function createConsumptionChartWidget(config) {
|
|
|
24872
24985
|
}
|
|
24873
24986
|
function closeSettingsModal() {
|
|
24874
24987
|
settingsModalElement?.classList.add("hidden");
|
|
24988
|
+
if (dateRangePickerInstance) {
|
|
24989
|
+
dateRangePickerInstance.destroy();
|
|
24990
|
+
dateRangePickerInstance = null;
|
|
24991
|
+
}
|
|
24875
24992
|
}
|
|
24876
24993
|
function updateSettingsModalValues() {
|
|
24877
24994
|
const periodSelect = document.getElementById(`${widgetId}-settings-period`);
|
|
@@ -24981,8 +25098,46 @@ function createConsumptionChartWidget(config) {
|
|
|
24981
25098
|
label: "Faixa Sugerida"
|
|
24982
25099
|
};
|
|
24983
25100
|
}
|
|
24984
|
-
function setupSettingsModalListeners() {
|
|
25101
|
+
async function setupSettingsModalListeners() {
|
|
24985
25102
|
settingsHeaderInstance?.attachListeners();
|
|
25103
|
+
const dateRangeInput = document.getElementById(`${widgetId}-settings-daterange`);
|
|
25104
|
+
if (dateRangeInput && !dateRangePickerInstance) {
|
|
25105
|
+
try {
|
|
25106
|
+
const endDate = /* @__PURE__ */ new Date();
|
|
25107
|
+
const startDate = /* @__PURE__ */ new Date();
|
|
25108
|
+
startDate.setDate(endDate.getDate() - tempPeriod);
|
|
25109
|
+
const presetStart = tempStartDate || startDate.toISOString();
|
|
25110
|
+
const presetEnd = tempEndDate || endDate.toISOString();
|
|
25111
|
+
dateRangePickerInstance = await createDateRangePicker2(dateRangeInput, {
|
|
25112
|
+
presetStart,
|
|
25113
|
+
presetEnd,
|
|
25114
|
+
includeTime: true,
|
|
25115
|
+
timePrecision: "hour",
|
|
25116
|
+
maxRangeDays: 90,
|
|
25117
|
+
locale: "pt-BR",
|
|
25118
|
+
parentEl: document.getElementById(`${widgetId}-settings-overlay`),
|
|
25119
|
+
onApply: (result) => {
|
|
25120
|
+
tempStartDate = result.startISO;
|
|
25121
|
+
tempEndDate = result.endISO;
|
|
25122
|
+
const start = new Date(result.startISO);
|
|
25123
|
+
const end = new Date(result.endISO);
|
|
25124
|
+
const diffTime = Math.abs(end.getTime() - start.getTime());
|
|
25125
|
+
const diffHours = diffTime / (1e3 * 60 * 60);
|
|
25126
|
+
const diffDays = Math.ceil(diffTime / (1e3 * 60 * 60 * 24));
|
|
25127
|
+
tempPeriod = diffDays || 7;
|
|
25128
|
+
const granularitySelect = document.getElementById(`${widgetId}-settings-granularity`);
|
|
25129
|
+
if (granularitySelect && diffHours <= 48) {
|
|
25130
|
+
granularitySelect.value = "1h";
|
|
25131
|
+
const dayPeriodField = document.getElementById(`${widgetId}-settings-dayperiod-field`);
|
|
25132
|
+
if (dayPeriodField) dayPeriodField.style.display = "block";
|
|
25133
|
+
}
|
|
25134
|
+
console.log("[ConsumptionChartWidget] Date range applied:", { start: result.startISO, end: result.endISO, hours: diffHours, days: tempPeriod });
|
|
25135
|
+
}
|
|
25136
|
+
});
|
|
25137
|
+
} catch (error) {
|
|
25138
|
+
console.warn("[ConsumptionChartWidget] DateRangePicker initialization failed:", error);
|
|
25139
|
+
}
|
|
25140
|
+
}
|
|
24986
25141
|
document.getElementById(`${widgetId}-settings-overlay`)?.addEventListener("click", (e) => {
|
|
24987
25142
|
if (e.target.classList.contains("myio-settings-overlay")) {
|
|
24988
25143
|
closeSettingsModal();
|
|
@@ -25070,13 +25225,56 @@ function createConsumptionChartWidget(config) {
|
|
|
25070
25225
|
updateSettingsModalTabs();
|
|
25071
25226
|
}
|
|
25072
25227
|
});
|
|
25073
|
-
document.getElementById(`${widgetId}-settings-reset`)?.addEventListener("click", () => {
|
|
25228
|
+
document.getElementById(`${widgetId}-settings-reset`)?.addEventListener("click", async () => {
|
|
25074
25229
|
tempPeriod = config.defaultPeriod ?? 7;
|
|
25075
25230
|
tempChartType = config.defaultChartType ?? "line";
|
|
25076
25231
|
tempVizMode = config.defaultVizMode ?? "total";
|
|
25077
25232
|
tempTheme = config.theme ?? "light";
|
|
25078
25233
|
tempIdealRange = config.idealRange ?? null;
|
|
25079
|
-
|
|
25234
|
+
tempStartDate = null;
|
|
25235
|
+
tempEndDate = null;
|
|
25236
|
+
if (dateRangePickerInstance) {
|
|
25237
|
+
dateRangePickerInstance.destroy();
|
|
25238
|
+
dateRangePickerInstance = null;
|
|
25239
|
+
}
|
|
25240
|
+
const dateRangeInput2 = document.getElementById(`${widgetId}-settings-daterange`);
|
|
25241
|
+
if (dateRangeInput2) {
|
|
25242
|
+
const endDate = /* @__PURE__ */ new Date();
|
|
25243
|
+
const startDate = /* @__PURE__ */ new Date();
|
|
25244
|
+
startDate.setDate(endDate.getDate() - tempPeriod);
|
|
25245
|
+
try {
|
|
25246
|
+
dateRangePickerInstance = await createDateRangePicker2(dateRangeInput2, {
|
|
25247
|
+
presetStart: startDate.toISOString(),
|
|
25248
|
+
presetEnd: endDate.toISOString(),
|
|
25249
|
+
includeTime: true,
|
|
25250
|
+
timePrecision: "hour",
|
|
25251
|
+
maxRangeDays: 90,
|
|
25252
|
+
locale: "pt-BR",
|
|
25253
|
+
parentEl: document.getElementById(`${widgetId}-settings-overlay`),
|
|
25254
|
+
onApply: (result) => {
|
|
25255
|
+
tempStartDate = result.startISO;
|
|
25256
|
+
tempEndDate = result.endISO;
|
|
25257
|
+
const start = new Date(result.startISO);
|
|
25258
|
+
const end = new Date(result.endISO);
|
|
25259
|
+
const diffTime = Math.abs(end.getTime() - start.getTime());
|
|
25260
|
+
const diffHours = diffTime / (1e3 * 60 * 60);
|
|
25261
|
+
const diffDays = Math.ceil(diffTime / (1e3 * 60 * 60 * 24));
|
|
25262
|
+
tempPeriod = diffDays || 7;
|
|
25263
|
+
const granularitySelect2 = document.getElementById(`${widgetId}-settings-granularity`);
|
|
25264
|
+
if (granularitySelect2 && diffHours <= 48) {
|
|
25265
|
+
granularitySelect2.value = "1h";
|
|
25266
|
+
const dayPeriodField2 = document.getElementById(`${widgetId}-settings-dayperiod-field`);
|
|
25267
|
+
if (dayPeriodField2) dayPeriodField2.style.display = "block";
|
|
25268
|
+
}
|
|
25269
|
+
}
|
|
25270
|
+
});
|
|
25271
|
+
} catch (error) {
|
|
25272
|
+
console.warn("[ConsumptionChartWidget] DateRangePicker reset failed:", error);
|
|
25273
|
+
}
|
|
25274
|
+
}
|
|
25275
|
+
const granularitySelect = document.getElementById(
|
|
25276
|
+
`${widgetId}-settings-granularity`
|
|
25277
|
+
);
|
|
25080
25278
|
if (granularitySelect) granularitySelect.value = "1d";
|
|
25081
25279
|
const dayPeriodField = document.getElementById(`${widgetId}-settings-dayperiod-field`);
|
|
25082
25280
|
if (dayPeriodField) dayPeriodField.style.display = "none";
|
|
@@ -25222,6 +25420,10 @@ function createConsumptionChartWidget(config) {
|
|
|
25222
25420
|
}
|
|
25223
25421
|
settingsHeaderInstance?.destroy();
|
|
25224
25422
|
settingsHeaderInstance = null;
|
|
25423
|
+
if (dateRangePickerInstance) {
|
|
25424
|
+
dateRangePickerInstance.destroy();
|
|
25425
|
+
dateRangePickerInstance = null;
|
|
25426
|
+
}
|
|
25225
25427
|
if (settingsModalElement) {
|
|
25226
25428
|
settingsModalElement.remove();
|
|
25227
25429
|
settingsModalElement = null;
|
|
@@ -25673,6 +25875,581 @@ var EXPORT_DEFAULT_COLORS = DEFAULT_COLORS4;
|
|
|
25673
25875
|
var EXPORT_DOMAIN_ICONS = DOMAIN_ICONS;
|
|
25674
25876
|
var EXPORT_DOMAIN_LABELS = DOMAIN_LABELS;
|
|
25675
25877
|
var EXPORT_DOMAIN_UNITS = DOMAIN_UNITS;
|
|
25878
|
+
|
|
25879
|
+
// src/components/DistributionChart/colorManager.ts
|
|
25880
|
+
var DEFAULT_SHOPPING_COLORS = [
|
|
25881
|
+
"#3b82f6",
|
|
25882
|
+
// Blue
|
|
25883
|
+
"#8b5cf6",
|
|
25884
|
+
// Purple
|
|
25885
|
+
"#f59e0b",
|
|
25886
|
+
// Amber
|
|
25887
|
+
"#ef4444",
|
|
25888
|
+
// Red
|
|
25889
|
+
"#10b981",
|
|
25890
|
+
// Emerald
|
|
25891
|
+
"#06b6d4",
|
|
25892
|
+
// Cyan
|
|
25893
|
+
"#ec4899",
|
|
25894
|
+
// Pink
|
|
25895
|
+
"#14b8a6",
|
|
25896
|
+
// Teal
|
|
25897
|
+
"#f97316",
|
|
25898
|
+
// Orange
|
|
25899
|
+
"#a855f7"
|
|
25900
|
+
// Violet
|
|
25901
|
+
];
|
|
25902
|
+
var DEFAULT_ENERGY_GROUP_COLORS = {
|
|
25903
|
+
"Elevadores": "#3b82f6",
|
|
25904
|
+
"Escadas Rolantes": "#8b5cf6",
|
|
25905
|
+
"Climatiza\xE7\xE3o": "#f59e0b",
|
|
25906
|
+
"Climatizacao": "#f59e0b",
|
|
25907
|
+
// Without accent
|
|
25908
|
+
"Outros Equipamentos": "#ef4444",
|
|
25909
|
+
"Lojas": "#10b981"
|
|
25910
|
+
};
|
|
25911
|
+
var DEFAULT_WATER_GROUP_COLORS = {
|
|
25912
|
+
"Lojas": "#10b981",
|
|
25913
|
+
"\xC1rea Comum": "#0288d1",
|
|
25914
|
+
"Area Comum": "#0288d1"
|
|
25915
|
+
// Without accent
|
|
25916
|
+
};
|
|
25917
|
+
var DEFAULT_GAS_GROUP_COLORS = {
|
|
25918
|
+
"Cozinha": "#f59e0b",
|
|
25919
|
+
"Aquecimento": "#ef4444",
|
|
25920
|
+
"Outros": "#94a3b8"
|
|
25921
|
+
};
|
|
25922
|
+
function getDefaultGroupColors(domain) {
|
|
25923
|
+
switch (domain.toLowerCase()) {
|
|
25924
|
+
case "energy":
|
|
25925
|
+
return DEFAULT_ENERGY_GROUP_COLORS;
|
|
25926
|
+
case "water":
|
|
25927
|
+
return DEFAULT_WATER_GROUP_COLORS;
|
|
25928
|
+
case "gas":
|
|
25929
|
+
return DEFAULT_GAS_GROUP_COLORS;
|
|
25930
|
+
default:
|
|
25931
|
+
return DEFAULT_ENERGY_GROUP_COLORS;
|
|
25932
|
+
}
|
|
25933
|
+
}
|
|
25934
|
+
function assignShoppingColors(shoppingIds) {
|
|
25935
|
+
const colors = {};
|
|
25936
|
+
shoppingIds.forEach((id, index) => {
|
|
25937
|
+
colors[id] = DEFAULT_SHOPPING_COLORS[index % DEFAULT_SHOPPING_COLORS.length];
|
|
25938
|
+
});
|
|
25939
|
+
return colors;
|
|
25940
|
+
}
|
|
25941
|
+
function getShoppingColor(shoppingId, shoppingColors, fallbackIndex = 0) {
|
|
25942
|
+
if (shoppingColors && shoppingColors[shoppingId]) {
|
|
25943
|
+
return shoppingColors[shoppingId];
|
|
25944
|
+
}
|
|
25945
|
+
if (shoppingColors) {
|
|
25946
|
+
const normalizedId = shoppingId.toLowerCase();
|
|
25947
|
+
for (const [key, color] of Object.entries(shoppingColors)) {
|
|
25948
|
+
if (key.toLowerCase() === normalizedId || key.toLowerCase().includes(normalizedId)) {
|
|
25949
|
+
return color;
|
|
25950
|
+
}
|
|
25951
|
+
}
|
|
25952
|
+
}
|
|
25953
|
+
return DEFAULT_SHOPPING_COLORS[Math.abs(fallbackIndex) % DEFAULT_SHOPPING_COLORS.length];
|
|
25954
|
+
}
|
|
25955
|
+
function getGroupColor(groupName, groupColors, domain = "energy", fallbackIndex = 0) {
|
|
25956
|
+
if (groupColors && groupColors[groupName]) {
|
|
25957
|
+
return groupColors[groupName];
|
|
25958
|
+
}
|
|
25959
|
+
const defaultColors = getDefaultGroupColors(domain);
|
|
25960
|
+
if (defaultColors[groupName]) {
|
|
25961
|
+
return defaultColors[groupName];
|
|
25962
|
+
}
|
|
25963
|
+
return DEFAULT_SHOPPING_COLORS[Math.abs(fallbackIndex) % DEFAULT_SHOPPING_COLORS.length];
|
|
25964
|
+
}
|
|
25965
|
+
function getThemeColors2(theme) {
|
|
25966
|
+
if (theme === "dark") {
|
|
25967
|
+
return {
|
|
25968
|
+
text: "#f3f4f6",
|
|
25969
|
+
secondaryText: "#9ca3af",
|
|
25970
|
+
background: "#111827",
|
|
25971
|
+
cardBackground: "#1f2937",
|
|
25972
|
+
border: "#374151",
|
|
25973
|
+
grid: "#374151"
|
|
25974
|
+
};
|
|
25975
|
+
}
|
|
25976
|
+
return {
|
|
25977
|
+
text: "#1f2937",
|
|
25978
|
+
secondaryText: "#6b7280",
|
|
25979
|
+
background: "#f5f5f5",
|
|
25980
|
+
cardBackground: "#ffffff",
|
|
25981
|
+
border: "#e5e7eb",
|
|
25982
|
+
grid: "#e5e7eb"
|
|
25983
|
+
};
|
|
25984
|
+
}
|
|
25985
|
+
function getHashColor(str) {
|
|
25986
|
+
let hash = 0;
|
|
25987
|
+
for (let i = 0; i < str.length; i++) {
|
|
25988
|
+
const char = str.charCodeAt(i);
|
|
25989
|
+
hash = (hash << 5) - hash + char;
|
|
25990
|
+
hash = hash & hash;
|
|
25991
|
+
}
|
|
25992
|
+
return DEFAULT_SHOPPING_COLORS[Math.abs(hash) % DEFAULT_SHOPPING_COLORS.length];
|
|
25993
|
+
}
|
|
25994
|
+
|
|
25995
|
+
// src/components/DistributionChart/createDistributionChartWidget.ts
|
|
25996
|
+
var settingsIcon = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:16px;height:16px;pointer-events:none"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>`;
|
|
25997
|
+
var maximizeIcon = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:16px;height:16px;pointer-events:none"><polyline points="15 3 21 3 21 9"/><polyline points="9 21 3 21 3 15"/><line x1="21" y1="3" x2="14" y2="10"/><line x1="3" y1="21" x2="10" y2="14"/></svg>`;
|
|
25998
|
+
function createDistributionChartWidget(config) {
|
|
25999
|
+
const widgetId = `distribution-${config.domain}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
26000
|
+
let chartInstance = null;
|
|
26001
|
+
let currentMode = config.defaultMode || "groups";
|
|
26002
|
+
let currentTheme = config.theme || "light";
|
|
26003
|
+
let currentData = null;
|
|
26004
|
+
let containerElement = null;
|
|
26005
|
+
let isLoading = false;
|
|
26006
|
+
const title = config.title || getDomainTitle(config.domain);
|
|
26007
|
+
const chartHeight = config.chartHeight || 300;
|
|
26008
|
+
const showHeader = config.showHeader !== false;
|
|
26009
|
+
const showModeSelector = config.showModeSelector !== false;
|
|
26010
|
+
const showSettingsButton = config.showSettingsButton ?? false;
|
|
26011
|
+
const showMaximizeButton = config.showMaximizeButton ?? false;
|
|
26012
|
+
const decimalPlaces = config.decimalPlaces ?? 2;
|
|
26013
|
+
const modes = config.modes || getDefaultModes(config.domain);
|
|
26014
|
+
const groupColors = config.groupColors || getDefaultGroupColors(config.domain);
|
|
26015
|
+
function getDomainTitle(domain) {
|
|
26016
|
+
const titles = {
|
|
26017
|
+
energy: "Distribui\xE7\xE3o de Energia",
|
|
26018
|
+
water: "Distribui\xE7\xE3o de \xC1gua",
|
|
26019
|
+
gas: "Distribui\xE7\xE3o de G\xE1s",
|
|
26020
|
+
temperature: "Distribui\xE7\xE3o de Temperatura"
|
|
26021
|
+
};
|
|
26022
|
+
return titles[domain.toLowerCase()] || `Distribui\xE7\xE3o de ${domain}`;
|
|
26023
|
+
}
|
|
26024
|
+
function getDefaultModes(domain) {
|
|
26025
|
+
if (domain === "water") {
|
|
26026
|
+
return [
|
|
26027
|
+
{ value: "groups", label: "Lojas vs \xC1rea Comum" },
|
|
26028
|
+
{ value: "stores", label: "Lojas por Shopping" },
|
|
26029
|
+
{ value: "common", label: "\xC1rea Comum por Shopping" }
|
|
26030
|
+
];
|
|
26031
|
+
}
|
|
26032
|
+
return [
|
|
26033
|
+
{ value: "groups", label: "Por Grupos de Equipamentos" },
|
|
26034
|
+
{ value: "elevators", label: "Elevadores por Shopping" },
|
|
26035
|
+
{ value: "escalators", label: "Escadas Rolantes por Shopping" },
|
|
26036
|
+
{ value: "hvac", label: "Climatiza\xE7\xE3o por Shopping" },
|
|
26037
|
+
{ value: "others", label: "Outros Equipamentos por Shopping" },
|
|
26038
|
+
{ value: "stores", label: "Lojas por Shopping" }
|
|
26039
|
+
];
|
|
26040
|
+
}
|
|
26041
|
+
function $id(id) {
|
|
26042
|
+
if (config.$container) {
|
|
26043
|
+
return config.$container[0].querySelector(`#${id}`);
|
|
26044
|
+
}
|
|
26045
|
+
return document.getElementById(id);
|
|
26046
|
+
}
|
|
26047
|
+
function formatValue(value) {
|
|
26048
|
+
if (config.unitLarge && config.thresholdForLargeUnit && value >= config.thresholdForLargeUnit) {
|
|
26049
|
+
return `${(value / config.thresholdForLargeUnit).toFixed(decimalPlaces)} ${config.unitLarge}`;
|
|
26050
|
+
}
|
|
26051
|
+
return `${value.toFixed(decimalPlaces)} ${config.unit}`;
|
|
26052
|
+
}
|
|
26053
|
+
function getColor(key, index, isGroupMode2) {
|
|
26054
|
+
if (isGroupMode2) {
|
|
26055
|
+
return getGroupColor(key, groupColors, config.domain, index);
|
|
26056
|
+
}
|
|
26057
|
+
const shoppingColors = config.getShoppingColors?.();
|
|
26058
|
+
return getShoppingColor(key, shoppingColors, index);
|
|
26059
|
+
}
|
|
26060
|
+
function getColors2() {
|
|
26061
|
+
return getThemeColors2(currentTheme);
|
|
26062
|
+
}
|
|
26063
|
+
function isGroupMode() {
|
|
26064
|
+
return currentMode === "groups";
|
|
26065
|
+
}
|
|
26066
|
+
function renderHTML() {
|
|
26067
|
+
const colors = getColors2();
|
|
26068
|
+
const modeOptions = modes.map(
|
|
26069
|
+
(m) => `<option value="${m.value}" ${m.value === currentMode ? "selected" : ""}>${m.label}</option>`
|
|
26070
|
+
).join("");
|
|
26071
|
+
const headerButtons = [];
|
|
26072
|
+
if (showSettingsButton) {
|
|
26073
|
+
headerButtons.push(`
|
|
26074
|
+
<button id="${widgetId}-settings-btn" class="myio-dist-btn" title="Configura\xE7\xF5es">
|
|
26075
|
+
${settingsIcon}
|
|
26076
|
+
</button>
|
|
26077
|
+
`);
|
|
26078
|
+
}
|
|
26079
|
+
if (showMaximizeButton) {
|
|
26080
|
+
headerButtons.push(`
|
|
26081
|
+
<button id="${widgetId}-maximize-btn" class="myio-dist-btn" title="Expandir">
|
|
26082
|
+
${maximizeIcon}
|
|
26083
|
+
</button>
|
|
26084
|
+
`);
|
|
26085
|
+
}
|
|
26086
|
+
return `
|
|
26087
|
+
<style>
|
|
26088
|
+
#${widgetId} {
|
|
26089
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
26090
|
+
}
|
|
26091
|
+
#${widgetId} .myio-dist-header {
|
|
26092
|
+
display: flex;
|
|
26093
|
+
justify-content: space-between;
|
|
26094
|
+
align-items: center;
|
|
26095
|
+
margin-bottom: 16px;
|
|
26096
|
+
flex-wrap: wrap;
|
|
26097
|
+
gap: 12px;
|
|
26098
|
+
}
|
|
26099
|
+
#${widgetId} .myio-dist-title {
|
|
26100
|
+
margin: 0;
|
|
26101
|
+
font-size: 16px;
|
|
26102
|
+
font-weight: 600;
|
|
26103
|
+
color: ${colors.text};
|
|
26104
|
+
}
|
|
26105
|
+
#${widgetId} .myio-dist-controls {
|
|
26106
|
+
display: flex;
|
|
26107
|
+
align-items: center;
|
|
26108
|
+
gap: 8px;
|
|
26109
|
+
}
|
|
26110
|
+
#${widgetId} .myio-dist-label {
|
|
26111
|
+
font-size: 12px;
|
|
26112
|
+
color: ${colors.secondaryText};
|
|
26113
|
+
}
|
|
26114
|
+
#${widgetId} .myio-dist-select {
|
|
26115
|
+
padding: 6px 10px;
|
|
26116
|
+
border-radius: 6px;
|
|
26117
|
+
border: 1px solid ${colors.border};
|
|
26118
|
+
background: ${colors.cardBackground};
|
|
26119
|
+
color: ${colors.text};
|
|
26120
|
+
font-size: 12px;
|
|
26121
|
+
cursor: pointer;
|
|
26122
|
+
min-width: 180px;
|
|
26123
|
+
}
|
|
26124
|
+
#${widgetId} .myio-dist-select:focus {
|
|
26125
|
+
outline: none;
|
|
26126
|
+
border-color: #3e1a7d;
|
|
26127
|
+
}
|
|
26128
|
+
#${widgetId} .myio-dist-btn {
|
|
26129
|
+
display: flex;
|
|
26130
|
+
align-items: center;
|
|
26131
|
+
justify-content: center;
|
|
26132
|
+
padding: 6px 8px;
|
|
26133
|
+
border: 1px solid ${colors.border};
|
|
26134
|
+
border-radius: 6px;
|
|
26135
|
+
background: transparent;
|
|
26136
|
+
color: ${colors.text};
|
|
26137
|
+
cursor: pointer;
|
|
26138
|
+
transition: all 0.2s;
|
|
26139
|
+
}
|
|
26140
|
+
#${widgetId} .myio-dist-btn:hover {
|
|
26141
|
+
background: #3e1a7d;
|
|
26142
|
+
border-color: #3e1a7d;
|
|
26143
|
+
color: white;
|
|
26144
|
+
}
|
|
26145
|
+
#${widgetId} .myio-dist-chart-container {
|
|
26146
|
+
position: relative;
|
|
26147
|
+
height: ${chartHeight}px;
|
|
26148
|
+
}
|
|
26149
|
+
#${widgetId} .myio-dist-loading {
|
|
26150
|
+
position: absolute;
|
|
26151
|
+
top: 0;
|
|
26152
|
+
left: 0;
|
|
26153
|
+
right: 0;
|
|
26154
|
+
bottom: 0;
|
|
26155
|
+
display: flex;
|
|
26156
|
+
align-items: center;
|
|
26157
|
+
justify-content: center;
|
|
26158
|
+
background: ${colors.cardBackground}ee;
|
|
26159
|
+
z-index: 10;
|
|
26160
|
+
}
|
|
26161
|
+
#${widgetId} .myio-dist-spinner {
|
|
26162
|
+
width: 32px;
|
|
26163
|
+
height: 32px;
|
|
26164
|
+
border: 3px solid ${colors.border};
|
|
26165
|
+
border-top-color: #3e1a7d;
|
|
26166
|
+
border-radius: 50%;
|
|
26167
|
+
animation: myio-dist-spin 0.8s linear infinite;
|
|
26168
|
+
}
|
|
26169
|
+
@keyframes myio-dist-spin {
|
|
26170
|
+
to { transform: rotate(360deg); }
|
|
26171
|
+
}
|
|
26172
|
+
#${widgetId} .myio-dist-empty {
|
|
26173
|
+
display: flex;
|
|
26174
|
+
flex-direction: column;
|
|
26175
|
+
align-items: center;
|
|
26176
|
+
justify-content: center;
|
|
26177
|
+
height: 100%;
|
|
26178
|
+
color: ${colors.secondaryText};
|
|
26179
|
+
font-size: 14px;
|
|
26180
|
+
}
|
|
26181
|
+
#${widgetId} .myio-dist-empty-icon {
|
|
26182
|
+
font-size: 48px;
|
|
26183
|
+
margin-bottom: 12px;
|
|
26184
|
+
opacity: 0.5;
|
|
26185
|
+
}
|
|
26186
|
+
</style>
|
|
26187
|
+
|
|
26188
|
+
<div id="${widgetId}" class="myio-distribution-widget" style="
|
|
26189
|
+
background: ${colors.cardBackground};
|
|
26190
|
+
border-radius: 12px;
|
|
26191
|
+
padding: 16px;
|
|
26192
|
+
height: 100%;
|
|
26193
|
+
display: flex;
|
|
26194
|
+
flex-direction: column;
|
|
26195
|
+
">
|
|
26196
|
+
${showHeader ? `
|
|
26197
|
+
<div class="myio-dist-header">
|
|
26198
|
+
<h4 class="myio-dist-title">${title}</h4>
|
|
26199
|
+
<div class="myio-dist-controls">
|
|
26200
|
+
${showModeSelector && modes.length > 1 ? `
|
|
26201
|
+
<label for="${widgetId}-mode" class="myio-dist-label">Visualizar:</label>
|
|
26202
|
+
<select id="${widgetId}-mode" class="myio-dist-select">
|
|
26203
|
+
${modeOptions}
|
|
26204
|
+
</select>
|
|
26205
|
+
` : ""}
|
|
26206
|
+
${headerButtons.join("")}
|
|
26207
|
+
</div>
|
|
26208
|
+
</div>
|
|
26209
|
+
` : ""}
|
|
26210
|
+
|
|
26211
|
+
<div class="myio-dist-chart-container">
|
|
26212
|
+
<canvas id="${widgetId}-canvas"></canvas>
|
|
26213
|
+
<div id="${widgetId}-loading" class="myio-dist-loading" style="display: none;">
|
|
26214
|
+
<div class="myio-dist-spinner"></div>
|
|
26215
|
+
</div>
|
|
26216
|
+
</div>
|
|
26217
|
+
</div>
|
|
26218
|
+
`;
|
|
26219
|
+
}
|
|
26220
|
+
function setLoading(loading) {
|
|
26221
|
+
isLoading = loading;
|
|
26222
|
+
const loadingEl = $id(`${widgetId}-loading`);
|
|
26223
|
+
if (loadingEl) {
|
|
26224
|
+
loadingEl.style.display = loading ? "flex" : "none";
|
|
26225
|
+
}
|
|
26226
|
+
}
|
|
26227
|
+
function buildChartData(distribution) {
|
|
26228
|
+
const labels = [];
|
|
26229
|
+
const data = [];
|
|
26230
|
+
const backgroundColors = [];
|
|
26231
|
+
const total = Object.values(distribution).reduce((sum, val) => sum + val, 0);
|
|
26232
|
+
const isGroup = isGroupMode();
|
|
26233
|
+
const entries = Object.entries(distribution).filter(([_, value]) => value > 0).sort((a, b) => b[1] - a[1]);
|
|
26234
|
+
entries.forEach(([key, value], index) => {
|
|
26235
|
+
const percentage = total > 0 ? (value / total * 100).toFixed(1) : "0";
|
|
26236
|
+
labels.push(`${key} (${formatValue(value)} - ${percentage}%)`);
|
|
26237
|
+
data.push(value);
|
|
26238
|
+
backgroundColors.push(getColor(key, index, isGroup));
|
|
26239
|
+
});
|
|
26240
|
+
return { labels, data, backgroundColors, total };
|
|
26241
|
+
}
|
|
26242
|
+
function renderEmptyState() {
|
|
26243
|
+
const container = $id(`${widgetId}-canvas`)?.parentElement;
|
|
26244
|
+
if (container) {
|
|
26245
|
+
const emptyEl = document.createElement("div");
|
|
26246
|
+
emptyEl.className = "myio-dist-empty";
|
|
26247
|
+
emptyEl.innerHTML = `
|
|
26248
|
+
<div class="myio-dist-empty-icon">\u{1F4CA}</div>
|
|
26249
|
+
<div>Sem dados dispon\xEDveis</div>
|
|
26250
|
+
`;
|
|
26251
|
+
const canvas = $id(`${widgetId}-canvas`);
|
|
26252
|
+
if (canvas) canvas.style.display = "none";
|
|
26253
|
+
const existingEmpty = container.querySelector(".myio-dist-empty");
|
|
26254
|
+
if (!existingEmpty) {
|
|
26255
|
+
container.appendChild(emptyEl);
|
|
26256
|
+
}
|
|
26257
|
+
}
|
|
26258
|
+
}
|
|
26259
|
+
function removeEmptyState() {
|
|
26260
|
+
const container = $id(`${widgetId}-canvas`)?.parentElement;
|
|
26261
|
+
if (container) {
|
|
26262
|
+
const emptyEl = container.querySelector(".myio-dist-empty");
|
|
26263
|
+
if (emptyEl) emptyEl.remove();
|
|
26264
|
+
const canvas = $id(`${widgetId}-canvas`);
|
|
26265
|
+
if (canvas) canvas.style.display = "block";
|
|
26266
|
+
}
|
|
26267
|
+
}
|
|
26268
|
+
async function updateChart() {
|
|
26269
|
+
const canvas = $id(`${widgetId}-canvas`);
|
|
26270
|
+
if (!canvas) {
|
|
26271
|
+
console.error(`[${config.domain.toUpperCase()}] Distribution canvas not found`);
|
|
26272
|
+
return;
|
|
26273
|
+
}
|
|
26274
|
+
setLoading(true);
|
|
26275
|
+
try {
|
|
26276
|
+
const distribution = await config.fetchDistribution(currentMode);
|
|
26277
|
+
if (!distribution || Object.keys(distribution).length === 0) {
|
|
26278
|
+
console.warn(`[${config.domain.toUpperCase()}] No distribution data for mode: ${currentMode}`);
|
|
26279
|
+
currentData = null;
|
|
26280
|
+
setLoading(false);
|
|
26281
|
+
renderEmptyState();
|
|
26282
|
+
return;
|
|
26283
|
+
}
|
|
26284
|
+
removeEmptyState();
|
|
26285
|
+
currentData = distribution;
|
|
26286
|
+
const { labels, data, backgroundColors, total } = buildChartData(distribution);
|
|
26287
|
+
const colors = getColors2();
|
|
26288
|
+
const Chart2 = window.Chart;
|
|
26289
|
+
if (!Chart2) {
|
|
26290
|
+
throw new Error("Chart.js not loaded");
|
|
26291
|
+
}
|
|
26292
|
+
if (chartInstance) {
|
|
26293
|
+
chartInstance.destroy();
|
|
26294
|
+
chartInstance = null;
|
|
26295
|
+
}
|
|
26296
|
+
const ctx = canvas.getContext("2d");
|
|
26297
|
+
if (!ctx) {
|
|
26298
|
+
throw new Error("Could not get canvas context");
|
|
26299
|
+
}
|
|
26300
|
+
chartInstance = new Chart2(ctx, {
|
|
26301
|
+
type: "bar",
|
|
26302
|
+
data: {
|
|
26303
|
+
labels,
|
|
26304
|
+
datasets: [
|
|
26305
|
+
{
|
|
26306
|
+
label: `Consumo (${config.unit})`,
|
|
26307
|
+
data,
|
|
26308
|
+
backgroundColor: backgroundColors
|
|
26309
|
+
}
|
|
26310
|
+
]
|
|
26311
|
+
},
|
|
26312
|
+
options: {
|
|
26313
|
+
responsive: true,
|
|
26314
|
+
maintainAspectRatio: false,
|
|
26315
|
+
indexAxis: "y",
|
|
26316
|
+
// Horizontal bar chart
|
|
26317
|
+
animation: false,
|
|
26318
|
+
plugins: {
|
|
26319
|
+
legend: { display: false },
|
|
26320
|
+
tooltip: {
|
|
26321
|
+
callbacks: {
|
|
26322
|
+
label: (context) => {
|
|
26323
|
+
const value = context.parsed.x || 0;
|
|
26324
|
+
const percentage = total > 0 ? (value / total * 100).toFixed(1) : "0";
|
|
26325
|
+
return `${formatValue(value)} (${percentage}%)`;
|
|
26326
|
+
}
|
|
26327
|
+
}
|
|
26328
|
+
}
|
|
26329
|
+
},
|
|
26330
|
+
scales: {
|
|
26331
|
+
x: {
|
|
26332
|
+
beginAtZero: true,
|
|
26333
|
+
ticks: {
|
|
26334
|
+
callback: (value) => formatValue(Number(value)),
|
|
26335
|
+
color: colors.secondaryText,
|
|
26336
|
+
font: { size: 11 }
|
|
26337
|
+
},
|
|
26338
|
+
grid: { color: colors.grid }
|
|
26339
|
+
},
|
|
26340
|
+
y: {
|
|
26341
|
+
ticks: {
|
|
26342
|
+
font: { size: 11 },
|
|
26343
|
+
color: colors.text
|
|
26344
|
+
},
|
|
26345
|
+
grid: { display: false }
|
|
26346
|
+
}
|
|
26347
|
+
}
|
|
26348
|
+
}
|
|
26349
|
+
});
|
|
26350
|
+
config.onDataLoaded?.(distribution);
|
|
26351
|
+
console.log(`[${config.domain.toUpperCase()}] Distribution chart updated for mode: ${currentMode}`);
|
|
26352
|
+
} catch (error) {
|
|
26353
|
+
console.error(`[${config.domain.toUpperCase()}] Error updating distribution chart:`, error);
|
|
26354
|
+
config.onError?.(error);
|
|
26355
|
+
renderEmptyState();
|
|
26356
|
+
} finally {
|
|
26357
|
+
setLoading(false);
|
|
26358
|
+
}
|
|
26359
|
+
}
|
|
26360
|
+
function setupListeners() {
|
|
26361
|
+
const modeSelect = $id(`${widgetId}-mode`);
|
|
26362
|
+
if (modeSelect) {
|
|
26363
|
+
modeSelect.addEventListener("change", async (e) => {
|
|
26364
|
+
currentMode = e.target.value;
|
|
26365
|
+
config.onModeChange?.(currentMode);
|
|
26366
|
+
await updateChart();
|
|
26367
|
+
});
|
|
26368
|
+
}
|
|
26369
|
+
if (showSettingsButton) {
|
|
26370
|
+
const settingsBtn = $id(`${widgetId}-settings-btn`);
|
|
26371
|
+
if (settingsBtn) {
|
|
26372
|
+
settingsBtn.addEventListener("click", () => {
|
|
26373
|
+
config.onSettingsClick?.();
|
|
26374
|
+
});
|
|
26375
|
+
}
|
|
26376
|
+
}
|
|
26377
|
+
if (showMaximizeButton) {
|
|
26378
|
+
const maximizeBtn = $id(`${widgetId}-maximize-btn`);
|
|
26379
|
+
if (maximizeBtn) {
|
|
26380
|
+
maximizeBtn.addEventListener("click", () => {
|
|
26381
|
+
config.onMaximizeClick?.();
|
|
26382
|
+
});
|
|
26383
|
+
}
|
|
26384
|
+
}
|
|
26385
|
+
}
|
|
26386
|
+
function updateThemeStyles() {
|
|
26387
|
+
const colors = getColors2();
|
|
26388
|
+
const widget = $id(widgetId);
|
|
26389
|
+
if (widget) {
|
|
26390
|
+
widget.style.background = colors.cardBackground;
|
|
26391
|
+
const title2 = widget.querySelector(".myio-dist-title");
|
|
26392
|
+
if (title2) title2.style.color = colors.text;
|
|
26393
|
+
const labels = widget.querySelectorAll(".myio-dist-label");
|
|
26394
|
+
labels.forEach((l) => l.style.color = colors.secondaryText);
|
|
26395
|
+
const select = widget.querySelector(".myio-dist-select");
|
|
26396
|
+
if (select) {
|
|
26397
|
+
select.style.background = colors.cardBackground;
|
|
26398
|
+
select.style.color = colors.text;
|
|
26399
|
+
select.style.borderColor = colors.border;
|
|
26400
|
+
}
|
|
26401
|
+
const buttons = widget.querySelectorAll(".myio-dist-btn");
|
|
26402
|
+
buttons.forEach((b) => {
|
|
26403
|
+
b.style.color = colors.text;
|
|
26404
|
+
b.style.borderColor = colors.border;
|
|
26405
|
+
});
|
|
26406
|
+
}
|
|
26407
|
+
}
|
|
26408
|
+
const instance = {
|
|
26409
|
+
async render() {
|
|
26410
|
+
containerElement = $id(config.containerId);
|
|
26411
|
+
if (!containerElement) {
|
|
26412
|
+
throw new Error(`Container #${config.containerId} not found`);
|
|
26413
|
+
}
|
|
26414
|
+
containerElement.innerHTML = renderHTML();
|
|
26415
|
+
setupListeners();
|
|
26416
|
+
await updateChart();
|
|
26417
|
+
},
|
|
26418
|
+
async setMode(mode) {
|
|
26419
|
+
currentMode = mode;
|
|
26420
|
+
const modeSelect = $id(`${widgetId}-mode`);
|
|
26421
|
+
if (modeSelect) {
|
|
26422
|
+
modeSelect.value = mode;
|
|
26423
|
+
}
|
|
26424
|
+
config.onModeChange?.(mode);
|
|
26425
|
+
await updateChart();
|
|
26426
|
+
},
|
|
26427
|
+
async refresh() {
|
|
26428
|
+
await updateChart();
|
|
26429
|
+
},
|
|
26430
|
+
setTheme(theme) {
|
|
26431
|
+
currentTheme = theme;
|
|
26432
|
+
updateThemeStyles();
|
|
26433
|
+
if (currentData) {
|
|
26434
|
+
updateChart();
|
|
26435
|
+
}
|
|
26436
|
+
},
|
|
26437
|
+
destroy() {
|
|
26438
|
+
if (chartInstance) {
|
|
26439
|
+
chartInstance.destroy();
|
|
26440
|
+
chartInstance = null;
|
|
26441
|
+
}
|
|
26442
|
+
if (containerElement) {
|
|
26443
|
+
containerElement.innerHTML = "";
|
|
26444
|
+
}
|
|
26445
|
+
currentData = null;
|
|
26446
|
+
},
|
|
26447
|
+
getChartInstance: () => chartInstance,
|
|
26448
|
+
getCurrentMode: () => currentMode,
|
|
26449
|
+
getCurrentData: () => currentData
|
|
26450
|
+
};
|
|
26451
|
+
return instance;
|
|
26452
|
+
}
|
|
25676
26453
|
// Annotate the CommonJS export names for ESM import in node:
|
|
25677
26454
|
0 && (module.exports = {
|
|
25678
26455
|
CHART_COLORS,
|
|
@@ -25681,6 +26458,10 @@ var EXPORT_DOMAIN_UNITS = DOMAIN_UNITS;
|
|
|
25681
26458
|
CONSUMPTION_THEME_COLORS,
|
|
25682
26459
|
ConnectionStatusType,
|
|
25683
26460
|
DEFAULT_CLAMP_RANGE,
|
|
26461
|
+
DEFAULT_ENERGY_GROUP_COLORS,
|
|
26462
|
+
DEFAULT_GAS_GROUP_COLORS,
|
|
26463
|
+
DEFAULT_SHOPPING_COLORS,
|
|
26464
|
+
DEFAULT_WATER_GROUP_COLORS,
|
|
25684
26465
|
DeviceStatusType,
|
|
25685
26466
|
EXPORT_DEFAULT_COLORS,
|
|
25686
26467
|
EXPORT_DOMAIN_ICONS,
|
|
@@ -25694,6 +26475,7 @@ var EXPORT_DOMAIN_UNITS = DOMAIN_UNITS;
|
|
|
25694
26475
|
addDetectionContext,
|
|
25695
26476
|
addNamespace,
|
|
25696
26477
|
aggregateByDay,
|
|
26478
|
+
assignShoppingColors,
|
|
25697
26479
|
averageByDay,
|
|
25698
26480
|
buildListItemsThingsboardByUniqueDatasource,
|
|
25699
26481
|
buildMyioIngestionAuth,
|
|
@@ -25715,6 +26497,7 @@ var EXPORT_DOMAIN_UNITS = DOMAIN_UNITS;
|
|
|
25715
26497
|
createConsumptionChartWidget,
|
|
25716
26498
|
createConsumptionModal,
|
|
25717
26499
|
createDateRangePicker,
|
|
26500
|
+
createDistributionChartWidget,
|
|
25718
26501
|
createInputDateRangePickerInsideDIV,
|
|
25719
26502
|
createModalHeader,
|
|
25720
26503
|
decodePayload,
|
|
@@ -25753,11 +26536,16 @@ var EXPORT_DOMAIN_UNITS = DOMAIN_UNITS;
|
|
|
25753
26536
|
getAvailableContexts,
|
|
25754
26537
|
getConnectionStatusIcon,
|
|
25755
26538
|
getDateRangeArray,
|
|
26539
|
+
getDefaultGroupColors,
|
|
25756
26540
|
getDeviceStatusIcon,
|
|
25757
26541
|
getDeviceStatusInfo,
|
|
26542
|
+
getDistributionThemeColors,
|
|
26543
|
+
getGroupColor,
|
|
26544
|
+
getHashColor,
|
|
25758
26545
|
getModalHeaderStyles,
|
|
25759
26546
|
getSaoPauloISOString,
|
|
25760
26547
|
getSaoPauloISOStringFixed,
|
|
26548
|
+
getShoppingColor,
|
|
25761
26549
|
getValueByDatakey,
|
|
25762
26550
|
getValueByDatakeyLegacy,
|
|
25763
26551
|
getWaterCategories,
|