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.
@@ -1189,6 +1189,76 @@ const CombinedMarketTemplate = `
1189
1189
  </div>
1190
1190
  `;
1191
1191
 
1192
+ const IntradayChartTemplate = `
1193
+ <div class="intraday-chart-widget">
1194
+ <div class="chart-header">
1195
+ <div class="chart-title-section">
1196
+ <div class="company-market-info">
1197
+ <span class="intraday-company-name"></span>
1198
+ </div>
1199
+ <h3 class="intraday-chart-symbol editable-symbol"
1200
+ title="Double-click to edit symbol"
1201
+ data-original-symbol="">AAPL</h3>
1202
+ </div>
1203
+ <div class="chart-change positive">+0.00 (+0.00%)</div>
1204
+ </div>
1205
+
1206
+ <div class="chart-controls">
1207
+ <div class="chart-range-selector">
1208
+ <button class="range-btn active" data-range="0">1D</button>
1209
+ <button class="range-btn" data-range="5">5D</button>
1210
+ </div>
1211
+ <div class="chart-type-selector">
1212
+ <button class="type-btn active" data-type="line" title="Line Chart">Line</button>
1213
+ <button class="type-btn" data-type="area" title="Area Chart">Mountain</button>
1214
+ <button class="type-btn" data-type="candlestick" title="Candlestick Chart">Candles</button>
1215
+ </div>
1216
+ <button class="zoom-reset-btn" title="Reset Zoom">
1217
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
1218
+ <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"/>
1219
+ <path d="M5 8h6M8 5v6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
1220
+ </svg>
1221
+ Reset Zoom
1222
+ </button>
1223
+ </div>
1224
+
1225
+ <div class="chart-container">
1226
+ <canvas id="intradayChart"></canvas>
1227
+ </div>
1228
+
1229
+ <div class="chart-stats">
1230
+ <div class="stats-header">Daily Stats</div>
1231
+ <div class="stats-grid">
1232
+ <div class="stat-item stat-open">
1233
+ <span class="stat-label">Open</span>
1234
+ <span class="stat-value">$0.00</span>
1235
+ </div>
1236
+ <div class="stat-item stat-high">
1237
+ <span class="stat-label">High</span>
1238
+ <span class="stat-value">$0.00</span>
1239
+ </div>
1240
+ <div class="stat-item stat-low">
1241
+ <span class="stat-label">Low</span>
1242
+ <span class="stat-value">$0.00</span>
1243
+ </div>
1244
+ <div class="stat-item stat-close">
1245
+ <span class="stat-label">Close</span>
1246
+ <span class="stat-value">$0.00</span>
1247
+ </div>
1248
+ <div class="stat-item stat-volume">
1249
+ <span class="stat-label">Volume</span>
1250
+ <span class="stat-value">0</span>
1251
+ </div>
1252
+ </div>
1253
+ </div>
1254
+
1255
+ <div class="widget-loading-overlay hidden">
1256
+ <div class="loading-spinner"></div>
1257
+ <div class="loading-text">Loading chart data...</div>
1258
+ </div>
1259
+ </div>
1260
+ `;
1261
+
1192
1262
  // Widget HTML Templates
