mdas-jsview-sdk 1.0.12-uat.0 → 1.0.13-uat.0

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/mdas-sdk.js CHANGED
@@ -1195,6 +1195,76 @@
1195
1195
  </div>
1196
1196
  `;
1197
1197
 
1198
+ const IntradayChartTemplate = `
1199
+ <div class="intraday-chart-widget">
1200
+ <div class="chart-header">
1201
+ <div class="chart-title-section">
1202
+ <div class="company-market-info">
1203
+ <span class="intraday-company-name"></span>
1204
+ </div>
1205
+ <h3 class="intraday-chart-symbol editable-symbol"
1206
+ title="Double-click to edit symbol"
1207
+ data-original-symbol="">AAPL</h3>
1208
+ </div>
1209
+ <div class="chart-change positive">+0.00 (+0.00%)</div>
1210
+ </div>
1211
+
1212
+ <div class="chart-controls">
1213
+ <div class="chart-range-selector">
1214
+ <button class="range-btn active" data-range="0">1D</button>
1215
+ <button class="range-btn" data-range="5">5D</button>
1216
+ </div>
1217
+ <div class="chart-type-selector">
1218
+ <button class="type-btn active" data-type="line" title="Line Chart">Line</button>
1219
+ <button class="type-btn" data-type="area" title="Area Chart">Mountain</button>
1220
+ <button class="type-btn" data-type="candlestick" title="Candlestick Chart">Candles</button>
1221
+ </div>
1222
+ <button class="zoom-reset-btn" title="Reset Zoom">
1223
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
1224
+ <path d="M2 8a6 6 0 1 1 12 0A6 6 0 0 1 2 8zm6-7a7 7 0 1 0 0 14A7 7 0 0 0 8 1z" fill="currentColor"/>
1225
+ <path d="M5 8h6M8 5v6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
1226
+ </svg>
1227
+ Reset Zoom
1228
+ </button>
1229
+ </div>
1230
+
1231
+ <div class="chart-container">
1232
+ <canvas id="intradayChart"></canvas>
1233
+ </div>
1234
+
1235
+ <div class="chart-stats">
1236
+ <div class="stats-header">Daily Stats</div>
1237
+ <div class="stats-grid">
1238
+ <div class="stat-item stat-open">
1239
+ <span class="stat-label">Open</span>
1240
+ <span class="stat-value">$0.00</span>
1241
+ </div>
1242
+ <div class="stat-item stat-high">
1243
+ <span class="stat-label">High</span>
1244
+ <span class="stat-value">$0.00</span>
1245
+ </div>
1246
+ <div class="stat-item stat-low">
1247
+ <span class="stat-label">Low</span>
1248
+ <span class="stat-value">$0.00</span>
1249
+ </div>
1250
+ <div class="stat-item stat-close">
1251
+ <span class="stat-label">Close</span>
1252
+ <span class="stat-value">$0.00</span>
1253
+ </div>
1254
+ <div class="stat-item stat-volume">
1255
+ <span class="stat-label">Volume</span>
1256
+ <span class="stat-value">0</span>
1257
+ </div>
1258
+ </div>
1259
+ </div>
1260
+
1261
+ <div class="widget-loading-overlay hidden">
1262
+ <div class="loading-spinner"></div>
1263
+ <div class="loading-text">Loading chart data...</div>
1264
+ </div>
1265
+ </div>
1266
+ `;
1267
+
1198
1268
  // Widget HTML Templates
1199
1269
  const NightSessionTemplate = `
1200
1270
  <div class="night-session-widget widget">
@@ -7917,73 +7987,6 @@ ${SharedStyles}
7917
7987
  }
7918
7988
  }
7919
7989
 
