mdas-jsview-sdk 1.0.12-uat.0 → 1.0.14-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.esm.js +219 -85
- package/dist/mdas-sdk.esm.js.map +1 -1
- package/dist/mdas-sdk.js +219 -85
- package/dist/mdas-sdk.js.map +1 -1
- package/dist/mdas-sdk.min.js +2 -2
- package/dist/mdas-sdk.min.js.map +1 -1
- package/package.json +1 -1
package/dist/mdas-sdk.esm.js
CHANGED
|
@@ -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">
|
|
@@ -3967,9 +4037,11 @@ class NightSessionModel {
|
|
|
3967
4037
|
} else {
|
|
3968
4038
|
return 'BlueOcean 20 mins delayed';
|
|
3969
4039
|
}
|
|
3970
|
-
} else if (this.source.toLowerCase().includes('bruce') || this.source.toLowerCase().includes('blueocean')) {
|
|
4040
|
+
} else if (this.source.toLowerCase().includes('bruce') || this.source.toLowerCase().includes('blueocean') || this.source.toLowerCase().includes('onbbo')) {
|
|
3971
4041
|
if (this.source.toLowerCase() === 'bruce') {
|
|
3972
4042
|
return 'Bruce Real-time';
|
|
4043
|
+
} else if (this.source.toLowerCase() === 'onbbo') {
|
|
4044
|
+
return 'ONBBO Real-time';
|
|
3973
4045
|
} else {
|
|
3974
4046
|
return 'BlueOcean Real-time';
|
|
3975
4047
|
}
|
|
@@ -4005,8 +4077,8 @@ class NightSessionWidget extends BaseWidget {
|
|
|
4005
4077
|
if (!options.wsManager) {
|
|
4006
4078
|
throw new Error('WebSocketManager is required for NightSessionWidget');
|
|
4007
4079
|
}
|
|
4008
|
-
if (!options.source || options.source.toLowerCase() !== 'blueocean' && options.source.toLowerCase() !== 'bruce') {
|
|
4009
|
-
throw new Error('Source should be either "blueocean" or "
|
|
4080
|
+
if (!options.source || options.source.toLowerCase() !== 'blueocean' && options.source.toLowerCase() !== 'bruce' && options.source.toLowerCase() !== 'onbbo') {
|
|
4081
|
+
throw new Error('Source should be either "blueocean", "bruce", or "onbbo"');
|
|
4010
4082
|
}
|
|
4011
4083
|
this.type = 'nightsession ' + options.source;
|
|
4012
4084
|
|
|
@@ -4226,7 +4298,14 @@ class NightSessionWidget extends BaseWidget {
|
|
|
4226
4298
|
}
|
|
4227
4299
|
}
|
|
4228
4300
|
subscribeToData() {
|
|
4229
|
-
|
|
4301
|
+
let subscriptionType;
|
|
4302
|
+
if (this.source === 'bruce') {
|
|
4303
|
+
subscriptionType = 'querybrucel1';
|
|
4304
|
+
} else if (this.source === 'onbbo') {
|
|
4305
|
+
subscriptionType = 'queryonbbol1';
|
|
4306
|
+
} else {
|
|
4307
|
+
subscriptionType = 'queryblueoceanl1';
|
|
4308
|
+
}
|
|
4230
4309
|
|
|
4231
4310
|
// Subscribe with symbol for routing
|
|
4232
4311
|
this.unsubscribe = this.wsManager.subscribe(this.widgetId, [subscriptionType], this.handleMessage.bind(this), this.symbol // Pass symbol for routing
|
|
@@ -4340,9 +4419,12 @@ class NightSessionWidget extends BaseWidget {
|
|
|
4340
4419
|
}
|
|
4341
4420
|
}
|
|
4342
4421
|
// Handle wrapped format
|
|
4343
|
-
else if (message.type === 'queryblueoceanl1' || message.type === 'querybrucel1') {
|
|
4422
|
+
else if (message.type === 'queryblueoceanl1' || message.type === 'querybrucel1' || message.type === 'queryonbbol1') {
|
|
4344
4423
|
if (message['0']?.Symbol === this.symbol) {
|
|
4345
|
-
|
|
4424
|
+
// For onbbo source, skip MarketName check
|
|
4425
|
+
const isOnbbo = message.type === 'queryonbbol1';
|
|
4426
|
+
const shouldShowNoData = message['0'].NotFound === true || !isOnbbo && (!message['0'].MarketName || message['0'].MarketName !== 'BLUE');
|
|
4427
|
+
if (shouldShowNoData) {
|
|
4346
4428
|
// Only show no data state if we don't have cached data
|
|
4347
4429
|
if (!this.data) {
|
|
4348
4430
|
this.showNoDataState(message['0']);
|
|
@@ -7911,73 +7993,6 @@ class IntradayChartModel {
|
|
|
7911
7993
|
}
|
|
7912
7994
|
}
|
|
7913
7995
|
|
|
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
7996
|
const IntradayChartStyles = `
|
|
7982
7997
|
.intraday-chart-widget {
|
|
7983
7998
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
|
|
@@ -8162,14 +8177,28 @@ const IntradayChartStyles = `
|
|
|
8162
8177
|
}
|
|
8163
8178
|
|
|
8164
8179
|
.chart-stats {
|
|
8165
|
-
display: grid;
|
|
8166
|
-
grid-template-columns: repeat(5, 1fr);
|
|
8167
|
-
gap: 15px;
|
|
8168
8180
|
padding: 15px;
|
|
8169
8181
|
background: #f9fafb;
|
|
8170
8182
|
border-radius: 8px;
|
|
8171
8183
|
}
|
|
8172
8184
|
|
|
8185
|
+
.stats-header {
|
|
8186
|
+
font-size: 0.875em;
|
|
8187
|
+
font-weight: 700;
|
|
8188
|
+
color: #374151;
|
|
8189
|
+
text-transform: uppercase;
|
|
8190
|
+
letter-spacing: 0.5px;
|
|
8191
|
+
margin-bottom: 12px;
|
|
8192
|
+
padding-bottom: 8px;
|
|
8193
|
+
border-bottom: 2px solid #e5e7eb;
|
|
8194
|
+
}
|
|
8195
|
+
|
|
8196
|
+
.stats-grid {
|
|
8197
|
+
display: grid;
|
|
8198
|
+
grid-template-columns: repeat(5, 1fr);
|
|
8199
|
+
gap: 15px;
|
|
8200
|
+
}
|
|
8201
|
+
|
|
8173
8202
|
.stat-item {
|
|
8174
8203
|
display: flex;
|
|
8175
8204
|
flex-direction: column;
|
|
@@ -8238,11 +8267,16 @@ const IntradayChartStyles = `
|
|
|
8238
8267
|
padding: 15px;
|
|
8239
8268
|
}
|
|
8240
8269
|
|
|
8241
|
-
.
|
|
8270
|
+
.stats-grid {
|
|
8242
8271
|
grid-template-columns: repeat(3, 1fr);
|
|
8243
8272
|
gap: 10px;
|
|
8244
8273
|
}
|
|
8245
8274
|
|
|
8275
|
+
.stats-header {
|
|
8276
|
+
font-size: 0.8em;
|
|
8277
|
+
margin-bottom: 10px;
|
|
8278
|
+
}
|
|
8279
|
+
|
|
8246
8280
|
.chart-container {
|
|
8247
8281
|
height: 350px;
|
|
8248
8282
|
}
|
|
@@ -37493,7 +37527,8 @@ class IntradayChartWidget extends BaseWidget {
|
|
|
37493
37527
|
// Symbol editor
|
|
37494
37528
|
this.symbolEditor = null;
|
|
37495
37529
|
|
|
37496
|
-
// Lazy loading cache for
|
|
37530
|
+
// Lazy loading cache for chart data
|
|
37531
|
+
this.cached1DData = null;
|
|
37497
37532
|
this.cached5DData = null;
|
|
37498
37533
|
this.is5DDataLoading = false;
|
|
37499
37534
|
this.createWidgetStructure();
|
|
@@ -37597,7 +37632,8 @@ class IntradayChartWidget extends BaseWidget {
|
|
|
37597
37632
|
this.chartData = null;
|
|
37598
37633
|
this.livePrice = null;
|
|
37599
37634
|
|
|
37600
|
-
// Clear cached
|
|
37635
|
+
// Clear all cached data for old symbol
|
|
37636
|
+
this.cached1DData = null;
|
|
37601
37637
|
this.cached5DData = null;
|
|
37602
37638
|
this.is5DDataLoading = false;
|
|
37603
37639
|
|
|
@@ -37715,7 +37751,7 @@ class IntradayChartWidget extends BaseWidget {
|
|
|
37715
37751
|
// Update chart type and re-render
|
|
37716
37752
|
this.chartType = type;
|
|
37717
37753
|
this.renderChart();
|
|
37718
|
-
|
|
37754
|
+
// Stats are managed by WebSocket updates only
|
|
37719
37755
|
});
|
|
37720
37756
|
});
|
|
37721
37757
|
}
|
|
@@ -37751,12 +37787,30 @@ class IntradayChartWidget extends BaseWidget {
|
|
|
37751
37787
|
throw new Error('API service not available');
|
|
37752
37788
|
}
|
|
37753
37789
|
|
|
37754
|
-
// For 5D chart: Load data from multiple days (rangeback 0-
|
|
37790
|
+
// For 5D chart: Load data from multiple days (rangeback 0-6)
|
|
37755
37791
|
if (this.rangeBack === 5) {
|
|
37756
37792
|
await this.load5DayChartData(apiService);
|
|
37757
37793
|
return;
|
|
37758
37794
|
}
|
|
37759
37795
|
|
|
37796
|
+
// For 1D chart: Check if we have cached data first
|
|
37797
|
+
if (this.rangeBack === 0 && this.cached1DData) {
|
|
37798
|
+
if (this.debug) {
|
|
37799
|
+
console.log('[IntradayChartWidget] Using cached 1D data');
|
|
37800
|
+
}
|
|
37801
|
+
|
|
37802
|
+
// Use cached data
|
|
37803
|
+
this.chartData = this.cached1DData;
|
|
37804
|
+
this.renderChart();
|
|
37805
|
+
// Skip updateStats() - stats will be updated from WebSocket data only
|
|
37806
|
+
this.hideLoading();
|
|
37807
|
+
|
|
37808
|
+
// Restart auto-refresh and live price subscription
|
|
37809
|
+
await this.startAutoRefresh();
|
|
37810
|
+
this.subscribeToLivePrice();
|
|
37811
|
+
return;
|
|
37812
|
+
}
|
|
37813
|
+
|
|
37760
37814
|
// FALLBACK LOGIC: Try to find most recent available data (for 1D)
|
|
37761
37815
|
const MAX_LOOKBACK_DAYS = 7;
|
|
37762
37816
|
let attemptRangeBack = this.rangeBack;
|
|
@@ -37832,8 +37886,16 @@ class IntradayChartWidget extends BaseWidget {
|
|
|
37832
37886
|
console.error('[IntradayChartWidget] Model has no data points after processing');
|
|
37833
37887
|
throw new Error(`No valid data points for ${this.symbol}`);
|
|
37834
37888
|
}
|
|
37889
|
+
|
|
37890
|
+
// Cache 1D data for instant switching
|
|
37891
|
+
if (this.rangeBack === 0) {
|
|
37892
|
+
this.cached1DData = this.chartData;
|
|
37893
|
+
if (this.debug) {
|
|
37894
|
+
console.log('[IntradayChartWidget] Cached 1D data for instant switching');
|
|
37895
|
+
}
|
|
37896
|
+
}
|
|
37835
37897
|
this.renderChart();
|
|
37836
|
-
|
|
37898
|
+
// Skip updateStats() - stats will be updated from WebSocket data only
|
|
37837
37899
|
this.hideLoading();
|
|
37838
37900
|
if (this.debug) {
|
|
37839
37901
|
console.log(`[IntradayChartWidget] Loaded ${dataArray.length} data points`);
|
|
@@ -37887,9 +37949,12 @@ class IntradayChartWidget extends BaseWidget {
|
|
|
37887
37949
|
// Use cached data
|
|
37888
37950
|
this.chartData = this.cached5DData;
|
|
37889
37951
|
this.renderChart();
|
|
37890
|
-
|
|
37952
|
+
// Skip updateStats() - stats will be updated from WebSocket data only
|
|
37891
37953
|
this.hideLoading();
|
|
37892
37954
|
|
|
37955
|
+
// Subscribe to live price for stats updates (WebSocket only)
|
|
37956
|
+
this.subscribeToLivePrice();
|
|
37957
|
+
|
|
37893
37958
|
// Don't auto-refresh for 5D chart
|
|
37894
37959
|
this.stopAutoRefresh();
|
|
37895
37960
|
return;
|
|
@@ -37907,12 +37972,15 @@ class IntradayChartWidget extends BaseWidget {
|
|
|
37907
37972
|
// Cache the processed data
|
|
37908
37973
|
this.cached5DData = this.chartData;
|
|
37909
37974
|
this.renderChart();
|
|
37910
|
-
|
|
37975
|
+
// Skip updateStats() - stats will be updated from WebSocket data only
|
|
37911
37976
|
this.hideLoading();
|
|
37912
37977
|
if (this.debug) {
|
|
37913
37978
|
console.log(`[IntradayChartWidget] 5D chart loaded with ${this.chartData.dataPoints.length} data points`);
|
|
37914
37979
|
}
|
|
37915
37980
|
|
|
37981
|
+
// Subscribe to live price for stats updates (WebSocket only)
|
|
37982
|
+
this.subscribeToLivePrice();
|
|
37983
|
+
|
|
37916
37984
|
// Don't auto-refresh for 5D chart
|
|
37917
37985
|
this.stopAutoRefresh();
|
|
37918
37986
|
} catch (error) {
|
|
@@ -38113,6 +38181,64 @@ class IntradayChartWidget extends BaseWidget {
|
|
|
38113
38181
|
} else {
|
|
38114
38182
|
console.log('[IntradayChartWidget] Invalid price, not updating:', price);
|
|
38115
38183
|
}
|
|
38184
|
+
|
|
38185
|
+
// Update chart stats with live WebSocket data for both 1D and 5D charts
|
|
38186
|
+
// This shows the current day's stats from live data
|
|
38187
|
+
this.updateStatsFromLiveData(priceData);
|
|
38188
|
+
}
|
|
38189
|
+
updateStatsFromLiveData(data) {
|
|
38190
|
+
if (!data) return;
|
|
38191
|
+
|
|
38192
|
+
// Extract stats from WebSocket data
|
|
38193
|
+
const stats = {
|
|
38194
|
+
high: data.HighPx !== undefined && data.HighPx !== null ? parseFloat(data.HighPx) : null,
|
|
38195
|
+
low: data.LowPx !== undefined && data.LowPx !== null ? parseFloat(data.LowPx) : null,
|
|
38196
|
+
open: data.OpenPx !== undefined && data.OpenPx !== null ? parseFloat(data.OpenPx) : null,
|
|
38197
|
+
close: data.LastPx !== undefined && data.LastPx !== null ? parseFloat(data.LastPx) : data.TradePx !== undefined && data.TradePx !== null ? parseFloat(data.TradePx) : null,
|
|
38198
|
+
volume: data.Volume !== undefined && data.Volume !== null ? parseInt(data.Volume) : null,
|
|
38199
|
+
change: data.Change !== undefined && data.Change !== null ? parseFloat(data.Change) : null,
|
|
38200
|
+
changePercent: data.ChangePercent !== undefined && data.ChangePercent !== null ? parseFloat(data.ChangePercent) * 100 : null
|
|
38201
|
+
};
|
|
38202
|
+
if (this.debug) {
|
|
38203
|
+
console.log('[IntradayChartWidget] Updating stats from live data:', stats);
|
|
38204
|
+
}
|
|
38205
|
+
|
|
38206
|
+
// Update stats display
|
|
38207
|
+
const highElement = this.container.querySelector('.stat-high .stat-value');
|
|
38208
|
+
const lowElement = this.container.querySelector('.stat-low .stat-value');
|
|
38209
|
+
const openElement = this.container.querySelector('.stat-open .stat-value');
|
|
38210
|
+
const closeElement = this.container.querySelector('.stat-close .stat-value');
|
|
38211
|
+
const volumeElement = this.container.querySelector('.stat-volume .stat-value');
|
|
38212
|
+
const changeElement = this.container.querySelector('.chart-change');
|
|
38213
|
+
if (highElement && stats.high !== null) {
|
|
38214
|
+
highElement.textContent = `$${stats.high.toFixed(2)}`;
|
|
38215
|
+
}
|
|
38216
|
+
if (lowElement && stats.low !== null) {
|
|
38217
|
+
lowElement.textContent = `$${stats.low.toFixed(2)}`;
|
|
38218
|
+
}
|
|
38219
|
+
if (openElement && stats.open !== null) {
|
|
38220
|
+
openElement.textContent = `$${stats.open.toFixed(2)}`;
|
|
38221
|
+
}
|
|
38222
|
+
if (closeElement && stats.close !== null) {
|
|
38223
|
+
closeElement.textContent = `$${stats.close.toFixed(2)}`;
|
|
38224
|
+
}
|
|
38225
|
+
if (volumeElement && stats.volume !== null) {
|
|
38226
|
+
volumeElement.textContent = this.formatVolume(stats.volume);
|
|
38227
|
+
}
|
|
38228
|
+
if (changeElement && stats.change !== null && stats.changePercent !== null) {
|
|
38229
|
+
const changeClass = stats.change >= 0 ? 'positive' : 'negative';
|
|
38230
|
+
changeElement.className = `chart-change ${changeClass}`;
|
|
38231
|
+
const sign = stats.change >= 0 ? '+' : '';
|
|
38232
|
+
changeElement.textContent = `${sign}${stats.change.toFixed(2)} (${sign}${stats.changePercent.toFixed(2)}%)`;
|
|
38233
|
+
}
|
|
38234
|
+
}
|
|
38235
|
+
formatVolume(volume) {
|
|
38236
|
+
if (volume >= 1000000) {
|
|
38237
|
+
return (volume / 1000000).toFixed(2) + 'M';
|
|
38238
|
+
} else if (volume >= 1000) {
|
|
38239
|
+
return (volume / 1000).toFixed(2) + 'K';
|
|
38240
|
+
}
|
|
38241
|
+
return volume.toString();
|
|
38116
38242
|
}
|
|
38117
38243
|
updateLivePriceLine() {
|
|
38118
38244
|
if (!this.chartInstance || !this.livePrice) {
|
|
@@ -38271,7 +38397,8 @@ class IntradayChartWidget extends BaseWidget {
|
|
|
38271
38397
|
if (response && Array.isArray(response)) {
|
|
38272
38398
|
this.chartData = new IntradayChartModel(response);
|
|
38273
38399
|
this.renderChart();
|
|
38274
|
-
|
|
38400
|
+
// Stats are managed by WebSocket updates only
|
|
38401
|
+
|
|
38275
38402
|
if (this.debug) {
|
|
38276
38403
|
console.log(`[IntradayChartWidget] Auto-refresh complete - ${response.length} data points`);
|
|
38277
38404
|
}
|
|
@@ -38723,6 +38850,13 @@ class IntradayChartWidget extends BaseWidget {
|
|
|
38723
38850
|
});
|
|
38724
38851
|
}
|
|
38725
38852
|
}
|
|
38853
|
+
|
|
38854
|
+
/**
|
|
38855
|
+
* DEPRECATED: This method is no longer used. Stats are now exclusively
|
|
38856
|
+
* updated from WebSocket data via updateStatsFromLiveData() to ensure
|
|
38857
|
+
* consistency between 1D and 5D charts (both showing today's stats only).
|
|
38858
|
+
* Kept for reference only.
|
|
38859
|
+
*/
|
|
38726
38860
|
updateStats() {
|
|
38727
38861
|
if (!this.chartData) return;
|
|
38728
38862
|
const stats = this.chartData.getStats();
|