1193
1263
  const NightSessionTemplate = `
1194
1264
  <div class="night-session-widget widget">
@@ -7911,73 +7981,6 @@ class IntradayChartModel {
7911
7981
  }
7912
7982
  }
7913
7983
 
7914
- const IntradayChartTemplate = `
7915
- <div class="intraday-chart-widget">
7916
- <div class="chart-header">
7917
- <div class="chart-title-section">
7918
- <div class="company-market-info">
7919
- <span class="intraday-company-name"></span>
7920
- </div>
7921
- <h3 class="intraday-chart-symbol editable-symbol"
7922
- title="Double-click to edit symbol"
7923
- data-original-symbol="">AAPL</h3>
7924
- </div>
7925
- <div class="chart-change positive">+0.00 (+0.00%)</div>
7926
- </div>
7927
-
7928
- <div class="chart-controls">
7929
- <div class="chart-range-selector">
7930
- <button class="range-btn active" data-range="0">1D</button>
7931
- <button class="range-btn" data-range="5">5D</button>
7932
- </div>
7933
- <div class="chart-type-selector">
7934
- <button class="type-btn active" data-type="line" title="Line Chart">Line</button>
7935
- <button class="type-btn" data-type="area" title="Area Chart">Mountain</button>
7936
- <button class="type-btn" data-type="candlestick" title="Candlestick Chart">Candles</button>
7937
- </div>
7938
- <button class="zoom-reset-btn" title="Reset Zoom">
7939
- <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
7940
- <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"/>
7941
- <path d="M5 8h6M8 5v6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
7942
- </svg>
7943
- Reset Zoom
7944
- </button>
7945
- </div>
7946
-
7947
- <div class="chart-container">
7948
- <canvas id="intradayChart"></canvas>
7949
- </div>
7950
-
7951
- <div class="chart-stats">
7952
- <div class="stat-item stat-open">
7953
- <span class="stat-label">Open</span>
7954
- <span class="stat-value">$0.00</span>
7955
- </div>
7956
- <div class="stat-item stat-high">
7957
- <span class="stat-label">High</span>
7958
- <span class="stat-value">$0.00</span>
7959
- </div>
7960
- <div class="stat-item stat-low">
7961
- <span class="stat-label">Low</span>
7962
- <span class="stat-value">$0.00</span>
7963
- </div>
7964
- <div class="stat-item stat-close">
7965
- <span class="stat-label">Close</span>
7966
- <span class="stat-value">$0.00</span>
7967
- </div>
7968
- <div class="stat-item stat-volume">
7969
- <span class="stat-label">Volume</span>
7970
- <span class="stat-value">0</span>
7971
- </div>
7972
- </div>
7973
-
7974
- <div class="widget-loading-overlay hidden">
7975
- <div class="loading-spinner"></div>
7976
- <div class="loading-text">Loading chart data...</div>
7977
- </div>
7978
- </div>
7979
- `;
7980
-
7981
7984
  const IntradayChartStyles = `
7982
7985
  .intraday-chart-widget {
7983
7986
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
@@ -8162,14 +8165,28 @@ const IntradayChartStyles = `
8162
8165
  }
8163
8166
 
8164
8167
  .chart-stats {
8165
- display: grid;
8166
- grid-template-columns: repeat(5, 1fr);
8167
- gap: 15px;
8168
8168
  padding: 15px;
8169
8169
  background: #f9fafb;
8170
8170
  border-radius: 8px;
8171
8171
  }
8172
8172
 
8173
+ .stats-header {
8174
+ font-size: 0.875em;
8175
+ font-weight: 700;
8176
+ color: #374151;
8177
+ text-transform: uppercase;
8178
+ letter-spacing: 0.5px;
8179
+ margin-bottom: 12px;
8180
+ padding-bottom: 8px;
8181
+ border-bottom: 2px solid #e5e7eb;
8182
+ }
8183
+
8184
+ .stats-grid {
8185
+ display: grid;
8186
+ grid-template-columns: repeat(5, 1fr);
8187
+ gap: 15px;
8188
+ }
8189
+
8173
8190
  .stat-item {
8174
8191
  display: flex;
8175
8192
  flex-direction: column;
@@ -8238,11 +8255,16 @@ const IntradayChartStyles = `
8238
8255
  padding: 15px;
8239
8256
  }
8240
8257
 
8241
- .chart-stats {
8258
+ .stats-grid {
8242
8259
  grid-template-columns: repeat(3, 1fr);
8243
8260
  gap: 10px;
8244
8261
  }
8245
8262
 
8263
+ .stats-header {
8264
+ font-size: 0.8em;
8265
+ margin-bottom: 10px;
8266
+ }
8267
+
8246
8268
  .chart-container {
8247
8269
  height: 350px;
8248
8270
  }
@@ -37493,7 +37515,8 @@ class IntradayChartWidget extends BaseWidget {
37493
37515
  // Symbol editor
37494
37516
  this.symbolEditor = null;
37495
37517
 
37496
- // Lazy loading cache for 5D data
37518
+ // Lazy loading cache for chart data
37519
+ this.cached1DData = null;
37497
37520
  this.cached5DData = null;
37498
37521
  this.is5DDataLoading = false;
37499
37522
  this.createWidgetStructure();
@@ -37597,7 +37620,8 @@ class IntradayChartWidget extends BaseWidget {
37597
37620
  this.chartData = null;
37598
37621
  this.livePrice = null;
37599
37622
 
37600
- // Clear cached 5D data for old symbol
37623
+ // Clear all cached data for old symbol
37624
+ this.cached1DData = null;
37601
37625
  this.cached5DData = null;
37602
37626
  this.is5DDataLoading = false;
37603
37627
 
@@ -37715,7 +37739,7 @@ class IntradayChartWidget extends BaseWidget {
37715
37739
  // Update chart type and re-render
37716
37740
  this.chartType = type;
37717
37741
  this.renderChart();
37718
- this.updateStats();
37742
+ // Stats are managed by WebSocket updates only
37719
37743
  });
37720
37744
  });
