mdas-jsview-sdk 1.0.9-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.
package/dist/mdas-sdk.js CHANGED
@@ -1772,7 +1772,7 @@
1772
1772
  .widget {
1773
1773
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
1774
1774
  width: 100%;
1775
- max-width: 800px;
1775
+ max-width: 1400px;
1776
1776
  }
1777
1777
 
1778
1778
  /* HEADER STYLES */
@@ -2626,7 +2626,7 @@
2626
2626
  .options-widget {
2627
2627
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
2628
2628
  color: #333;
2629
- max-width: 800px;
2629
+ max-width: 1400px;
2630
2630
  width: 100%;
2631
2631
  margin: 0 auto;
2632
2632
  position: relative;
@@ -37726,11 +37726,26 @@ ${SharedStyles}
37726
37726
  });
37727
37727
  }
37728
37728
  addStyles() {
37729
+ // Skip style injection if external styles are detected or explicitly disabled
37730
+ if (this.options.skipStyleInjection || document.querySelector('link[href*="mdas-styles.css"]')) {
37731
+ if (this.debug) {
37732
+ console.log('[IntradayChartWidget] Skipping style injection - external styles detected');
37733
+ }
37734
+ return;
37735
+ }
37729
37736
  if (!document.querySelector('#intraday-chart-styles')) {
37730
- const styleSheet = document.createElement('style');
37731
- styleSheet.id = 'intraday-chart-styles';
37732
- styleSheet.textContent = IntradayChartStyles;
37733
- document.head.appendChild(styleSheet);
37737
+ try {
37738
+ const styleSheet = document.createElement('style');
37739
+ styleSheet.id = 'intraday-chart-styles';
37740
+ styleSheet.textContent = IntradayChartStyles;
37741
+ document.head.appendChild(styleSheet);
37742
+ if (this.debug) {
37743
+ console.log('[IntradayChartWidget] Styles injected successfully');
37744
+ }
37745
+ } catch (error) {
37746
+ console.warn('[IntradayChartWidget] Failed to inject styles:', error);
37747
+ console.warn('[IntradayChartWidget] Please add <link rel="stylesheet" href="mdas-styles.css"> to your HTML');
37748
+ }
37734
37749
  }
37735
37750
  }