7920
- const IntradayChartTemplate = `
7921
- <div class="intraday-chart-widget">
7922
- <div class="chart-header">
7923
- <div class="chart-title-section">
7924
- <div class="company-market-info">
7925
- <span class="intraday-company-name"></span>
7926
- </div>
7927
- <h3 class="intraday-chart-symbol editable-symbol"
7928
- title="Double-click to edit symbol"
7929
- data-original-symbol="">AAPL</h3>
7930
- </div>
7931
- <div class="chart-change positive">+0.00 (+0.00%)</div>
7932
- </div>
7933
-
7934
- <div class="chart-controls">
7935
- <div class="chart-range-selector">
7936
- <button class="range-btn active" data-range="0">1D</button>
7937
- <button class="range-btn" data-range="5">5D</button>
7938
- </div>
7939
- <div class="chart-type-selector">
7940
- <button class="type-btn active" data-type="line" title="Line Chart">Line</button>
7941
- <button class="type-btn" data-type="area" title="Area Chart">Mountain</button>
7942
- <button class="type-btn" data-type="candlestick" title="Candlestick Chart">Candles</button>
7943
- </div>
7944
- <button class="zoom-reset-btn" title="Reset Zoom">
7945
- <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
7946
- <path d="M2 8a6 6 0 1 1 12 0A6 6 0 0 1 2 8zm6-7a7 7 0 1 0 0 14A7 7 0 0 0 8 1z" fill="currentColor"/>
7947
- <path d="M5 8h6M8 5v6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
7948
- </svg>
7949
- Reset Zoom
7950
- </button>
7951
- </div>
7952
-
7953
- <div class="chart-container">
7954
- <canvas id="intradayChart"></canvas>
7955
- </div>
7956
-
7957
- <div class="chart-stats">
7958
- <div class="stat-item stat-open">
7959
- <span class="stat-label">Open</span>
7960
- <span class="stat-value">$0.00</span>
7961
- </div>
7962
- <div class="stat-item stat-high">
7963
- <span class="stat-label">High</span>
7964
- <span class="stat-value">$0.00</span>
7965
- </div>
7966
- <div class="stat-item stat-low">
7967
- <span class="stat-label">Low</span>
7968
- <span class="stat-value">$0.00</span>
7969
- </div>
7970
- <div class="stat-item stat-close">
7971
- <span class="stat-label">Close</span>
7972
- <span class="stat-value">$0.00</span>
7973
- </div>
7974
- <div class="stat-item stat-volume">
7975
- <span class="stat-label">Volume</span>
7976
- <span class="stat-value">0</span>
7977
- </div>
7978
- </div>
7979
-
7980
- <div class="widget-loading-overlay hidden">
7981
- <div class="loading-spinner"></div>
7982
- <div class="loading-text">Loading chart data...</div>
7983
- </div>
7984
- </div>
7985
- `;
7986
-
7987
7990
  const IntradayChartStyles = `
7988
7991
  .intraday-chart-widget {
7989
7992
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
@@ -8168,14 +8171,28 @@ ${SharedStyles}
8168
8171
  }
8169
8172
 
8170
8173
  .chart-stats {
8171
- display: grid;
8172
- grid-template-columns: repeat(5, 1fr);
8173
- gap: 15px;
8174
8174
  padding: 15px;
8175
8175
  background: #f9fafb;
8176
8176
  border-radius: 8px;
8177
8177
  }
8178
8178
 
8179
+ .stats-header {
8180
+ font-size: 0.875em;
8181
+ font-weight: 700;
8182
+ color: #374151;
8183
+ text-transform: uppercase;
8184
+ letter-spacing: 0.5px;
8185
+ margin-bottom: 12px;
8186
+ padding-bottom: 8px;
8187
+ border-bottom: 2px solid #e5e7eb;
8188
+ }
8189
+
8190
+ .stats-grid {
8191
+ display: grid;
8192
+ grid-template-columns: repeat(5, 1fr);
8193
+ gap: 15px;
8194
+ }
8195
+
8179
8196
  .stat-item {
8180
8197
  display: flex;
8181
8198
  flex-direction: column;
@@ -8244,11 +8261,16 @@ ${SharedStyles}
8244
8261
  padding: 15px;
8245
8262
  }
8246
8263
 
8247
- .chart-stats {
8264
+ .stats-grid {
8248
8265
  grid-template-columns: repeat(3, 1fr);
8249
8266
  gap: 10px;
8250
8267
  }
8251
8268
 
8269
+ .stats-header {
8270
+ font-size: 0.8em;
8271
+ margin-bottom: 10px;
8272
+ }
8273
+
8252
8274
  .chart-container {
8253
8275
  height: 350px;
8254
8276
  }
@@ -37499,7 +37521,8 @@ ${SharedStyles}
37499
37521
  // Symbol editor
37500
37522
  this.symbolEditor = null;
37501
37523
 
37502
- // Lazy loading cache for 5D data
37524
+ // Lazy loading cache for chart data
37525
+ this.cached1DData = null;
37503
37526
  this.cached5DData = null;
37504
37527
  this.is5DDataLoading = false;
37505
37528
  this.createWidgetStructure();
@@ -37603,7 +37626,8 @@ ${SharedStyles}
37603
37626
  this.chartData = null;
37604
37627
  this.livePrice = null;
37605
37628
 
37606
- // Clear cached 5D data for old symbol
37629
+ // Clear all cached data for old symbol
37630
+ this.cached1DData = null;
37607
37631
  this.cached5DData = null;
37608
37632
  this.is5DDataLoading = false;
37609
37633
 
@@ -37721,7 +37745,7 @@ ${SharedStyles}
37721
37745
  // Update chart type and re-render
37722
37746
  this.chartType = type;
37723
37747
  this.renderChart();
37724
- this.updateStats();
37748
+ // Stats are managed by WebSocket updates only
37725
37749
  });
37726
37750
  });
37727
37751
  }
@@ -37757,12 +37781,30 @@ ${SharedStyles}
37757
37781
  throw new Error('API service not available');
37758
37782
  }
37759
37783
 
37760
- // For 5D chart: Load data from multiple days (rangeback 0-5)
37784
+ // For 5D chart: Load data from multiple days (rangeback 0-6)
37761
37785
  if (this.rangeBack === 5) {
37762
37786
  await this.load5DayChartData(apiService);
37763
37787
  return;
37764
37788
  }
37765
37789
 
37790
+ // For 1D chart: Check if we have cached data first
37791
+ if (this.rangeBack === 0 && this.cached1DData) {
37792
+ if (this.debug) {
37793
+ console.log('[IntradayChartWidget] Using cached 1D data');
37794
+ }
37795
+
37796
+ // Use cached data
37797
+ this.chartData = this.cached1DData;
37798
+ this.renderChart();
37799
+ // Skip updateStats() - stats will be updated from WebSocket data only
37800
+ this.hideLoading();
37801
+
37802
+ // Restart auto-refresh and live price subscription
37803
+ await this.startAutoRefresh();
37804
+ this.subscribeToLivePrice();
37805
+ return;
37806
+ }
37807
+
37766
37808
  // FALLBACK LOGIC: Try to find most recent available data (for 1D)
37767
37809
  const MAX_LOOKBACK_DAYS = 7;
37768
37810
  let attemptRangeBack = this.rangeBack;
@@ -37838,8 +37880,16 @@ ${SharedStyles}
37838
37880
  console.error('[IntradayChartWidget] Model has no data points after processing');
37839
37881
  throw new Error(`No valid data points for ${this.symbol}`);
37840
37882
  }
37883
+
37884
+ // Cache 1D data for instant switching
37885
+ if (this.rangeBack === 0) {
37886
+ this.cached1DData = this.chartData;
37887
+ if (this.debug) {
37888
+ console.log('[IntradayChartWidget] Cached 1D data for instant switching');
37889
+ }
37890
+ }
37841
37891
  this.renderChart();
37842
- this.updateStats();
37892
+ // Skip updateStats() - stats will be updated from WebSocket data only
37843
37893
  this.hideLoading();
37844
37894
  if (this.debug) {
37845
37895
  console.log(`[IntradayChartWidget] Loaded ${dataArray.length} data points`);
@@ -37893,9 +37943,12 @@ ${SharedStyles}
37893
37943
  // Use cached data
37894
37944
  this.chartData = this.cached5DData;
37895
37945
  this.renderChart();
37896
- this.updateStats();
37946
+ // Skip updateStats() - stats will be updated from WebSocket data only
37897
37947
  this.hideLoading();
37898
37948
 
37949
+ // Subscribe to live price for stats updates (WebSocket only)
37950
+ this.subscribeToLivePrice();
37951
+
37899
37952
  // Don't auto-refresh for 5D chart
37900
37953
  this.stopAutoRefresh();
37901
37954
  return;
@@ -37913,12 +37966,15 @@ ${SharedStyles}
37913
37966
  // Cache the processed data
37914
37967
  this.cached5DData = this.chartData;
37915
37968
  this.renderChart();
37916
- this.updateStats();
37969
+ // Skip updateStats() - stats will be updated from WebSocket data only
37917
37970
  this.hideLoading();
37918
37971
  if (this.debug) {
37919
37972
  console.log(`[IntradayChartWidget] 5D chart loaded with ${this.chartData.dataPoints.length} data points`);
37920
37973
  }
37921
37974
 
37975
+ // Subscribe to live price for stats updates (WebSocket only)
37976
+ this.subscribeToLivePrice();
37977
+
37922
37978
  // Don't auto-refresh for 5D chart
37923
37979
  this.stopAutoRefresh();
37924
37980
  } catch (error) {
@@ -38119,6 +38175,64 @@ ${SharedStyles}
38119
38175
  } else {
38120
38176
  console.log('[IntradayChartWidget] Invalid price, not updating:', price);
38121
38177
  }
38178
+
38179
+ // Update chart stats with live WebSocket data for both 1D and 5D charts
38180
+ // This shows the current day's stats from live data
38181
+ this.updateStatsFromLiveData(priceData);
38182
+ }
38183
+ updateStatsFromLiveData(data) {
38184
+ if (!data) return;
38185
+
38186
+ // Extract stats from WebSocket data
38187
+ const stats = {
38188
+ high: data.HighPx !== undefined && data.HighPx !== null ? parseFloat(data.HighPx) : null,
38189
+ low: data.LowPx !== undefined && data.LowPx !== null ? parseFloat(data.LowPx) : null,
38190
+ open: data.OpenPx !== undefined && data.OpenPx !== null ? parseFloat(data.OpenPx) : null,
38191
+ close: data.LastPx !== undefined && data.LastPx !== null ? parseFloat(data.LastPx) : data.TradePx !== undefined && data.TradePx !== null ? parseFloat(data.TradePx) : null,
38192
+ volume: data.Volume !== undefined && data.Volume !== null ? parseInt(data.Volume) : null,
38193
+ change: data.Change !== undefined && data.Change !== null ? parseFloat(data.Change) : null,
38194
+ changePercent: data.ChangePercent !== undefined && data.ChangePercent !== null ? parseFloat(data.ChangePercent) * 100 : null
38195
+ };
38196
+ if (this.debug) {
38197
+ console.log('[IntradayChartWidget] Updating stats from live data:', stats);
38198
+ }
38199
+
38200
+ // Update stats display
38201
+ const highElement = this.container.querySelector('.stat-high .stat-value');
38202
+ const lowElement = this.container.querySelector('.stat-low .stat-value');
38203
+ const openElement = this.container.querySelector('.stat-open .stat-value');
38204
+ const closeElement = this.container.querySelector('.stat-close .stat-value');
38205
+ const volumeElement = this.container.querySelector('.stat-volume .stat-value');
38206
+ const changeElement = this.container.querySelector('.chart-change');
38207
+ if (highElement && stats.high !== null) {
38208
+ highElement.textContent = `$${stats.high.toFixed(2)}`;
38209
+ }
38210
+ if (lowElement && stats.low !== null) {
38211
+ lowElement.textContent = `$${stats.low.toFixed(2)}`;
38212
+ }
38213
+ if (openElement && stats.open !== null) {
38214
+ openElement.textContent = `$${stats.open.toFixed(2)}`;
38215
+ }
38216
+ if (closeElement && stats.close !== null) {
38217
+ closeElement.textContent = `$${stats.close.toFixed(2)}`;
38218
+ }
38219
+ if (volumeElement && stats.volume !== null) {
38220
+ volumeElement.textContent = this.formatVolume(stats.volume);
38221
+ }
38222
+ if (changeElement && stats.change !== null && stats.changePercent !== null) {
38223
+ const changeClass = stats.change >= 0 ? 'positive' : 'negative';
38224
+ changeElement.className = `chart-change ${changeClass}`;
38225
+ const sign = stats.change >= 0 ? '+' : '';
38226
+ changeElement.textContent = `${sign}${stats.change.toFixed(2)} (${sign}${stats.changePercent.toFixed(2)}%)`;
38227
+ }
38228
+ }
38229
+ formatVolume(volume) {
38230
+ if (volume >= 1000000) {
38231
+ return (volume / 1000000).toFixed(2) + 'M';
38232
+ } else if (volume >= 1000) {
38233
+ return (volume / 1000).toFixed(2) + 'K';
38234
+ }
38235
+ return volume.toString();
38122
38236
  }
38123
38237
  updateLivePriceLine() {
38124
38238
  if (!this.chartInstance || !this.livePrice) {
@@ -38277,7 +38391,8 @@ ${SharedStyles}
38277
38391
  if (response && Array.isArray(response)) {
38278
38392
  this.chartData = new IntradayChartModel(response);
38279
38393
  this.renderChart();
38280
- this.updateStats();
38394
+ // Stats are managed by WebSocket updates only
38395
+
38281
38396
  if (this.debug) {
38282
38397
  console.log(`[IntradayChartWidget] Auto-refresh complete - ${response.length} data points`);
38283
38398
  }
@@ -38729,6 +38844,13 @@ ${SharedStyles}
38729
38844
  });
38730
38845
  }
38731
38846
  }
38847
+
38848
+ /**
38849
+ * DEPRECATED: This method is no longer used. Stats are now exclusively
38850
+ * updated from WebSocket data via updateStatsFromLiveData() to ensure
38851
+ * consistency between 1D and 5D charts (both showing today's stats only).
38852
+ * Kept for reference only.
38853
+ */
38732
38854
  updateStats() {
38733
38855
  if (!this.chartData) return;
38734
38856
  const stats = this.chartData.getStats();