37721
37745
  }
@@ -37751,12 +37775,30 @@ class IntradayChartWidget extends BaseWidget {
37751
37775
  throw new Error('API service not available');
37752
37776
  }
37753
37777
 
37754
- // For 5D chart: Load data from multiple days (rangeback 0-5)
37778
+ // For 5D chart: Load data from multiple days (rangeback 0-6)
37755
37779
  if (this.rangeBack === 5) {
37756
37780
  await this.load5DayChartData(apiService);
37757
37781
  return;
37758
37782
  }
37759
37783
 
37784
+ // For 1D chart: Check if we have cached data first
37785
+ if (this.rangeBack === 0 && this.cached1DData) {
37786
+ if (this.debug) {
37787
+ console.log('[IntradayChartWidget] Using cached 1D data');
37788
+ }
37789
+
37790
+ // Use cached data
37791
+ this.chartData = this.cached1DData;
37792
+ this.renderChart();
37793
+ // Skip updateStats() - stats will be updated from WebSocket data only
37794
+ this.hideLoading();
37795
+
37796
+ // Restart auto-refresh and live price subscription
37797
+ await this.startAutoRefresh();
37798
+ this.subscribeToLivePrice();
37799
+ return;
37800
+ }
37801
+
37760
37802
  // FALLBACK LOGIC: Try to find most recent available data (for 1D)
37761
37803
  const MAX_LOOKBACK_DAYS = 7;
37762
37804
  let attemptRangeBack = this.rangeBack;
@@ -37832,8 +37874,16 @@ class IntradayChartWidget extends BaseWidget {
37832
37874
  console.error('[IntradayChartWidget] Model has no data points after processing');
37833
37875
  throw new Error(`No valid data points for ${this.symbol}`);
37834
37876
  }
37877
+
37878
+ // Cache 1D data for instant switching
37879
+ if (this.rangeBack === 0) {
37880
+ this.cached1DData = this.chartData;
37881
+ if (this.debug) {
37882
+ console.log('[IntradayChartWidget] Cached 1D data for instant switching');
37883
+ }
37884
+ }
37835
37885
  this.renderChart();
37836
- this.updateStats();
37886
+ // Skip updateStats() - stats will be updated from WebSocket data only
37837
37887
  this.hideLoading();
