mdas-jsview-sdk 1.0.10-uat.0 → 1.0.11-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.
@@ -38189,16 +38189,28 @@ class IntradayChartWidget extends BaseWidget {
38189
38189
 
38190
38190
  if (this.chartType === 'candlestick') {
38191
38191
  // Prepare OHLC data for candlestick chart
38192
- chartDataPoints = validDataPoints.map(point => ({
38193
- x: this.parseTimestamp(point.time).getTime(),
38194
- o: point.open,
38195
- h: point.high,
38196
- l: point.low,
38197
- c: point.close
38198
- })).filter(point => {
38199
- // Filter out invalid timestamps
38200
- return !isNaN(point.x) && point.x > 0;
38201
- });
38192
+ if (this.rangeBack > 0) {
38193
+ // For multi-day charts, use index as x-value (linear scale)
38194
+ chartDataPoints = validDataPoints.map((point, index) => ({
38195
+ x: index,
38196
+ o: point.open,
38197
+ h: point.high,
38198
+ l: point.low,
38199
+ c: point.close
38200
+ }));
38201
+ } else {
38202
+ // For single-day charts, use timestamps (time scale)
38203
+ chartDataPoints = validDataPoints.map(point => ({
38204
+ x: this.parseTimestamp(point.time).getTime(),
38205
+ o: point.open,
38206
+ h: point.high,
38207
+ l: point.low,
38208
+ c: point.close
38209
+ })).filter(point => {
38210
+ // Filter out invalid timestamps
38211
+ return !isNaN(point.x) && point.x > 0;
38212
+ });
38213
+ }
38202
38214
  if (chartDataPoints.length === 0) {
38203
38215
  console.error('[IntradayChartWidget] No valid candlestick data points after date parsing');
38204
38216
  this.showError('Unable to parse chart data timestamps');
@@ -38220,14 +38232,23 @@ class IntradayChartWidget extends BaseWidget {
38220
38232
  };
38221
38233
  } else {
38222
38234
  // Prepare data with timestamps for line/area chart
38223
- chartDataPoints = validDataPoints.map(point => ({
38224
- x: this.parseTimestamp(point.time),
38225
- y: point.close
38226
- })).filter(point => {
38227
- // Filter out invalid dates
38228
- const timestamp = point.x.getTime();
38229
- return !isNaN(timestamp) && timestamp > 0;
38230
- });
38235
+ if (this.rangeBack > 0) {
38236
+ // For multi-day charts, use index as x-value (linear scale)
38237
+ chartDataPoints = validDataPoints.map((point, index) => ({
38238
+ x: index,
38239
+ y: point.close
38240
+ }));
38241
+ } else {
38242
+ // For single-day charts, use timestamps (time scale)
38243
+ chartDataPoints = validDataPoints.map(point => ({
38244
+ x: this.parseTimestamp(point.time),
38245
+ y: point.close
38246
+ })).filter(point => {
38247
+ // Filter out invalid dates
38248
+ const timestamp = point.x.getTime();
38249
+ return !isNaN(timestamp) && timestamp > 0;
38250
+ });
38251
+ }
38231
38252
  if (chartDataPoints.length === 0) {
38232
38253
  console.error('[IntradayChartWidget] No valid chart data points after date parsing');
38233
38254
  this.showError('Unable to parse chart data timestamps');
@@ -38262,16 +38283,23 @@ class IntradayChartWidget extends BaseWidget {
38262
38283
  console.log('[IntradayChartWidget] Last data point - Source time:', validDataPoints[validDataPoints.length - 1].time);
38263
38284
  console.log('[IntradayChartWidget] Last chart point:', chartDataPoints[chartDataPoints.length - 1]);
38264
38285
 
38265
- // Calculate explicit min/max for x-axis to prevent Chart.js from auto-calculating incorrectly
38266
- const timestamps = chartDataPoints.map(p => this.chartType === 'candlestick' ? p.x : p.x.getTime());
38267
- const minTimestamp = Math.min(...timestamps);
38268
- const maxTimestamp = Math.max(...timestamps);
38269
- console.log('[IntradayChartWidget] X-axis bounds:', {
38270
- min: minTimestamp,
38271
- max: maxTimestamp,
38272
- minDate: new Date(minTimestamp),
38273
- maxDate: new Date(maxTimestamp)
38274
- });
38286
+ // Calculate explicit min/max for x-axis (only for time scale, not linear)
38287
+ let minTimestamp, maxTimestamp;
38288
+ if (this.rangeBack === 0) {
38289
+ // For time scale, calculate timestamp bounds
38290
+ const timestamps = chartDataPoints.map(p => this.chartType === 'candlestick' ? p.x : p.x.getTime());
38291
+ minTimestamp = Math.min(...timestamps);
38292
+ maxTimestamp = Math.max(...timestamps);
38293
+ console.log('[IntradayChartWidget] X-axis bounds:', {
38294
+ min: minTimestamp,
38295
+ max: maxTimestamp,
38296
+ minDate: new Date(minTimestamp),
38297
+ maxDate: new Date(maxTimestamp)
38298
+ });
38299
+ } else {
38300
+ // For linear scale, bounds are just indices
38301
+ console.log('[IntradayChartWidget] Using linear scale with', chartDataPoints.length, 'data points');
38302
+ }
38275
38303
  const config = {
38276
38304
  type: this.chartType === 'candlestick' ? 'candlestick' : 'line',
38277
38305
  data: {
@@ -38309,10 +38337,9 @@ class IntradayChartWidget extends BaseWidget {
38309
38337
  const index = context[0].dataIndex;
38310
38338
  const point = validDataPoints[index];
38311
38339
  if (point) {
38312
- // Format timestamp for tooltip
38340
+ // Display timestamp as-is from the data, without timezone conversion
38313
38341
  const date = new Date(point.time);
38314
38342
  return date.toLocaleString('en-US', {
38315
- timeZone: 'America/New_York',
38316
38343
  month: '2-digit',
38317
38344
  day: '2-digit',
38318
38345
  year: 'numeric',
@@ -38363,62 +38390,60 @@ class IntradayChartWidget extends BaseWidget {
38363
38390
  }
38364
38391
  },
38365
38392
  annotation: {
38366
- annotations: {
38367
- livePriceLine: {
38368
- type: 'line',
38369
- scaleID: 'y',
38370
- value: this.livePrice || stats.close,
38371
- borderColor: '#667eea',
38372
- borderWidth: 2,
38373
- borderDash: [5, 5],
38374
- label: {
38375
- display: true,
38376
- content: this.livePrice ? `$${this.livePrice.toFixed(2)}` : `$${stats.close.toFixed(2)}`,
38377
- enabled: true,
38378
- position: 'end',
38379
- backgroundColor: 'rgb(102, 126, 234)',
38380
- color: '#ffffff',
38381
- font: {
38382
- size: 12,
38383
- weight: 'bold',
38384
- family: 'system-ui, -apple-system, sans-serif'
38385
- },
38386
- padding: {
38387
- top: 4,
38388
- bottom: 4,
38389
- left: 8,
38390
- right: 8
38391
- },
38392
- borderRadius: 4,
38393
- xAdjust: -10,
38394
- yAdjust: 0
38395
- }
38396
- }
38397
- }
38393
+ annotations: this.createAnnotations(validDataPoints, stats)
38398
38394
  }
38399
38395
  },
38400
38396
  scales: {
38401
38397
  x: {
38402
- type: 'time',
38403
- min: minTimestamp,
38404
- max: maxTimestamp,
38405
- time: {
38406
- unit: this.rangeBack === 0 ? 'minute' : 'hour',
38398
+ type: this.rangeBack === 0 ? 'time' : 'linear',
38399
+ min: this.rangeBack === 0 ? minTimestamp : undefined,
38400
+ max: this.rangeBack === 0 ? maxTimestamp : undefined,
38401
+ time: this.rangeBack === 0 ? {
38402
+ unit: 'hour',
38403
+ stepSize: 1,
38407
38404
  displayFormats: {
38408
- minute: 'h:mm a',
38409
- hour: 'MMM d, ha'
38405
+ hour: 'h:mm a'
38410
38406
  },
38411
38407
  tooltipFormat: 'MMM d, h:mm a'
38412
- },
38408
+ } : undefined,
38413
38409
  grid: {
38414
38410
  display: false
38415
38411
  },
38416
38412
  ticks: {
38417
- maxTicksLimit: 10,
38413
+ maxTicksLimit: this.rangeBack === 0 ? 10 : 8,
38418
38414
  color: '#6b7280',
38419
38415
  autoSkip: true,
38420
38416
  maxRotation: 0,
38421
- minRotation: 0
38417
+ minRotation: 0,
38418
+ callback: (value, index) => {
38419
+ if (this.rangeBack > 0) {
38420
+ // For multi-day charts with linear scale, show actual time from data point
38421
+ const point = validDataPoints[index];
38422
+ if (point) {
38423
+ const date = new Date(point.time);
38424
+ return date.toLocaleString('en-US', {
38425
+ month: 'short',
38426
+ day: 'numeric',
38427
+ hour: 'numeric',
38428
+ minute: '2-digit',
38429
+ hour12: true
38430
+ });
38431
+ }
38432
+ return '';
38433
+ }
38434
+ // For single-day time scale, provide fallback formatting
38435
+ // If value is a number (timestamp), format it
38436
+ if (typeof value === 'number') {
38437
+ const date = new Date(value);
38438
+ return date.toLocaleString('en-US', {
38439
+ hour: 'numeric',
38440
+ minute: '2-digit',
38441
+ hour12: true
38442
+ });
38443
+ }
38444
+ // Otherwise let Chart.js handle it (if date adapter is working)
38445
+ return value;
38446
+ }
38422
38447
  }
38423
38448
  },
38424
38449
  y: {
@@ -38464,6 +38489,63 @@ class IntradayChartWidget extends BaseWidget {
38464
38489
  // Add reset zoom button listener
38465
38490
  this.setupZoomReset();
38466
38491
  }
38492
+ createAnnotations(dataPoints, stats) {
38493
+ const annotations = {
38494
+ livePriceLine: {
38495
+ type: 'line',
38496
+ scaleID: 'y',
38497
+ value: this.livePrice || stats.close,
38498
+ borderColor: '#667eea',
38499
+ borderWidth: 2,
38500
+ borderDash: [5, 5],
38501
+ label: {
38502
+ display: true,
38503
+ content: this.livePrice ? `$${this.livePrice.toFixed(2)}` : `$${stats.close.toFixed(2)}`,
38504
+ enabled: true,
38505
+ position: 'end',
38506
+ backgroundColor: 'rgb(102, 126, 234)',
38507
+ color: '#ffffff',
38508
+ font: {
38509
+ size: 12,
38510
+ weight: 'bold',
38511
+ family: 'system-ui, -apple-system, sans-serif'
38512
+ },
38513
+ padding: {
38514
+ top: 4,
38515
+ bottom: 4,
38516
+ left: 8,
38517
+ right: 8
38518
+ },
38519
+ borderRadius: 4,
38520
+ xAdjust: -10,
38521
+ yAdjust: 0
38522
+ }
38523
+ }
38524
+ };
38525
+
38526
+ // Add day separators for multi-day charts (5D, etc.)
38527
+ if (this.rangeBack > 0 && dataPoints.length > 0) {
38528
+ let currentDay = null;
38529
+ dataPoints.forEach((point, index) => {
38530
+ const pointDate = new Date(point.time);
38531
+ const day = pointDate.toDateString();
38532
+
38533
+ // Add vertical line at the start of each new day
38534
+ if (currentDay !== day && currentDay !== null) {
38535
+ annotations[`daySeparator${index}`] = {
38536
+ type: 'line',
38537
+ scaleID: 'x',
38538
+ value: index,
38539
+ borderColor: 'rgba(0, 0, 0, 0.1)',
38540
+ borderWidth: 1,
38541
+ borderDash: [3, 3]
38542
+ };
38543
+ }
38544
+ currentDay = day;
38545
+ });
38546
+ }
38547
+ return annotations;
38548
+ }
38467
38549
  setupZoomReset() {
38468
38550
  const resetBtn = this.container.querySelector('.zoom-reset-btn');
38469
38551
  if (resetBtn) {