37736
37751
  async loadChartData() {
@@ -38180,16 +38195,28 @@ ${SharedStyles}
38180
38195
 
38181
38196
  if (this.chartType === 'candlestick') {
38182
38197
  // Prepare OHLC data for candlestick chart
38183
- chartDataPoints = validDataPoints.map(point => ({
38184
- x: this.parseTimestamp(point.time).getTime(),
38185
- o: point.open,
38186
- h: point.high,
38187
- l: point.low,
38188
- c: point.close
38189
- })).filter(point => {
38190
- // Filter out invalid timestamps
38191
- return !isNaN(point.x) && point.x > 0;
38192
- });
38198
+ if (this.rangeBack > 0) {
38199
+ // For multi-day charts, use index as x-value (linear scale)
38200
+ chartDataPoints = validDataPoints.map((point, index) => ({
38201
+ x: index,
38202
+ o: point.open,
38203
+ h: point.high,
38204
+ l: point.low,
38205
+ c: point.close
38206
+ }));
38207
+ } else {
38208
+ // For single-day charts, use timestamps (time scale)
38209
+ chartDataPoints = validDataPoints.map(point => ({
38210
+ x: this.parseTimestamp(point.time).getTime(),
38211
+ o: point.open,
38212
+ h: point.high,
38213
+ l: point.low,
38214
+ c: point.close
38215
+ })).filter(point => {
38216
+ // Filter out invalid timestamps
38217
+ return !isNaN(point.x) && point.x > 0;
38218
+ });
38219
+ }
38193
38220
  if (chartDataPoints.length === 0) {
38194
38221
  console.error('[IntradayChartWidget] No valid candlestick data points after date parsing');
38195
38222
  this.showError('Unable to parse chart data timestamps');
@@ -38211,14 +38238,23 @@ ${SharedStyles}
38211
38238
  };
38212
38239
  } else {
38213
38240
  // Prepare data with timestamps for line/area chart
38214
- chartDataPoints = validDataPoints.map(point => ({
38215
- x: this.parseTimestamp(point.time),
38216
- y: point.close
38217
- })).filter(point => {
38218
- // Filter out invalid dates
38219
- const timestamp = point.x.getTime();
38220
- return !isNaN(timestamp) && timestamp > 0;
38221
- });
38241
+ if (this.rangeBack > 0) {
38242
+ // For multi-day charts, use index as x-value (linear scale)
38243
+ chartDataPoints = validDataPoints.map((point, index) => ({
38244
+ x: index,
38245
+ y: point.close
38246
+ }));
38247
+ } else {
38248
+ // For single-day charts, use timestamps (time scale)
38249
+ chartDataPoints = validDataPoints.map(point => ({
38250
+ x: this.parseTimestamp(point.time),
38251
+ y: point.close
38252
+ })).filter(point => {
38253
+ // Filter out invalid dates
38254
+ const timestamp = point.x.getTime();
38255
+ return !isNaN(timestamp) && timestamp > 0;
38256
+ });
38257
+ }
38222
38258
  if (chartDataPoints.length === 0) {
38223
38259
  console.error('[IntradayChartWidget] No valid chart data points after date parsing');
38224
38260
  this.showError('Unable to parse chart data timestamps');
@@ -38253,16 +38289,23 @@ ${SharedStyles}
38253
38289
  console.log('[IntradayChartWidget] Last data point - Source time:', validDataPoints[validDataPoints.length - 1].time);
38254
38290
  console.log('[IntradayChartWidget] Last chart point:', chartDataPoints[chartDataPoints.length - 1]);
38255
38291
 
38256
- // Calculate explicit min/max for x-axis to prevent Chart.js from auto-calculating incorrectly
38257
- const timestamps = chartDataPoints.map(p => this.chartType === 'candlestick' ? p.x : p.x.getTime());
38258
- const minTimestamp = Math.min(...timestamps);
38259
- const maxTimestamp = Math.max(...timestamps);
38260
- console.log('[IntradayChartWidget] X-axis bounds:', {
38261
- min: minTimestamp,
38262
- max: maxTimestamp,
38263
- minDate: new Date(minTimestamp),
38264
- maxDate: new Date(maxTimestamp)
38265
- });
38292
+ // Calculate explicit min/max for x-axis (only for time scale, not linear)
38293
+ let minTimestamp, maxTimestamp;
38294
+ if (this.rangeBack === 0) {
38295
+ // For time scale, calculate timestamp bounds
38296
+ const timestamps = chartDataPoints.map(p => this.chartType === 'candlestick' ? p.x : p.x.getTime());
38297
+ minTimestamp = Math.min(...timestamps);
38298
+ maxTimestamp = Math.max(...timestamps);
38299
+ console.log('[IntradayChartWidget] X-axis bounds:', {
38300
+ min: minTimestamp,
38301
+ max: maxTimestamp,
38302
+ minDate: new Date(minTimestamp),
38303
+ maxDate: new Date(maxTimestamp)
38304
+ });
38305
+ } else {
38306
+ // For linear scale, bounds are just indices
38307
+ console.log('[IntradayChartWidget] Using linear scale with', chartDataPoints.length, 'data points');
38308
+ }
38266
38309
  const config = {
38267
38310
  type: this.chartType === 'candlestick' ? 'candlestick' : 'line',
38268
38311
  data: {
@@ -38300,10 +38343,9 @@ ${SharedStyles}
38300
38343
  const index = context[0].dataIndex;
38301
38344
  const point = validDataPoints[index];
38302
38345
  if (point) {
38303
- // Format timestamp for tooltip
38346
+ // Display timestamp as-is from the data, without timezone conversion
38304
38347
  const date = new Date(point.time);
38305
38348
  return date.toLocaleString('en-US', {
38306
- timeZone: 'America/New_York',
38307
38349
  month: '2-digit',
38308
38350
  day: '2-digit',
38309
38351
  year: 'numeric',
@@ -38354,62 +38396,60 @@ ${SharedStyles}
38354
38396
  }
38355
38397
  },
38356
38398
  annotation: {
38357
- annotations: {
38358
- livePriceLine: {
38359
- type: 'line',
38360
- scaleID: 'y',
38361
- value: this.livePrice || stats.close,
38362
- borderColor: '#667eea',
38363
- borderWidth: 2,
38364
- borderDash: [5, 5],
38365
- label: {
38366
- display: true,
38367
- content: this.livePrice ? `$${this.livePrice.toFixed(2)}` : `$${stats.close.toFixed(2)}`,
38368
- enabled: true,
38369
- position: 'end',
38370
- backgroundColor: 'rgb(102, 126, 234)',
38371
- color: '#ffffff',
38372
- font: {
38373
- size: 12,
38374
- weight: 'bold',
38375
- family: 'system-ui, -apple-system, sans-serif'
38376
- },
38377
- padding: {
38378
- top: 4,
38379
- bottom: 4,
38380
- left: 8,
38381
- right: 8
38382
- },
38383
- borderRadius: 4,
38384
- xAdjust: -10,
38385
- yAdjust: 0
38386
- }
38387
- }
38388
- }
38399
+ annotations: this.createAnnotations(validDataPoints, stats)
38389
38400
  }
38390
38401
  },
38391
38402
  scales: {
38392
38403
  x: {
38393
- type: 'time',
38394
- min: minTimestamp,
38395
- max: maxTimestamp,
38396
- time: {
38397
- unit: this.rangeBack === 0 ? 'minute' : 'hour',
38404
+ type: this.rangeBack === 0 ? 'time' : 'linear',
38405
+ min: this.rangeBack === 0 ? minTimestamp : undefined,
38406
+ max: this.rangeBack === 0 ? maxTimestamp : undefined,
38407
+ time: this.rangeBack === 0 ? {
38408
+ unit: 'hour',
38409
+ stepSize: 1,
38398
38410
  displayFormats: {
38399
- minute: 'h:mm a',
38400
- hour: 'MMM d, ha'
38411
+ hour: 'h:mm a'
38401
38412
  },
38402
38413
  tooltipFormat: 'MMM d, h:mm a'
38403
- },
38414
+ } : undefined,
38404
38415
  grid: {
38405
38416
  display: false
38406
38417
  },
38407
38418
  ticks: {
38408
- maxTicksLimit: 10,
38419
+ maxTicksLimit: this.rangeBack === 0 ? 10 : 8,
38409
38420
  color: '#6b7280',
38410
38421
  autoSkip: true,
38411
38422
  maxRotation: 0,
38412
- minRotation: 0
38423
+ minRotation: 0,
38424
+ callback: (value, index) => {
38425
+ if (this.rangeBack > 0) {
38426
+ // For multi-day charts with linear scale, show actual time from data point
38427
+ const point = validDataPoints[index];
38428
+ if (point) {
38429
+ const date = new Date(point.time);
38430
+ return date.toLocaleString('en-US', {
38431
+ month: 'short',
38432
+ day: 'numeric',
38433
+ hour: 'numeric',
38434
+ minute: '2-digit',
38435
+ hour12: true
38436
+ });
38437
+ }
38438
+ return '';
38439
+ }
38440
+ // For single-day time scale, provide fallback formatting
38441
+ // If value is a number (timestamp), format it
38442
+ if (typeof value === 'number') {
38443
+ const date = new Date(value);
38444
+ return date.toLocaleString('en-US', {
38445
+ hour: 'numeric',
38446
+ minute: '2-digit',
38447
+ hour12: true
38448
+ });
38449
+ }
38450
+ // Otherwise let Chart.js handle it (if date adapter is working)
38451
+ return value;
38452
+ }
38413
38453
  }
38414
38454
  },
38415
38455
  y: {
@@ -38455,6 +38495,63 @@ ${SharedStyles}
38455
38495
  // Add reset zoom button listener
38456
38496
  this.setupZoomReset();
38457
38497
  }
38498
+ createAnnotations(dataPoints, stats) {
38499
+ const annotations = {
38500
+ livePriceLine: {
38501
+ type: 'line',
38502
+ scaleID: 'y',
38503
+ value: this.livePrice || stats.close,
38504
+ borderColor: '#667eea',
38505
+ borderWidth: 2,
38506
+ borderDash: [5, 5],
38507
+ label: {
38508
+ display: true,
38509
+ content: this.livePrice ? `$${this.livePrice.toFixed(2)}` : `$${stats.close.toFixed(2)}`,
38510
+ enabled: true,
38511
+ position: 'end',
38512
+ backgroundColor: 'rgb(102, 126, 234)',
38513
+ color: '#ffffff',
38514
+ font: {
38515
+ size: 12,
38516
+ weight: 'bold',
38517
+ family: 'system-ui, -apple-system, sans-serif'
38518
+ },
38519
+ padding: {
38520
+ top: 4,
38521
+ bottom: 4,
38522
+ left: 8,
38523
+ right: 8
38524
+ },
38525
+ borderRadius: 4,
38526
+ xAdjust: -10,
38527
+ yAdjust: 0
38528
+ }
38529
+ }
38530
+ };
38531
+
38532
+ // Add day separators for multi-day charts (5D, etc.)
38533
+ if (this.rangeBack > 0 && dataPoints.length > 0) {
38534
+ let currentDay = null;
38535
+ dataPoints.forEach((point, index) => {
38536
+ const pointDate = new Date(point.time);
38537
+ const day = pointDate.toDateString();
38538
+
38539
+ // Add vertical line at the start of each new day
38540
+ if (currentDay !== day && currentDay !== null) {
38541
+ annotations[`daySeparator${index}`] = {
38542
+ type: 'line',
38543
+ scaleID: 'x',
38544
+ value: index,
38545
+ borderColor: 'rgba(0, 0, 0, 0.1)',
38546
+ borderWidth: 1,
38547
+ borderDash: [3, 3]
38548
+ };
38549
+ }
38550
+ currentDay = day;
38551
+ });
38552
+ }
38553
+ return annotations;
38554
+ }
38458
38555
  setupZoomReset() {
38459
38556
  const resetBtn = this.container.querySelector('.zoom-reset-btn');
38460
38557
  if (resetBtn) {