37838
37888
  if (this.debug) {
37839
37889
  console.log(`[IntradayChartWidget] Loaded ${dataArray.length} data points`);
@@ -37887,9 +37937,12 @@ class IntradayChartWidget extends BaseWidget {
37887
37937
  // Use cached data
37888
37938
  this.chartData = this.cached5DData;
37889
37939
  this.renderChart();
37890
- this.updateStats();
37940
+ // Skip updateStats() - stats will be updated from WebSocket data only
37891
37941
  this.hideLoading();
37892
37942
 
37943
+ // Subscribe to live price for stats updates (WebSocket only)
37944
+ this.subscribeToLivePrice();
37945
+
37893
37946
  // Don't auto-refresh for 5D chart
37894
37947
  this.stopAutoRefresh();
37895
37948
  return;
@@ -37907,12 +37960,15 @@ class IntradayChartWidget extends BaseWidget {
37907
37960
  // Cache the processed data
37908
37961
  this.cached5DData = this.chartData;
37909
37962
  this.renderChart();
37910
- this.updateStats();
37963
+ // Skip updateStats() - stats will be updated from WebSocket data only
37911
37964
  this.hideLoading();
37912
37965
  if (this.debug) {
37913
37966
  console.log(`[IntradayChartWidget] 5D chart loaded with ${this.chartData.dataPoints.length} data points`);
37914
37967
  }
37915
37968
 
37969
+ // Subscribe to live price for stats updates (WebSocket only)
37970
+ this.subscribeToLivePrice();
37971
+
37916
37972
  // Don't auto-refresh for 5D chart
37917
37973
  this.stopAutoRefresh();
37918
37974
  } catch (error) {
@@ -38113,6 +38169,64 @@ class IntradayChartWidget extends BaseWidget {
38113
38169
  } else {
38114
38170
  console.log('[IntradayChartWidget] Invalid price, not updating:', price);
38115
38171
  }
38172
+
38173
+ // Update chart stats with live WebSocket data for both 1D and 5D charts
38174
+ // This shows the current day's stats from live data
38175
+ this.updateStatsFromLiveData(priceData);
38176
+ }
38177
+ updateStatsFromLiveData(data) {
38178
+ if (!data) return;
38179
+
38180
+ // Extract stats from WebSocket data
38181
+ const stats = {
38182
+ high: data.HighPx !== undefined && data.HighPx !== null ? parseFloat(data.HighPx) : null,
38183
+ low: data.LowPx !== undefined && data.LowPx !== null ? parseFloat(data.LowPx) : null,
38184
+ open: data.OpenPx !== undefined && data.OpenPx !== null ? parseFloat(data.OpenPx) : null,
38185
+ close: data.LastPx !== undefined && data.LastPx !== null ? parseFloat(data.LastPx) : data.TradePx !== undefined && data.TradePx !== null ? parseFloat(data.TradePx) : null,
38186
+ volume: data.Volume !== undefined && data.Volume !== null ? parseInt(data.Volume) : null,
38187
+ change: data.Change !== undefined && data.Change !== null ? parseFloat(data.Change) : null,
38188
+ changePercent: data.ChangePercent !== undefined && data.ChangePercent !== null ? parseFloat(data.ChangePercent) * 100 : null
38189
+ };
38190
+ if (this.debug) {
38191
+ console.log('[IntradayChartWidget] Updating stats from live data:', stats);
38192
+ }
38193
+
38194
+ // Update stats display
38195
+ const highElement = this.container.querySelector('.stat-high .stat-value');
38196
+ const lowElement = this.container.querySelector('.stat-low .stat-value');
38197
+ const openElement = this.container.querySelector('.stat-open .stat-value');
38198
+ const closeElement = this.container.querySelector('.stat-close .stat-value');
38199
+ const volumeElement = this.container.querySelector('.stat-volume .stat-value');
38200
+ const changeElement = this.container.querySelector('.chart-change');
38201
+ if (highElement && stats.high !== null) {
38202
+ highElement.textContent = `$${stats.high.toFixed(2)}`;
38203
+ }
38204
+ if (lowElement && stats.low !== null) {
38205
+ lowElement.textContent = `$${stats.low.toFixed(2)}`;
38206
+ }
38207
+ if (openElement && stats.open !== null) {
38208
+ openElement.textContent = `$${stats.open.toFixed(2)}`;
38209
+ }
38210
+ if (closeElement && stats.close !== null) {
38211
+ closeElement.textContent = `$${stats.close.toFixed(2)}`;
38212
+ }
38213
+ if (volumeElement && stats.volume !== null) {
38214
+ volumeElement.textContent = this.formatVolume(stats.volume);
38215
+ }
38216
+ if (changeElement && stats.change !== null && stats.changePercent !== null) {
38217
+ const changeClass = stats.change >= 0 ? 'positive' : 'negative';
38218
+ changeElement.className = `chart-change ${changeClass}`;
38219
+ const sign = stats.change >= 0 ? '+' : '';
38220
+ changeElement.textContent = `${sign}${stats.change.toFixed(2)} (${sign}${stats.changePercent.toFixed(2)}%)`;
38221
+ }
38222
+ }
38223
+ formatVolume(volume) {
38224
+ if (volume >= 1000000) {
38225
+ return (volume / 1000000).toFixed(2) + 'M';
38226
+ } else if (volume >= 1000) {
38227
+ return (volume / 1000).toFixed(2) + 'K';
38228
+ }
38229
+ return volume.toString();
38116
38230
  }
38117
38231
  updateLivePriceLine() {
38118
38232
  if (!this.chartInstance || !this.livePrice) {
@@ -38271,7 +38385,8 @@ class IntradayChartWidget extends BaseWidget {
38271
38385
  if (response && Array.isArray(response)) {
38272
38386
  this.chartData = new IntradayChartModel(response);
38273
38387
  this.renderChart();
38274
- this.updateStats();
38388
+ // Stats are managed by WebSocket updates only
38389
+
38275
38390
  if (this.debug) {
38276
38391
  console.log(`[IntradayChartWidget] Auto-refresh complete - ${response.length} data points`);
38277
38392
  }
@@ -38723,6 +38838,13 @@ class IntradayChartWidget extends BaseWidget {
38723
38838
  });
38724
38839
  }
38725
38840
  }
38841
+
38842
+ /**
38843
+ * DEPRECATED: This method is no longer used. Stats are now exclusively
38844
+ * updated from WebSocket data via updateStatsFromLiveData() to ensure
38845
+ * consistency between 1D and 5D charts (both showing today's stats only).
38846
+ * Kept for reference only.
38847
+ */
38726
38848
  updateStats() {
38727
38849
  if (!this.chartData) return;
38728
38850
  const stats = this.chartData.getStats();