myio-js-library 0.1.162 → 0.1.164

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.js CHANGED
@@ -23149,7 +23149,7 @@ function createConsumption7DaysChart(config) {
23149
23149
  const isTemperature = config.domain === "temperature";
23150
23150
  let datasets;
23151
23151
  if (currentVizMode === "separate" && data.shoppingData && data.shoppingNames) {
23152
- const shoppingColors = [
23152
+ const shoppingColors = colors.shoppingColors || [
23153
23153
  "#2563eb",
23154
23154
  "#16a34a",
23155
23155
  "#ea580c",
@@ -23834,8 +23834,1279 @@ function createConsumptionModal(config) {
23834
23834
  return instance;
23835
23835
  }
23836
23836
 
23837
+ // src/components/Consumption7DaysChart/createConsumptionChartWidget.ts
23838
+ var DOMAIN_CONFIG4 = {
23839
+ energy: {
23840
+ name: "Energia",
23841
+ icon: "\u26A1",
23842
+ color: "#6c2fbf",
23843
+ colors: ["#2563eb", "#16a34a", "#8b5cf6", "#ea580c", "#dc2626"]
23844
+ },
23845
+ water: {
23846
+ name: "\xC1gua",
23847
+ icon: "\u{1F4A7}",
23848
+ color: "#0288d1",
23849
+ colors: ["#0288d1", "#06b6d4", "#0891b2", "#22d3ee", "#67e8f9"]
23850
+ },
23851
+ gas: {
23852
+ name: "G\xE1s",
23853
+ icon: "\u{1F525}",
23854
+ color: "#ea580c",
23855
+ colors: ["#ea580c", "#f97316", "#fb923c", "#fdba74", "#fed7aa"]
23856
+ },
23857
+ temperature: {
23858
+ name: "Temperatura",
23859
+ icon: "\u{1F321}\uFE0F",
23860
+ color: "#e65100",
23861
+ colors: ["#dc2626", "#059669", "#0ea5e9", "#f59e0b", "#8b5cf6"]
23862
+ }
23863
+ };
23864
+ function getWidgetStyles(theme, primaryColor) {
23865
+ const colors = THEME_COLORS[theme];
23866
+ return `
23867
+ .myio-chart-widget {
23868
+ font-family: Inter, system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;
23869
+ background: ${colors.chartBackground};
23870
+ border: 1px solid ${colors.border};
23871
+ border-radius: 16px;
23872
+ overflow: hidden;
23873
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
23874
+ }
23875
+
23876
+ .myio-chart-widget.dark {
23877
+ background: ${THEME_COLORS.dark.chartBackground};
23878
+ border-color: ${THEME_COLORS.dark.border};
23879
+ }
23880
+
23881
+ .myio-chart-widget-header {
23882
+ display: flex;
23883
+ justify-content: space-between;
23884
+ align-items: center;
23885
+ padding: 16px 20px;
23886
+ border-bottom: 1px solid ${colors.border};
23887
+ flex-wrap: wrap;
23888
+ gap: 12px;
23889
+ }
23890
+
23891
+ .myio-chart-widget-title-group {
23892
+ display: flex;
23893
+ align-items: center;
23894
+ gap: 10px;
23895
+ }
23896
+
23897
+ .myio-chart-widget-title {
23898
+ margin: 0;
23899
+ font-size: 16px;
23900
+ font-weight: 600;
23901
+ color: ${colors.text};
23902
+ }
23903
+
23904
+ .myio-chart-widget-controls {
23905
+ display: flex;
23906
+ align-items: center;
23907
+ gap: 12px;
23908
+ flex-wrap: wrap;
23909
+ }
23910
+
23911
+ .myio-chart-widget-tabs {
23912
+ display: flex;
23913
+ gap: 2px;
23914
+ background: ${theme === "dark" ? "#374151" : "#f3f4f6"};
23915
+ padding: 3px;
23916
+ border-radius: 8px;
23917
+ }
23918
+
23919
+ .myio-chart-widget-tab {
23920
+ padding: 6px 14px;
23921
+ font-size: 12px;
23922
+ font-weight: 500;
23923
+ border: none;
23924
+ background: transparent;
23925
+ color: ${colors.textMuted};
23926
+ cursor: pointer;
23927
+ border-radius: 6px;
23928
+ transition: all 0.2s;
23929
+ white-space: nowrap;
23930
+ }
23931
+
23932
+ .myio-chart-widget-tab:hover {
23933
+ color: ${colors.text};
23934
+ background: ${theme === "dark" ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.05)"};
23935
+ }
23936
+
23937
+ .myio-chart-widget-tab.active {
23938
+ background: ${primaryColor};
23939
+ color: white;
23940
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
23941
+ }
23942
+
23943
+ .myio-chart-widget-btn {
23944
+ background: transparent;
23945
+ border: 1px solid ${colors.border};
23946
+ font-size: 16px;
23947
+ cursor: pointer;
23948
+ padding: 6px 10px;
23949
+ border-radius: 6px;
23950
+ transition: all 0.2s;
23951
+ color: ${colors.text};
23952
+ }
23953
+
23954
+ .myio-chart-widget-btn:hover {
23955
+ background: ${primaryColor};
23956
+ border-color: ${primaryColor};
23957
+ color: white;
23958
+ }
23959
+
23960
+ .myio-chart-widget-body {
23961
+ position: relative;
23962
+ padding: 16px 20px;
23963
+ }
23964
+
23965
+ .myio-chart-widget-canvas-container {
23966
+ position: relative;
23967
+ width: 100%;
23968
+ }
23969
+
23970
+ .myio-chart-widget-loading {
23971
+ position: absolute;
23972
+ top: 0;
23973
+ left: 0;
23974
+ right: 0;
23975
+ bottom: 0;
23976
+ background: rgba(255, 255, 255, 0.9);
23977
+ display: flex;
23978
+ align-items: center;
23979
+ justify-content: center;
23980
+ z-index: 10;
23981
+ border-radius: 8px;
23982
+ }
23983
+
23984
+ .myio-chart-widget.dark .myio-chart-widget-loading {
23985
+ background: rgba(31, 41, 55, 0.9);
23986
+ }
23987
+
23988
+ .myio-chart-widget-spinner {
23989
+ width: 32px;
23990
+ height: 32px;
23991
+ border: 3px solid ${colors.border};
23992
+ border-top-color: ${primaryColor};
23993
+ border-radius: 50%;
23994
+ animation: myio-spin 1s linear infinite;
23995
+ }
23996
+
23997
+ @keyframes myio-spin {
23998
+ to { transform: rotate(360deg); }
23999
+ }
24000
+
24001
+ .myio-chart-widget-footer {
24002
+ display: flex;
24003
+ justify-content: space-around;
24004
+ padding: 16px 20px;
24005
+ border-top: 1px solid ${colors.border};
24006
+ gap: 16px;
24007
+ flex-wrap: wrap;
24008
+ }
24009
+
24010
+ .myio-chart-widget-stat {
24011
+ display: flex;
24012
+ flex-direction: column;
24013
+ align-items: center;
24014
+ text-align: center;
24015
+ min-width: 100px;
24016
+ }
24017
+
24018
+ .myio-chart-widget-stat-label {
24019
+ font-size: 11px;
24020
+ font-weight: 500;
24021
+ color: ${colors.textMuted};
24022
+ text-transform: uppercase;
24023
+ letter-spacing: 0.5px;
24024
+ margin-bottom: 4px;
24025
+ }
24026
+
24027
+ .myio-chart-widget-stat-value {
24028
+ font-size: 20px;
24029
+ font-weight: 700;
24030
+ color: ${colors.text};
24031
+ }
24032
+
24033
+ .myio-chart-widget-stat-value.primary {
24034
+ color: ${primaryColor};
24035
+ }
24036
+
24037
+ .myio-chart-widget-stat-sub {
24038
+ font-size: 11px;
24039
+ color: ${colors.textMuted};
24040
+ margin-top: 2px;
24041
+ }
24042
+
24043
+ /* Settings Modal Overlay */
24044
+ .myio-settings-overlay {
24045
+ position: fixed;
24046
+ inset: 0;
24047
+ background: rgba(0, 0, 0, 0.6);
24048
+ display: flex;
24049
+ align-items: center;
24050
+ justify-content: center;
24051
+ z-index: 99999;
24052
+ backdrop-filter: blur(4px);
24053
+ }
24054
+
24055
+ .myio-settings-overlay.hidden {
24056
+ display: none;
24057
+ }
24058
+
24059
+ .myio-settings-card {
24060
+ background: ${colors.chartBackground};
24061
+ border-radius: 10px;
24062
+ width: 90%;
24063
+ max-width: 600px;
24064
+ max-height: 90vh;
24065
+ display: flex;
24066
+ flex-direction: column;
24067
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
24068
+ overflow: hidden;
24069
+ }
24070
+
24071
+ .myio-settings-card .myio-modal-header {
24072
+ border-radius: 10px 10px 0 0;
24073
+ }
24074
+
24075
+ .myio-settings-body {
24076
+ padding: 20px;
24077
+ overflow-y: auto;
24078
+ display: flex;
24079
+ flex-direction: column;
24080
+ gap: 20px;
24081
+ }
24082
+
24083
+ .myio-settings-section {
24084
+ background: ${theme === "dark" ? "rgba(255,255,255,0.05)" : "#f8fafc"};
24085
+ border-radius: 10px;
24086
+ padding: 16px;
24087
+ border: 1px solid ${theme === "dark" ? "rgba(255,255,255,0.1)" : "#e2e8f0"};
24088
+ }
24089
+
24090
+ .myio-settings-section-label {
24091
+ font-size: 13px;
24092
+ font-weight: 600;
24093
+ color: ${colors.text};
24094
+ margin-bottom: 12px;
24095
+ display: flex;
24096
+ align-items: center;
24097
+ gap: 8px;
24098
+ }
24099
+
24100
+ .myio-settings-row {
24101
+ display: flex;
24102
+ gap: 16px;
24103
+ flex-wrap: wrap;
24104
+ align-items: flex-end;
24105
+ }
24106
+
24107
+ .myio-settings-field {
24108
+ display: flex;
24109
+ flex-direction: column;
24110
+ gap: 6px;
24111
+ flex: 1;
24112
+ min-width: 120px;
24113
+ }
24114
+
24115
+ .myio-settings-field-label {
24116
+ font-size: 12px;
24117
+ font-weight: 500;
24118
+ color: ${colors.textMuted};
24119
+ }
24120
+
24121
+ .myio-settings-input,
24122
+ .myio-settings-select {
24123
+ padding: 10px 14px;
24124
+ border: 1px solid ${colors.border};
24125
+ border-radius: 8px;
24126
+ font-size: 14px;
24127
+ background: ${colors.chartBackground};
24128
+ color: ${colors.text};
24129
+ width: 100%;
24130
+ }
24131
+
24132
+ .myio-settings-input:focus,
24133
+ .myio-settings-select:focus {
24134
+ outline: 2px solid ${primaryColor};
24135
+ outline-offset: 1px;
24136
+ }
24137
+
24138
+ .myio-settings-tabs {
24139
+ display: flex;
24140
+ gap: 2px;
24141
+ background: ${theme === "dark" ? "#374151" : "#e5e7eb"};
24142
+ padding: 3px;
24143
+ border-radius: 8px;
24144
+ }
24145
+
24146
+ .myio-settings-tab {
24147
+ flex: 1;
24148
+ padding: 8px 12px;
24149
+ font-size: 12px;
24150
+ font-weight: 500;
24151
+ border: none;
24152
+ background: transparent;
24153
+ color: ${colors.textMuted};
24154
+ cursor: pointer;
24155
+ border-radius: 6px;
24156
+ transition: all 0.2s;
24157
+ white-space: nowrap;
24158
+ }
24159
+
24160
+ .myio-settings-tab:hover {
24161
+ color: ${colors.text};
24162
+ background: ${theme === "dark" ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.05)"};
24163
+ }
24164
+
24165
+ .myio-settings-tab.active {
24166
+ background: ${primaryColor};
24167
+ color: white;
24168
+ }
24169
+
24170
+ .myio-settings-footer {
24171
+ display: flex;
24172
+ gap: 12px;
24173
+ justify-content: flex-end;
24174
+ padding: 16px 20px;
24175
+ border-top: 1px solid ${colors.border};
24176
+ background: ${theme === "dark" ? "rgba(0,0,0,0.2)" : "#fafafa"};
24177
+ }
24178
+
24179
+ .myio-settings-btn {
24180
+ padding: 10px 20px;
24181
+ border-radius: 8px;
24182
+ font-size: 14px;
24183
+ font-weight: 500;
24184
+ cursor: pointer;
24185
+ transition: all 0.2s;
24186
+ }
24187
+
24188
+ .myio-settings-btn-secondary {
24189
+ background: transparent;
24190
+ border: 1px solid ${colors.border};
24191
+ color: ${colors.text};
24192
+ }
24193
+
24194
+ .myio-settings-btn-secondary:hover {
24195
+ background: ${theme === "dark" ? "rgba(255,255,255,0.1)" : "#f3f4f6"};
24196
+ }
24197
+
24198
+ .myio-settings-btn-primary {
24199
+ background: ${primaryColor};
24200
+ border: none;
24201
+ color: white;
24202
+ }
24203
+
24204
+ .myio-settings-btn-primary:hover {
24205
+ filter: brightness(1.1);
24206
+ }
24207
+
24208
+ .myio-settings-hint {
24209
+ font-size: 11px;
24210
+ color: ${colors.textMuted};
24211
+ font-weight: normal;
24212
+ }
24213
+
24214
+ .myio-settings-context-group {
24215
+ margin-bottom: 8px;
24216
+ }
24217
+
24218
+ .myio-settings-context-group:last-child {
24219
+ margin-bottom: 0;
24220
+ }
24221
+
24222
+ /* Dropdown styles */
24223
+ .myio-settings-dropdown-container {
24224
+ position: relative;
24225
+ }
24226
+
24227
+ .myio-settings-dropdown-btn {
24228
+ padding: 10px 14px;
24229
+ border: 1px solid ${colors.border};
24230
+ border-radius: 8px;
24231
+ font-size: 14px;
24232
+ background: ${colors.chartBackground};
24233
+ color: ${colors.text};
24234
+ cursor: pointer;
24235
+ min-width: 180px;
24236
+ display: flex;
24237
+ align-items: center;
24238
+ justify-content: space-between;
24239
+ gap: 8px;
24240
+ width: 100%;
24241
+ }
24242
+
24243
+ .myio-settings-dropdown-btn:hover {
24244
+ border-color: ${primaryColor};
24245
+ }
24246
+
24247
+ .myio-settings-dropdown-arrow {
24248
+ font-size: 10px;
24249
+ color: ${colors.textMuted};
24250
+ }
24251
+
24252
+ .myio-settings-dropdown {
24253
+ position: absolute;
24254
+ top: calc(100% + 4px);
24255
+ left: 0;
24256
+ z-index: 100001;
24257
+ background: ${colors.chartBackground};
24258
+ border: 1px solid ${colors.border};
24259
+ border-radius: 8px;
24260
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
24261
+ min-width: 220px;
24262
+ padding: 8px 0;
24263
+ }
24264
+
24265
+ .myio-settings-dropdown.hidden {
24266
+ display: none;
24267
+ }
24268
+
24269
+ .myio-settings-dropdown-option {
24270
+ display: flex;
24271
+ align-items: center;
24272
+ gap: 10px;
24273
+ padding: 10px 14px;
24274
+ cursor: pointer;
24275
+ font-size: 13px;
24276
+ color: ${colors.text};
24277
+ transition: background 0.15s;
24278
+ }
24279
+
24280
+ .myio-settings-dropdown-option:hover {
24281
+ background: ${theme === "dark" ? "rgba(255,255,255,0.1)" : "#f3f4f6"};
24282
+ }
24283
+
24284
+ .myio-settings-dropdown-option input {
24285
+ width: 16px;
24286
+ height: 16px;
24287
+ cursor: pointer;
24288
+ accent-color: ${primaryColor};
24289
+ }
24290
+
24291
+ .myio-settings-dropdown-actions {
24292
+ border-top: 1px solid ${colors.border};
24293
+ margin-top: 8px;
24294
+ padding: 8px;
24295
+ display: flex;
24296
+ flex-direction: column;
24297
+ gap: 6px;
24298
+ }
24299
+
24300
+ .myio-settings-dropdown-actions button {
24301
+ width: 100%;
24302
+ padding: 8px;
24303
+ background: ${theme === "dark" ? "rgba(255,255,255,0.1)" : "#f3f4f6"};
24304
+ border: none;
24305
+ border-radius: 6px;
24306
+ cursor: pointer;
24307
+ font-size: 12px;
24308
+ color: ${colors.text};
24309
+ transition: background 0.15s;
24310
+ }
24311
+
24312
+ .myio-settings-dropdown-actions button:hover {
24313
+ background: ${theme === "dark" ? "rgba(255,255,255,0.15)" : "#e5e7eb"};
24314
+ }
24315
+
24316
+ /* Suggestion icon styles */
24317
+ .myio-settings-section-label span[id$="-settings-suggestion"] {
24318
+ transition: opacity 0.2s, transform 0.2s;
24319
+ }
24320
+
24321
+ .myio-settings-section-label span[id$="-settings-suggestion"]:hover {
24322
+ opacity: 1 !important;
24323
+ transform: scale(1.2);
24324
+ }
24325
+ `;
24326
+ }
24327
+ function createConsumptionChartWidget(config) {
24328
+ const widgetId = `myio-widget-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
24329
+ let containerElement = null;
24330
+ let chartInstance = null;
24331
+ let styleElement = null;
24332
+ let settingsModalElement = null;
24333
+ let settingsHeaderInstance = null;
24334
+ let currentTheme = config.theme ?? "light";
24335
+ let currentChartType = config.defaultChartType ?? "line";
24336
+ let currentVizMode = config.defaultVizMode ?? "total";
24337
+ let currentPeriod = config.defaultPeriod ?? 7;
24338
+ let currentIdealRange = config.idealRange ?? null;
24339
+ let isLoading = false;
24340
+ let tempPeriod = currentPeriod;
24341
+ let tempChartType = currentChartType;
24342
+ let tempVizMode = currentVizMode;
24343
+ let tempTheme = currentTheme;
24344
+ let tempIdealRange = currentIdealRange;
24345
+ let currentSuggestion = null;
24346
+ const domainCfg = DOMAIN_CONFIG4[config.domain] || DOMAIN_CONFIG4.energy;
24347
+ const primaryColor = config.colors?.primary || domainCfg.color;
24348
+ const domainColors = config.colors?.shoppingColors || domainCfg.colors;
24349
+ const showSettingsButton = config.showSettingsButton ?? true;
24350
+ const showMaximizeButton = config.showMaximizeButton ?? true;
24351
+ const showVizModeTabs = config.showVizModeTabs ?? true;
24352
+ const showChartTypeTabs = config.showChartTypeTabs ?? true;
24353
+ const chartHeight = typeof config.chartHeight === "number" ? `${config.chartHeight}px` : config.chartHeight ?? "300px";
24354
+ function getTitle() {
24355
+ if (config.title) return config.title;
24356
+ const domainName = config.domain === "temperature" ? "Temperatura" : "Consumo";
24357
+ return `${domainName} dos \xFAltimos ${currentPeriod} dias`;
24358
+ }
24359
+ function renderHTML() {
24360
+ return `
24361
+ <div id="${widgetId}" class="myio-chart-widget ${currentTheme === "dark" ? "dark" : ""} ${config.className || ""}">
24362
+ <div class="myio-chart-widget-header">
24363
+ <div class="myio-chart-widget-title-group">
24364
+ ${showSettingsButton ? `
24365
+ <button id="${widgetId}-settings-btn" class="myio-chart-widget-btn" title="Configura\xE7\xF5es">\u2699\uFE0F</button>
24366
+ ` : ""}
24367
+ <h4 id="${widgetId}-title" class="myio-chart-widget-title">${getTitle()}</h4>
24368
+ </div>
24369
+ <div class="myio-chart-widget-controls">
24370
+ ${showVizModeTabs ? `
24371
+ <div class="myio-chart-widget-tabs" id="${widgetId}-viz-tabs">
24372
+ <button class="myio-chart-widget-tab ${currentVizMode === "total" ? "active" : ""}" data-viz="total">Consolidado</button>
24373
+ <button class="myio-chart-widget-tab ${currentVizMode === "separate" ? "active" : ""}" data-viz="separate">Por Shopping</button>
24374
+ </div>
24375
+ ` : ""}
24376
+ ${showChartTypeTabs ? `
24377
+ <div class="myio-chart-widget-tabs" id="${widgetId}-type-tabs">
24378
+ <button class="myio-chart-widget-tab ${currentChartType === "line" ? "active" : ""}" data-type="line">Linhas</button>
24379
+ <button class="myio-chart-widget-tab ${currentChartType === "bar" ? "active" : ""}" data-type="bar">Barras</button>
24380
+ </div>
24381
+ ` : ""}
24382
+ ${showMaximizeButton ? `
24383
+ <button id="${widgetId}-maximize-btn" class="myio-chart-widget-btn" title="Maximizar">\u26F6</button>
24384
+ ` : ""}
24385
+ </div>
24386
+ </div>
24387
+ <div class="myio-chart-widget-body">
24388
+ <div id="${widgetId}-loading" class="myio-chart-widget-loading" style="display: none;">
24389
+ <div class="myio-chart-widget-spinner"></div>
24390
+ </div>
24391
+ <div class="myio-chart-widget-canvas-container" style="height: ${chartHeight};">
24392
+ <canvas id="${widgetId}-canvas"></canvas>
24393
+ </div>
24394
+ </div>
24395
+ <div class="myio-chart-widget-footer" id="${widgetId}-footer">
24396
+ <div class="myio-chart-widget-stat">
24397
+ <span class="myio-chart-widget-stat-label">Total Per\xEDodo</span>
24398
+ <span id="${widgetId}-stat-total" class="myio-chart-widget-stat-value primary">--</span>
24399
+ </div>
24400
+ <div class="myio-chart-widget-stat">
24401
+ <span class="myio-chart-widget-stat-label">M\xE9dia Di\xE1ria</span>
24402
+ <span id="${widgetId}-stat-avg" class="myio-chart-widget-stat-value">--</span>
24403
+ </div>
24404
+ <div class="myio-chart-widget-stat">
24405
+ <span class="myio-chart-widget-stat-label">Dia de Pico</span>
24406
+ <span id="${widgetId}-stat-peak" class="myio-chart-widget-stat-value">--</span>
24407
+ <span id="${widgetId}-stat-peak-date" class="myio-chart-widget-stat-sub"></span>
24408
+ </div>
24409
+ </div>
24410
+ </div>
24411
+ `;
24412
+ }
24413
+ function renderSettingsModal() {
24414
+ const unit = config.unit ?? "";
24415
+ const isTemperature = config.domain === "temperature";
24416
+ settingsHeaderInstance = createModalHeader({
24417
+ id: `${widgetId}-settings`,
24418
+ title: "Configura\xE7\xF5es",
24419
+ icon: "\u2699\uFE0F",
24420
+ theme: tempTheme,
24421
+ backgroundColor: primaryColor,
24422
+ showThemeToggle: false,
24423
+ showMaximize: false,
24424
+ showClose: true,
24425
+ onClose: () => closeSettingsModal()
24426
+ });
24427
+ return `
24428
+ <div id="${widgetId}-settings-overlay" class="myio-settings-overlay hidden">
24429
+ <div class="myio-settings-card">
24430
+ ${settingsHeaderInstance.render()}
24431
+ <div class="myio-settings-body">
24432
+ <!-- CONTEXT 1: Per\xEDodo e Dados -->
24433
+ <div class="myio-settings-context-group">
24434
+ <!-- Per\xEDodo -->
24435
+ <div class="myio-settings-section">
24436
+ <div class="myio-settings-section-label">\u{1F4C5} Per\xEDodo</div>
24437
+ <div class="myio-settings-row">
24438
+ <div class="myio-settings-field" style="flex: 1;">
24439
+ <select id="${widgetId}-settings-period" class="myio-settings-select">
24440
+ <option value="7" ${tempPeriod === 7 ? "selected" : ""}>\xDAltimos 7 dias</option>
24441
+ <option value="14" ${tempPeriod === 14 ? "selected" : ""}>\xDAltimos 14 dias</option>
24442
+ <option value="30" ${tempPeriod === 30 ? "selected" : ""}>\xDAltimos 30 dias</option>
24443
+ <option value="60" ${tempPeriod === 60 ? "selected" : ""}>\xDAltimos 60 dias</option>
24444
+ <option value="90" ${tempPeriod === 90 ? "selected" : ""}>\xDAltimos 90 dias</option>
24445
+ </select>
24446
+ </div>
24447
+ </div>
24448
+ </div>
24449
+
24450
+ <!-- Dados -->
24451
+ <div class="myio-settings-section">
24452
+ <div class="myio-settings-section-label">\u{1F4CA} Dados</div>
24453
+ <div class="myio-settings-row">
24454
+ <!-- Granularity Select -->
24455
+ <div class="myio-settings-field">
24456
+ <label class="myio-settings-field-label">Granularidade</label>
24457
+ <select id="${widgetId}-settings-granularity" class="myio-settings-select">
24458
+ <option value="1d" selected>\u{1F4C6} Por Dia</option>
24459
+ <option value="1h">\u{1F550} Por Hora</option>
24460
+ </select>
24461
+ </div>
24462
+
24463
+ <!-- Weekday Filter -->
24464
+ <div class="myio-settings-field">
24465
+ <label class="myio-settings-field-label">Dias da Semana</label>
24466
+ <div class="myio-settings-dropdown-container">
24467
+ <button type="button" id="${widgetId}-settings-weekday-btn" class="myio-settings-dropdown-btn">
24468
+ <span id="${widgetId}-settings-weekday-label">Todos os dias</span>
24469
+ <span class="myio-settings-dropdown-arrow">\u25BC</span>
24470
+ </button>
24471
+ <div id="${widgetId}-settings-weekday-dropdown" class="myio-settings-dropdown hidden">
24472
+ <label class="myio-settings-dropdown-option">
24473
+ <input type="checkbox" name="${widgetId}-weekday" value="dom" checked /> Domingo
24474
+ </label>
24475
+ <label class="myio-settings-dropdown-option">
24476
+ <input type="checkbox" name="${widgetId}-weekday" value="seg" checked /> Segunda-feira
24477
+ </label>
24478
+ <label class="myio-settings-dropdown-option">
24479
+ <input type="checkbox" name="${widgetId}-weekday" value="ter" checked /> Ter\xE7a-feira
24480
+ </label>
24481
+ <label class="myio-settings-dropdown-option">
24482
+ <input type="checkbox" name="${widgetId}-weekday" value="qua" checked /> Quarta-feira
24483
+ </label>
24484
+ <label class="myio-settings-dropdown-option">
24485
+ <input type="checkbox" name="${widgetId}-weekday" value="qui" checked /> Quinta-feira
24486
+ </label>
24487
+ <label class="myio-settings-dropdown-option">
24488
+ <input type="checkbox" name="${widgetId}-weekday" value="sex" checked /> Sexta-feira
24489
+ </label>
24490
+ <label class="myio-settings-dropdown-option">
24491
+ <input type="checkbox" name="${widgetId}-weekday" value="sab" checked /> S\xE1bado
24492
+ </label>
24493
+ <div class="myio-settings-dropdown-actions">
24494
+ <button type="button" id="${widgetId}-settings-weekday-all">Selecionar Todos</button>
24495
+ <button type="button" id="${widgetId}-settings-weekday-clear">Limpar</button>
24496
+ </div>
24497
+ </div>
24498
+ </div>
24499
+ </div>
24500
+
24501
+ <!-- Day Period Filter (only visible when hourly) -->
24502
+ <div class="myio-settings-field" id="${widgetId}-settings-dayperiod-field" style="display: none;">
24503
+ <label class="myio-settings-field-label">Per\xEDodos do Dia</label>
24504
+ <div class="myio-settings-dropdown-container">
24505
+ <button type="button" id="${widgetId}-settings-dayperiod-btn" class="myio-settings-dropdown-btn">
24506
+ <span id="${widgetId}-settings-dayperiod-label">Todos os per\xEDodos</span>
24507
+ <span class="myio-settings-dropdown-arrow">\u25BC</span>
24508
+ </button>
24509
+ <div id="${widgetId}-settings-dayperiod-dropdown" class="myio-settings-dropdown hidden">
24510
+ <label class="myio-settings-dropdown-option">
24511
+ <input type="checkbox" name="${widgetId}-dayperiod" value="madrugada" checked /> Madrugada (00h-06h)
24512
+ </label>
24513
+ <label class="myio-settings-dropdown-option">
24514
+ <input type="checkbox" name="${widgetId}-dayperiod" value="manha" checked /> Manh\xE3 (06h-12h)
24515
+ </label>
24516
+ <label class="myio-settings-dropdown-option">
24517
+ <input type="checkbox" name="${widgetId}-dayperiod" value="tarde" checked /> Tarde (12h-18h)
24518
+ </label>
24519
+ <label class="myio-settings-dropdown-option">
24520
+ <input type="checkbox" name="${widgetId}-dayperiod" value="noite" checked /> Noite (18h-24h)
24521
+ </label>
24522
+ <div class="myio-settings-dropdown-actions">
24523
+ <button type="button" id="${widgetId}-settings-dayperiod-all">Selecionar Todos</button>
24524
+ <button type="button" id="${widgetId}-settings-dayperiod-clear">Limpar</button>
24525
+ </div>
24526
+ </div>
24527
+ </div>
24528
+ </div>
24529
+ </div>
24530
+ </div>
24531
+ </div>
24532
+
24533
+ <!-- CONTEXT 2: Faixa Ideal -->
24534
+ <div class="myio-settings-context-group">
24535
+ <div class="myio-settings-section">
24536
+ <div class="myio-settings-section-label">
24537
+ \u{1F3AF} Faixa Ideal
24538
+ <span class="myio-settings-hint" id="${widgetId}-settings-range-hint">(opcional - deixe zerado para n\xE3o exibir)</span>
24539
+ <span
24540
+ id="${widgetId}-settings-suggestion"
24541
+ title=""
24542
+ style="cursor: pointer; font-size: 16px; opacity: 0.7; transition: opacity 0.2s; margin-left: 4px;"
24543
+ >\u{1F4A1}</span>
24544
+ </div>
24545
+ <div class="myio-settings-row">
24546
+ <div class="myio-settings-field" style="min-width: 100px;">
24547
+ <label class="myio-settings-field-label">M\xEDnimo (${unit})</label>
24548
+ <input type="number" id="${widgetId}-settings-range-min" class="myio-settings-input"
24549
+ value="${tempIdealRange?.min ?? ""}" placeholder="0" step="0.1">
24550
+ </div>
24551
+ <div class="myio-settings-field" style="min-width: 100px;">
24552
+ <label class="myio-settings-field-label">M\xE1ximo (${unit})</label>
24553
+ <input type="number" id="${widgetId}-settings-range-max" class="myio-settings-input"
24554
+ value="${tempIdealRange?.max ?? ""}" placeholder="0" step="0.1">
24555
+ </div>
24556
+ <div class="myio-settings-field" style="flex: 1;">
24557
+ <label class="myio-settings-field-label">R\xF3tulo</label>
24558
+ <input type="text" id="${widgetId}-settings-range-label" class="myio-settings-input"
24559
+ value="${tempIdealRange?.label ?? ""}" placeholder="${isTemperature ? "Faixa Ideal" : "Meta de Consumo"}">
24560
+ </div>
24561
+ </div>
24562
+ </div>
24563
+ </div>
24564
+
24565
+ <!-- CONTEXT 3: Visualiza\xE7\xE3o -->
24566
+ <div class="myio-settings-context-group">
24567
+ <div class="myio-settings-section">
24568
+ <div class="myio-settings-section-label">\u{1F3A8} Visualiza\xE7\xE3o</div>
24569
+ <div class="myio-settings-row" style="gap: 20px; flex-wrap: wrap;">
24570
+ <!-- Chart Type -->
24571
+ <div class="myio-settings-field" style="flex: 1; min-width: 180px;">
24572
+ <label class="myio-settings-field-label">Tipo de Gr\xE1fico</label>
24573
+ <div class="myio-settings-tabs" id="${widgetId}-settings-chart-type">
24574
+ <button class="myio-settings-tab ${tempChartType === "line" ? "active" : ""}" data-type="line">\u{1F4C8} Linhas</button>
24575
+ <button class="myio-settings-tab ${tempChartType === "bar" ? "active" : ""}" data-type="bar">\u{1F4CA} Barras</button>
24576
+ </div>
24577
+ </div>
24578
+
24579
+ <!-- Viz Mode -->
24580
+ <div class="myio-settings-field" style="flex: 1; min-width: 200px;">
24581
+ <label class="myio-settings-field-label">Agrupamento</label>
24582
+ <div class="myio-settings-tabs" id="${widgetId}-settings-viz-mode">
24583
+ <button class="myio-settings-tab ${tempVizMode === "total" ? "active" : ""}" data-viz="total">\u{1F517} Consolidado</button>
24584
+ <button class="myio-settings-tab ${tempVizMode === "separate" ? "active" : ""}" data-viz="separate">\u{1F3EC} Por Shopping</button>
24585
+ </div>
24586
+ </div>
24587
+
24588
+ <!-- Theme -->
24589
+ <div class="myio-settings-field" style="flex: 1; min-width: 160px;">
24590
+ <label class="myio-settings-field-label">Tema</label>
24591
+ <div class="myio-settings-tabs" id="${widgetId}-settings-theme">
24592
+ <button class="myio-settings-tab ${tempTheme === "light" ? "active" : ""}" data-theme="light">\u2600\uFE0F Light</button>
24593
+ <button class="myio-settings-tab ${tempTheme === "dark" ? "active" : ""}" data-theme="dark">\u{1F319} Dark</button>
24594
+ </div>
24595
+ </div>
24596
+ </div>
24597
+ </div>
24598
+ </div>
24599
+ </div>
24600
+ <div class="myio-settings-footer">
24601
+ <button id="${widgetId}-settings-reset" class="myio-settings-btn myio-settings-btn-secondary">Resetar</button>
24602
+ <button id="${widgetId}-settings-apply" class="myio-settings-btn myio-settings-btn-primary">Carregar</button>
24603
+ </div>
24604
+ </div>
24605
+ </div>
24606
+ `;
24607
+ }
24608
+ function injectStyles() {
24609
+ if (styleElement) return;
24610
+ styleElement = document.createElement("style");
24611
+ styleElement.id = `${widgetId}-styles`;
24612
+ styleElement.textContent = getWidgetStyles(currentTheme, primaryColor);
24613
+ document.head.appendChild(styleElement);
24614
+ }
24615
+ function updateStyles() {
24616
+ if (styleElement) {
24617
+ styleElement.textContent = getWidgetStyles(currentTheme, primaryColor);
24618
+ }
24619
+ }
24620
+ function setupListeners() {
24621
+ if (showSettingsButton) {
24622
+ document.getElementById(`${widgetId}-settings-btn`)?.addEventListener("click", () => {
24623
+ openSettingsModal();
24624
+ config.onSettingsClick?.();
24625
+ });
24626
+ }
24627
+ if (showMaximizeButton && config.onMaximizeClick) {
24628
+ document.getElementById(`${widgetId}-maximize-btn`)?.addEventListener("click", () => {
24629
+ config.onMaximizeClick?.();
24630
+ });
24631
+ }
24632
+ if (showVizModeTabs) {
24633
+ document.getElementById(`${widgetId}-viz-tabs`)?.addEventListener("click", (e) => {
24634
+ const target = e.target;
24635
+ if (target.classList.contains("myio-chart-widget-tab")) {
24636
+ const mode = target.dataset.viz;
24637
+ if (mode) {
24638
+ instance.setVizMode(mode);
24639
+ }
24640
+ }
24641
+ });
24642
+ }
24643
+ if (showChartTypeTabs) {
24644
+ document.getElementById(`${widgetId}-type-tabs`)?.addEventListener("click", (e) => {
24645
+ const target = e.target;
24646
+ if (target.classList.contains("myio-chart-widget-tab")) {
24647
+ const type = target.dataset.type;
24648
+ if (type) {
24649
+ instance.setChartType(type);
24650
+ }
24651
+ }
24652
+ });
24653
+ }
24654
+ }
24655
+ function updateTabStates() {
24656
+ document.querySelectorAll(`#${widgetId}-viz-tabs .myio-chart-widget-tab`).forEach((tab) => {
24657
+ const btn = tab;
24658
+ btn.classList.toggle("active", btn.dataset.viz === currentVizMode);
24659
+ });
24660
+ document.querySelectorAll(`#${widgetId}-type-tabs .myio-chart-widget-tab`).forEach((tab) => {
24661
+ const btn = tab;
24662
+ btn.classList.toggle("active", btn.dataset.type === currentChartType);
24663
+ });
24664
+ }
24665
+ function updateTitle() {
24666
+ const titleEl = document.getElementById(`${widgetId}-title`);
24667
+ if (titleEl) {
24668
+ titleEl.textContent = getTitle();
24669
+ }
24670
+ }
24671
+ function setLoading(loading) {
24672
+ isLoading = loading;
24673
+ const loadingEl = document.getElementById(`${widgetId}-loading`);
24674
+ if (loadingEl) {
24675
+ loadingEl.style.display = loading ? "flex" : "none";
24676
+ }
24677
+ }
24678
+ function formatValue(value) {
24679
+ const unit = config.unit ?? "";
24680
+ const unitLarge = config.unitLarge;
24681
+ const threshold = config.thresholdForLargeUnit ?? 1e3;
24682
+ if (unitLarge && Math.abs(value) >= threshold) {
24683
+ return `${(value / threshold).toFixed(2)} ${unitLarge}`;
24684
+ }
24685
+ return `${value.toFixed(2)} ${unit}`;
24686
+ }
24687
+ function updateFooterStats(data) {
24688
+ const totalEl = document.getElementById(`${widgetId}-stat-total`);
24689
+ const avgEl = document.getElementById(`${widgetId}-stat-avg`);
24690
+ const peakEl = document.getElementById(`${widgetId}-stat-peak`);
24691
+ const peakDateEl = document.getElementById(`${widgetId}-stat-peak-date`);
24692
+ if (!data.dailyTotals || data.dailyTotals.length === 0) {
24693
+ if (totalEl) totalEl.textContent = "--";
24694
+ if (avgEl) avgEl.textContent = "--";
24695
+ if (peakEl) peakEl.textContent = "--";
24696
+ if (peakDateEl) peakDateEl.textContent = "";
24697
+ return;
24698
+ }
24699
+ const isTemperature = config.domain === "temperature";
24700
+ const totals = data.dailyTotals;
24701
+ const labels = data.labels ?? [];
24702
+ const total = totals.reduce((a, b) => a + b, 0);
24703
+ const avg = total / totals.length;
24704
+ const peakValue = Math.max(...totals);
24705
+ const peakIndex = totals.indexOf(peakValue);
24706
+ const peakDate = labels[peakIndex] ?? "";
24707
+ if (totalEl) {
24708
+ if (isTemperature) {
24709
+ totalEl.textContent = formatValue(avg);
24710
+ const labelEl = totalEl.previousElementSibling;
24711
+ if (labelEl) labelEl.textContent = "M\xE9dia Per\xEDodo";
24712
+ } else {
24713
+ totalEl.textContent = formatValue(total);
24714
+ }
24715
+ }
24716
+ if (avgEl) {
24717
+ avgEl.textContent = formatValue(avg);
24718
+ }
24719
+ if (peakEl) {
24720
+ peakEl.textContent = formatValue(peakValue);
24721
+ }
24722
+ if (peakDateEl) {
24723
+ peakDateEl.textContent = peakDate;
24724
+ }
24725
+ }
24726
+ function openSettingsModal() {
24727
+ tempPeriod = currentPeriod;
24728
+ tempChartType = currentChartType;
24729
+ tempVizMode = currentVizMode;
24730
+ tempTheme = currentTheme;
24731
+ tempIdealRange = currentIdealRange ? { ...currentIdealRange } : null;
24732
+ if (!settingsModalElement) {
24733
+ settingsModalElement = document.createElement("div");
24734
+ settingsModalElement.innerHTML = renderSettingsModal();
24735
+ document.body.appendChild(settingsModalElement.firstElementChild);
24736
+ settingsModalElement = document.getElementById(`${widgetId}-settings-overlay`);
24737
+ setupSettingsModalListeners();
24738
+ }
24739
+ updateSettingsModalValues();
24740
+ updateIdealRangeSuggestionTooltip();
24741
+ settingsModalElement?.classList.remove("hidden");
24742
+ }
24743
+ function closeSettingsModal() {
24744
+ settingsModalElement?.classList.add("hidden");
24745
+ }
24746
+ function updateSettingsModalValues() {
24747
+ const periodSelect = document.getElementById(`${widgetId}-settings-period`);
24748
+ if (periodSelect) periodSelect.value = String(tempPeriod);
24749
+ const minInput = document.getElementById(`${widgetId}-settings-range-min`);
24750
+ const maxInput = document.getElementById(`${widgetId}-settings-range-max`);
24751
+ const labelInput = document.getElementById(`${widgetId}-settings-range-label`);
24752
+ if (minInput) minInput.value = tempIdealRange?.min?.toString() ?? "";
24753
+ if (maxInput) maxInput.value = tempIdealRange?.max?.toString() ?? "";
24754
+ if (labelInput) labelInput.value = tempIdealRange?.label ?? "";
24755
+ updateSettingsModalTabs();
24756
+ }
24757
+ function updateSettingsModalTabs() {
24758
+ document.querySelectorAll(`#${widgetId}-settings-chart-type .myio-settings-tab`).forEach((tab) => {
24759
+ const btn = tab;
24760
+ btn.classList.toggle("active", btn.dataset.type === tempChartType);
24761
+ });
24762
+ document.querySelectorAll(`#${widgetId}-settings-viz-mode .myio-settings-tab`).forEach((tab) => {
24763
+ const btn = tab;
24764
+ btn.classList.toggle("active", btn.dataset.viz === tempVizMode);
24765
+ });
24766
+ document.querySelectorAll(`#${widgetId}-settings-theme .myio-settings-tab`).forEach((tab) => {
24767
+ const btn = tab;
24768
+ btn.classList.toggle("active", btn.dataset.theme === tempTheme);
24769
+ });
24770
+ }
24771
+ function updateWeekdayLabel() {
24772
+ const checkboxes = document.querySelectorAll(`input[name="${widgetId}-weekday"]`);
24773
+ const checked = Array.from(checkboxes).filter((cb) => cb.checked);
24774
+ const label = document.getElementById(`${widgetId}-settings-weekday-label`);
24775
+ if (label) {
24776
+ if (checked.length === 0) {
24777
+ label.textContent = "Nenhum dia";
24778
+ } else if (checked.length === checkboxes.length) {
24779
+ label.textContent = "Todos os dias";
24780
+ } else {
24781
+ label.textContent = `${checked.length} dias selecionados`;
24782
+ }
24783
+ }
24784
+ }
24785
+ function updateDayPeriodLabel() {
24786
+ const checkboxes = document.querySelectorAll(`input[name="${widgetId}-dayperiod"]`);
24787
+ const checked = Array.from(checkboxes).filter((cb) => cb.checked);
24788
+ const label = document.getElementById(`${widgetId}-settings-dayperiod-label`);
24789
+ if (label) {
24790
+ if (checked.length === 0) {
24791
+ label.textContent = "Nenhum per\xEDodo";
24792
+ } else if (checked.length === checkboxes.length) {
24793
+ label.textContent = "Todos os per\xEDodos";
24794
+ } else {
24795
+ label.textContent = `${checked.length} per\xEDodos selecionados`;
24796
+ }
24797
+ }
24798
+ }
24799
+ function calculateIdealRangeSuggestion() {
24800
+ const data = chartInstance?.getCachedData();
24801
+ if (!data || !data.dailyTotals || data.dailyTotals.length === 0) {
24802
+ return { min: 0, max: 0, avg: 0 };
24803
+ }
24804
+ const total = data.dailyTotals.reduce((a, b) => a + b, 0);
24805
+ const avg = total / data.dailyTotals.length;
24806
+ const min = avg * 0.85;
24807
+ const max = avg * 1.15;
24808
+ return {
24809
+ min: Math.round(min * 10) / 10,
24810
+ max: Math.round(max * 10) / 10,
24811
+ avg: Math.round(avg * 10) / 10
24812
+ };
24813
+ }
24814
+ function updateIdealRangeSuggestionTooltip() {
24815
+ const suggestion = calculateIdealRangeSuggestion();
24816
+ const suggestionEl = document.getElementById(`${widgetId}-settings-suggestion`);
24817
+ const hintEl = document.getElementById(`${widgetId}-settings-range-hint`);
24818
+ const unit = config.unit ?? "";
24819
+ const isTemperature = config.domain === "temperature";
24820
+ currentSuggestion = suggestion;
24821
+ if (hintEl) {
24822
+ if (isTemperature) {
24823
+ hintEl.textContent = "(valores carregados do cliente)";
24824
+ } else {
24825
+ hintEl.textContent = "(opcional - deixe zerado para n\xE3o exibir)";
24826
+ }
24827
+ }
24828
+ if (suggestionEl) {
24829
+ if (suggestion.avg > 0) {
24830
+ const tooltipText = `Sugest\xE3o: ${suggestion.min} - ${suggestion.max} ${unit} (m\xE9dia \xB115%). Clique para aplicar.`;
24831
+ suggestionEl.title = tooltipText;
24832
+ suggestionEl.style.display = "inline";
24833
+ } else {
24834
+ suggestionEl.style.display = "none";
24835
+ }
24836
+ }
24837
+ }
24838
+ function applyIdealRangeSuggestion() {
24839
+ if (!currentSuggestion || currentSuggestion.min === 0 && currentSuggestion.max === 0) {
24840
+ return;
24841
+ }
24842
+ const minInput = document.getElementById(`${widgetId}-settings-range-min`);
24843
+ const maxInput = document.getElementById(`${widgetId}-settings-range-max`);
24844
+ const labelInput = document.getElementById(`${widgetId}-settings-range-label`);
24845
+ if (minInput) minInput.value = String(currentSuggestion.min);
24846
+ if (maxInput) maxInput.value = String(currentSuggestion.max);
24847
+ if (labelInput) labelInput.value = "Faixa Sugerida";
24848
+ tempIdealRange = {
24849
+ min: currentSuggestion.min,
24850
+ max: currentSuggestion.max,
24851
+ label: "Faixa Sugerida"
24852
+ };
24853
+ }
24854
+ function setupSettingsModalListeners() {
24855
+ settingsHeaderInstance?.attachListeners();
24856
+ document.getElementById(`${widgetId}-settings-overlay`)?.addEventListener("click", (e) => {
24857
+ if (e.target.classList.contains("myio-settings-overlay")) {
24858
+ closeSettingsModal();
24859
+ }
24860
+ });
24861
+ document.getElementById(`${widgetId}-settings-granularity`)?.addEventListener("change", (e) => {
24862
+ const select = e.target;
24863
+ const dayPeriodField = document.getElementById(`${widgetId}-settings-dayperiod-field`);
24864
+ if (dayPeriodField) {
24865
+ dayPeriodField.style.display = select.value === "1h" ? "block" : "none";
24866
+ }
24867
+ });
24868
+ document.getElementById(`${widgetId}-settings-suggestion`)?.addEventListener("click", () => {
24869
+ applyIdealRangeSuggestion();
24870
+ });
24871
+ document.getElementById(`${widgetId}-settings-weekday-btn`)?.addEventListener("click", (e) => {
24872
+ e.stopPropagation();
24873
+ const dropdown = document.getElementById(`${widgetId}-settings-weekday-dropdown`);
24874
+ dropdown?.classList.toggle("hidden");
24875
+ });
24876
+ document.querySelectorAll(`input[name="${widgetId}-weekday"]`).forEach((cb) => {
24877
+ cb.addEventListener("change", updateWeekdayLabel);
24878
+ });
24879
+ document.getElementById(`${widgetId}-settings-weekday-all`)?.addEventListener("click", () => {
24880
+ document.querySelectorAll(`input[name="${widgetId}-weekday"]`).forEach((cb) => {
24881
+ cb.checked = true;
24882
+ });
24883
+ updateWeekdayLabel();
24884
+ });
24885
+ document.getElementById(`${widgetId}-settings-weekday-clear`)?.addEventListener("click", () => {
24886
+ document.querySelectorAll(`input[name="${widgetId}-weekday"]`).forEach((cb) => {
24887
+ cb.checked = false;
24888
+ });
24889
+ updateWeekdayLabel();
24890
+ });
24891
+ document.getElementById(`${widgetId}-settings-dayperiod-btn`)?.addEventListener("click", (e) => {
24892
+ e.stopPropagation();
24893
+ const dropdown = document.getElementById(`${widgetId}-settings-dayperiod-dropdown`);
24894
+ dropdown?.classList.toggle("hidden");
24895
+ });
24896
+ document.querySelectorAll(`input[name="${widgetId}-dayperiod"]`).forEach((cb) => {
24897
+ cb.addEventListener("change", updateDayPeriodLabel);
24898
+ });
24899
+ document.getElementById(`${widgetId}-settings-dayperiod-all`)?.addEventListener("click", () => {
24900
+ document.querySelectorAll(`input[name="${widgetId}-dayperiod"]`).forEach((cb) => {
24901
+ cb.checked = true;
24902
+ });
24903
+ updateDayPeriodLabel();
24904
+ });
24905
+ document.getElementById(`${widgetId}-settings-dayperiod-clear`)?.addEventListener("click", () => {
24906
+ document.querySelectorAll(`input[name="${widgetId}-dayperiod"]`).forEach((cb) => {
24907
+ cb.checked = false;
24908
+ });
24909
+ updateDayPeriodLabel();
24910
+ });
24911
+ document.addEventListener("click", (e) => {
24912
+ const target = e.target;
24913
+ const weekdayDropdown = document.getElementById(`${widgetId}-settings-weekday-dropdown`);
24914
+ const dayperiodDropdown = document.getElementById(`${widgetId}-settings-dayperiod-dropdown`);
24915
+ if (weekdayDropdown && !target.closest(`#${widgetId}-settings-weekday-btn`) && !target.closest(`#${widgetId}-settings-weekday-dropdown`)) {
24916
+ weekdayDropdown.classList.add("hidden");
24917
+ }
24918
+ if (dayperiodDropdown && !target.closest(`#${widgetId}-settings-dayperiod-btn`) && !target.closest(`#${widgetId}-settings-dayperiod-dropdown`)) {
24919
+ dayperiodDropdown.classList.add("hidden");
24920
+ }
24921
+ });
24922
+ document.getElementById(`${widgetId}-settings-chart-type`)?.addEventListener("click", (e) => {
24923
+ const target = e.target;
24924
+ if (target.classList.contains("myio-settings-tab")) {
24925
+ tempChartType = target.dataset.type;
24926
+ updateSettingsModalTabs();
24927
+ }
24928
+ });
24929
+ document.getElementById(`${widgetId}-settings-viz-mode`)?.addEventListener("click", (e) => {
24930
+ const target = e.target;
24931
+ if (target.classList.contains("myio-settings-tab")) {
24932
+ tempVizMode = target.dataset.viz;
24933
+ updateSettingsModalTabs();
24934
+ }
24935
+ });
24936
+ document.getElementById(`${widgetId}-settings-theme`)?.addEventListener("click", (e) => {
24937
+ const target = e.target;
24938
+ if (target.classList.contains("myio-settings-tab")) {
24939
+ tempTheme = target.dataset.theme;
24940
+ updateSettingsModalTabs();
24941
+ }
24942
+ });
24943
+ document.getElementById(`${widgetId}-settings-reset`)?.addEventListener("click", () => {
24944
+ tempPeriod = config.defaultPeriod ?? 7;
24945
+ tempChartType = config.defaultChartType ?? "line";
24946
+ tempVizMode = config.defaultVizMode ?? "total";
24947
+ tempTheme = config.theme ?? "light";
24948
+ tempIdealRange = config.idealRange ?? null;
24949
+ const granularitySelect = document.getElementById(`${widgetId}-settings-granularity`);
24950
+ if (granularitySelect) granularitySelect.value = "1d";
24951
+ const dayPeriodField = document.getElementById(`${widgetId}-settings-dayperiod-field`);
24952
+ if (dayPeriodField) dayPeriodField.style.display = "none";
24953
+ document.querySelectorAll(`input[name="${widgetId}-weekday"]`).forEach((cb) => {
24954
+ cb.checked = true;
24955
+ });
24956
+ updateWeekdayLabel();
24957
+ document.querySelectorAll(`input[name="${widgetId}-dayperiod"]`).forEach((cb) => {
24958
+ cb.checked = true;
24959
+ });
24960
+ updateDayPeriodLabel();
24961
+ updateSettingsModalValues();
24962
+ });
24963
+ document.getElementById(`${widgetId}-settings-apply`)?.addEventListener("click", async () => {
24964
+ const minInput = document.getElementById(`${widgetId}-settings-range-min`);
24965
+ const maxInput = document.getElementById(`${widgetId}-settings-range-max`);
24966
+ const labelInput = document.getElementById(`${widgetId}-settings-range-label`);
24967
+ const periodSelect = document.getElementById(`${widgetId}-settings-period`);
24968
+ const min = parseFloat(minInput?.value || "0");
24969
+ const max = parseFloat(maxInput?.value || "0");
24970
+ const label = labelInput?.value || "";
24971
+ tempPeriod = parseInt(periodSelect?.value || "7", 10);
24972
+ if (min > 0 || max > 0) {
24973
+ tempIdealRange = { min, max, label };
24974
+ } else {
24975
+ tempIdealRange = null;
24976
+ }
24977
+ closeSettingsModal();
24978
+ if (tempTheme !== currentTheme) {
24979
+ instance.setTheme(tempTheme);
24980
+ }
24981
+ if (tempChartType !== currentChartType) {
24982
+ instance.setChartType(tempChartType);
24983
+ }
24984
+ if (tempVizMode !== currentVizMode) {
24985
+ instance.setVizMode(tempVizMode);
24986
+ }
24987
+ if (JSON.stringify(tempIdealRange) !== JSON.stringify(currentIdealRange)) {
24988
+ instance.setIdealRange(tempIdealRange);
24989
+ }
24990
+ if (tempPeriod !== currentPeriod) {
24991
+ await instance.setPeriod(tempPeriod);
24992
+ }
24993
+ });
24994
+ }
24995
+ const instance = {
24996
+ async render() {
24997
+ containerElement = document.getElementById(config.containerId);
24998
+ if (!containerElement) {
24999
+ console.error(`[ConsumptionWidget] Container #${config.containerId} not found`);
25000
+ return;
25001
+ }
25002
+ injectStyles();
25003
+ containerElement.innerHTML = renderHTML();
25004
+ setupListeners();
25005
+ setLoading(true);
25006
+ chartInstance = createConsumption7DaysChart({
25007
+ ...config,
25008
+ containerId: `${widgetId}-canvas`,
25009
+ theme: currentTheme,
25010
+ defaultChartType: currentChartType,
25011
+ defaultVizMode: currentVizMode,
25012
+ defaultPeriod: currentPeriod,
25013
+ idealRange: currentIdealRange,
25014
+ colors: {
25015
+ primary: primaryColor,
25016
+ background: `${primaryColor}20`,
25017
+ shoppingColors: domainColors,
25018
+ ...config.colors
25019
+ },
25020
+ onDataLoaded: (data) => {
25021
+ setLoading(false);
25022
+ updateFooterStats(data);
25023
+ config.onDataLoaded?.(data);
25024
+ },
25025
+ onError: (error) => {
25026
+ setLoading(false);
25027
+ config.onError?.(error);
25028
+ }
25029
+ });
25030
+ await chartInstance.render();
25031
+ setLoading(false);
25032
+ },
25033
+ async refresh(forceRefresh = false) {
25034
+ if (!chartInstance) return;
25035
+ setLoading(true);
25036
+ await chartInstance.refresh(forceRefresh);
25037
+ setLoading(false);
25038
+ },
25039
+ setChartType(type) {
25040
+ if (currentChartType === type) return;
25041
+ currentChartType = type;
25042
+ chartInstance?.setChartType(type);
25043
+ updateTabStates();
25044
+ },
25045
+ setVizMode(mode) {
25046
+ if (currentVizMode === mode) return;
25047
+ currentVizMode = mode;
25048
+ chartInstance?.setVizMode(mode);
25049
+ updateTabStates();
25050
+ },
25051
+ setTheme(theme) {
25052
+ if (currentTheme === theme) return;
25053
+ currentTheme = theme;
25054
+ chartInstance?.setTheme(theme);
25055
+ const widget = document.getElementById(widgetId);
25056
+ if (widget) {
25057
+ widget.classList.toggle("dark", theme === "dark");
25058
+ }
25059
+ updateStyles();
25060
+ },
25061
+ async setPeriod(days) {
25062
+ if (currentPeriod === days) return;
25063
+ currentPeriod = days;
25064
+ updateTitle();
25065
+ setLoading(true);
25066
+ await chartInstance?.setPeriod(days);
25067
+ setLoading(false);
25068
+ },
25069
+ setIdealRange(range) {
25070
+ currentIdealRange = range;
25071
+ chartInstance?.setIdealRange(range);
25072
+ },
25073
+ getChart() {
25074
+ return chartInstance;
25075
+ },
25076
+ // Alias for backwards compatibility with createConsumption7DaysChart API
25077
+ getChartInstance() {
25078
+ return chartInstance?.getChartInstance?.() ?? null;
25079
+ },
25080
+ getCachedData() {
25081
+ return chartInstance?.getCachedData() ?? null;
25082
+ },
25083
+ exportCSV(filename) {
25084
+ chartInstance?.exportCSV(filename);
25085
+ },
25086
+ destroy() {
25087
+ chartInstance?.destroy();
25088
+ chartInstance = null;
25089
+ if (styleElement) {
25090
+ styleElement.remove();
25091
+ styleElement = null;
25092
+ }
25093
+ settingsHeaderInstance?.destroy();
25094
+ settingsHeaderInstance = null;
25095
+ if (settingsModalElement) {
25096
+ settingsModalElement.remove();
25097
+ settingsModalElement = null;
25098
+ }
25099
+ if (containerElement) {
25100
+ containerElement.innerHTML = "";
25101
+ containerElement = null;
25102
+ }
25103
+ }
25104
+ };
25105
+ return instance;
25106
+ }
25107
+
23837
25108
  // src/components/ExportData/index.ts
23838
- var DEFAULT_COLORS3 = {
25109
+ var DEFAULT_COLORS4 = {
23839
25110
  primary: "#3e1a7d",
23840
25111
  // MyIO purple
23841
25112
  secondary: "#6b4c9a",
@@ -24163,9 +25434,9 @@ function buildTemplateExport(params) {
24163
25434
  footerText
24164
25435
  } = params;
24165
25436
  const colors = {
24166
- ...DEFAULT_COLORS3,
25437
+ ...DEFAULT_COLORS4,
24167
25438
  ...colorsPallet,
24168
- chartColors: colorsPallet?.chartColors || DEFAULT_COLORS3.chartColors
25439
+ chartColors: colorsPallet?.chartColors || DEFAULT_COLORS4.chartColors
24169
25440
  };
24170
25441
  return {
24171
25442
  domain,
@@ -24268,7 +25539,7 @@ function myioExportData(data, config, options) {
24268
25539
  }
24269
25540
  return instance;
24270
25541
  }
24271
- var EXPORT_DEFAULT_COLORS = DEFAULT_COLORS3;
25542
+ var EXPORT_DEFAULT_COLORS = DEFAULT_COLORS4;
24272
25543
  var EXPORT_DOMAIN_ICONS = DOMAIN_ICONS;
24273
25544
  var EXPORT_DOMAIN_LABELS = DOMAIN_LABELS;
24274
25545
  var EXPORT_DOMAIN_UNITS = DOMAIN_UNITS;
@@ -24310,6 +25581,7 @@ export {
24310
25581
  clearAllAuthCaches,
24311
25582
  connectionStatusIcons,
24312
25583
  createConsumption7DaysChart,
25584
+ createConsumptionChartWidget,
24313
25585
  createConsumptionModal,
24314
25586
  createDateRangePicker2 as createDateRangePicker,
24315
25587
  createInputDateRangePickerInsideDIV,