@design.estate/dees-catalog 3.98.0 → 3.98.1

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.
@@ -161072,6 +161072,72 @@ var renderChartArea = /* @__PURE__ */ __name((component) => {
161072
161072
  `;
161073
161073
  }, "renderChartArea");
161074
161074
 
161075
+ // ts_web/elements/00group-chart/dees-chart-area/realtime-updates.ts
161076
+ var planRealtimeChartUpdates = /* @__PURE__ */ __name((renderedData, canonicalData) => {
161077
+ if (canonicalData.length === 0) {
161078
+ return {
161079
+ replacementRequired: renderedData.length !== 0,
161080
+ updates: [],
161081
+ pruneRecommended: false,
161082
+ pruneRequired: false
161083
+ };
161084
+ }
161085
+ if (renderedData.length === 0) {
161086
+ return {
161087
+ replacementRequired: false,
161088
+ updates: canonicalData.map((point4) => ({ point: point4, historicalUpdate: false })),
161089
+ pruneRecommended: false,
161090
+ pruneRequired: false
161091
+ };
161092
+ }
161093
+ const renderedByTime = new Map(renderedData.map((point4) => [point4.time, point4]));
161094
+ const canonicalByTime = new Map(canonicalData.map((point4) => [point4.time, point4]));
161095
+ const canonicalStart = canonicalData[0].time;
161096
+ const renderedLastTime = renderedData[renderedData.length - 1].time;
161097
+ const hasStructuralDeletion = renderedData.some(
161098
+ (point4) => point4.time >= canonicalStart && !canonicalByTime.has(point4.time)
161099
+ );
161100
+ if (hasStructuralDeletion) {
161101
+ return {
161102
+ replacementRequired: true,
161103
+ updates: [],
161104
+ pruneRecommended: false,
161105
+ pruneRequired: false
161106
+ };
161107
+ }
161108
+ const updates = [];
161109
+ for (const canonicalPoint of canonicalData) {
161110
+ const renderedPoint = renderedByTime.get(canonicalPoint.time);
161111
+ if (!renderedPoint) {
161112
+ if (canonicalPoint.time < renderedLastTime) {
161113
+ return {
161114
+ replacementRequired: true,
161115
+ updates: [],
161116
+ pruneRecommended: false,
161117
+ pruneRequired: false
161118
+ };
161119
+ }
161120
+ updates.push({ point: canonicalPoint, historicalUpdate: false });
161121
+ continue;
161122
+ }
161123
+ if (renderedPoint.value !== canonicalPoint.value) {
161124
+ updates.push({
161125
+ point: canonicalPoint,
161126
+ historicalUpdate: canonicalPoint.time < renderedLastTime
161127
+ });
161128
+ }
161129
+ }
161130
+ const firstCanonicalPointIndex = renderedData.findIndex((point4) => point4.time >= canonicalStart);
161131
+ const retainedPrefixLength = firstCanonicalPointIndex === -1 ? renderedData.length : firstCanonicalPointIndex;
161132
+ const projectedLength = renderedData.length + updates.filter((update) => !renderedByTime.has(update.point.time)).length;
161133
+ const retentionLimit = Math.max(canonicalData.length * 2, 2);
161134
+ const pruneRecommended = retainedPrefixLength > 0 && projectedLength > retentionLimit;
161135
+ const hardRetentionLimit = Math.max(canonicalData.length * 3, 3);
161136
+ const pruneRequired = retainedPrefixLength > 0 && projectedLength > hardRetentionLimit;
161137
+ return { replacementRequired: false, updates, pruneRecommended, pruneRequired };
161138
+ }, "planRealtimeChartUpdates");
161139
+ var haveSameSeriesLayout = /* @__PURE__ */ __name((renderedNames, canonicalNames) => renderedNames.length === canonicalNames.length && renderedNames.every((name, index3) => name === canonicalNames[index3]), "haveSameSeriesLayout");
161140
+
161075
161141
  // ts_web/elements/00group-chart/dees-chart-echarts-theme.ts
161076
161142
  init_theme();
161077
161143
  init_fonts();
@@ -161183,19 +161249,41 @@ var _DeesChartArea = class _DeesChartArea extends (_a56 = DeesElement, _chart_de
161183
161249
  __publicField(this, "seriesApis", /* @__PURE__ */ new Map());
161184
161250
  __publicField(this, "priceLines", /* @__PURE__ */ new Map());
161185
161251
  __publicField(this, "tooltipEl", null);
161252
+ __publicField(this, "crosshairActive", false);
161253
+ __publicField(this, "pendingRealtimePrune", false);
161254
+ __publicField(this, "crosshairMoveHandler", null);
161255
+ __publicField(this, "chartContainer", null);
161256
+ __publicField(this, "chartMouseLeaveHandler", /* @__PURE__ */ __name(() => {
161257
+ this.chart?.clearCrosshairPosition();
161258
+ this.handleCrosshairCleared();
161259
+ }, "chartMouseLeaveHandler"));
161186
161260
  domtools_elementbasic_exports.setup();
161187
161261
  this.registerGarbageFunction(async () => {
161188
161262
  this.stopAutoScroll();
161189
- if (this.chart) {
161263
+ const chart = this.chart;
161264
+ const crosshairMoveHandler = this.crosshairMoveHandler;
161265
+ this.chart = null;
161266
+ this.crosshairMoveHandler = null;
161267
+ this.chartContainer?.removeEventListener("mouseleave", this.chartMouseLeaveHandler);
161268
+ this.chartContainer = null;
161269
+ this.tooltipEl = null;
161270
+ this.crosshairActive = false;
161271
+ this.pendingRealtimePrune = false;
161272
+ if (crosshairMoveHandler && chart) {
161190
161273
  try {
161191
- this.chart.remove();
161192
- this.chart = null;
161193
- this.seriesApis.clear();
161194
- this.priceLines.clear();
161195
- } catch (e10) {
161196
- console.error("Error destroying chart:", e10);
161274
+ chart.unsubscribeCrosshairMove(crosshairMoveHandler);
161275
+ } catch (error) {
161276
+ console.error("Error unsubscribing chart crosshair:", error);
161197
161277
  }
161198
161278
  }
161279
+ try {
161280
+ chart?.remove();
161281
+ } catch (error) {
161282
+ console.error("Error destroying chart:", error);
161283
+ } finally {
161284
+ this.seriesApis.clear();
161285
+ this.priceLines.clear();
161286
+ }
161199
161287
  });
161200
161288
  }
161201
161289
  get chartSeries() {
@@ -161206,10 +161294,37 @@ var _DeesChartArea = class _DeesChartArea extends (_a56 = DeesElement, _chart_de
161206
161294
  }
161207
161295
  // --- Helpers ---
161208
161296
  convertDataToLC(data) {
161209
- return data.map((point4) => {
161297
+ const pointsByTime = /* @__PURE__ */ new Map();
161298
+ for (const point4 of data) {
161210
161299
  const ms = typeof point4.x === "number" ? point4.x : new Date(point4.x).getTime();
161211
- return { time: Math.floor(ms / 1e3), value: point4.y };
161212
- }).sort((a4, b4) => a4.time - b4.time);
161300
+ const time = Math.floor(ms / 1e3);
161301
+ if (!Number.isFinite(time) || !Number.isFinite(point4.y)) continue;
161302
+ pointsByTime.set(time, { time, value: point4.y });
161303
+ }
161304
+ return [...pointsByTime.values()].sort((a4, b4) => a4.time - b4.time);
161305
+ }
161306
+ getSeriesName(series, index3) {
161307
+ return series.name || `series-${index3}`;
161308
+ }
161309
+ getSeriesKey(series, index3) {
161310
+ return `${index3}:${this.getSeriesName(series, index3)}`;
161311
+ }
161312
+ getCanonicalChartSeries(chartSeries) {
161313
+ const cutoffTime = Date.now() - this.rollingWindow;
161314
+ return chartSeries.map((series) => ({
161315
+ ...series,
161316
+ data: this.convertDataToLC(series.data.filter((point4) => {
161317
+ if (!this.realtimeMode || this.rollingWindow <= 0) return true;
161318
+ const ms = typeof point4.x === "number" ? point4.x : new Date(point4.x).getTime();
161319
+ return ms > cutoffTime;
161320
+ })).map((point4) => ({
161321
+ x: point4.time * 1e3,
161322
+ y: point4.value
161323
+ }))
161324
+ }));
161325
+ }
161326
+ getRenderedSeriesData(api) {
161327
+ return api.data().filter((point4) => "value" in point4).map((point4) => ({ time: point4.time, value: point4.value }));
161213
161328
  }
161214
161329
  colorToRgba(color2, alpha2) {
161215
161330
  if (/^#[0-9a-fA-F]{6}$/.test(color2)) {
@@ -161301,7 +161416,7 @@ var _DeesChartArea = class _DeesChartArea extends (_a56 = DeesElement, _chart_de
161301
161416
  crosshairMarkerRadius: 4
161302
161417
  });
161303
161418
  api.setData(this.convertDataToLC(s9.data));
161304
- this.updatePriceLines(s9.name || `series-${index3}`, api, s9.data, color2);
161419
+ this.updatePriceLines(this.getSeriesKey(s9, index3), api, s9.data, color2);
161305
161420
  if (this.yAxisScaling !== "dynamic") {
161306
161421
  api.applyOptions({
161307
161422
  autoscaleInfoProvider: /* @__PURE__ */ __name(() => ({
@@ -161309,13 +161424,63 @@ var _DeesChartArea = class _DeesChartArea extends (_a56 = DeesElement, _chart_de
161309
161424
  }), "autoscaleInfoProvider")
161310
161425
  });
161311
161426
  }
161312
- this.seriesApis.set(s9.name || `series-${index3}`, api);
161427
+ this.seriesApis.set(this.getSeriesKey(s9, index3), api);
161313
161428
  });
161314
161429
  this.computeStats(chartSeries);
161315
- if (this.rollingWindow <= 0) {
161430
+ this.pendingRealtimePrune = false;
161431
+ if (this.realtimeMode && this.rollingWindow > 0) {
161432
+ void this.updateTimeWindow();
161433
+ } else {
161316
161434
  this.chart.timeScale().fitContent();
161317
161435
  }
161318
161436
  }
161437
+ updateSeriesPresentation(chartSeries) {
161438
+ const isDark = !this.goBright;
161439
+ chartSeries.forEach((series, index3) => {
161440
+ const seriesKey = this.getSeriesKey(series, index3);
161441
+ const api = this.seriesApis.get(seriesKey);
161442
+ if (!api) return;
161443
+ const color2 = this.resolveSeriesColor(series, index3, isDark);
161444
+ api.applyOptions({
161445
+ topColor: this.colorToRgba(color2, isDark ? 0.4 : 0.5),
161446
+ bottomColor: this.colorToRgba(color2, 0),
161447
+ lineColor: color2
161448
+ });
161449
+ this.updatePriceLines(seriesKey, api, series.data, color2);
161450
+ });
161451
+ this.computeStats(chartSeries);
161452
+ if (this.yAxisScaling === "dynamic") {
161453
+ const allValues = chartSeries.flatMap((series) => series.data.map((point4) => point4.y));
161454
+ if (allValues.length > 0) {
161455
+ const dynamicMax = Math.ceil(Math.max(...allValues) * 1.1);
161456
+ for (const [, api] of this.seriesApis) {
161457
+ api.applyOptions({
161458
+ autoscaleInfoProvider: /* @__PURE__ */ __name(() => ({ priceRange: { minValue: 0, maxValue: dynamicMax } }), "autoscaleInfoProvider")
161459
+ });
161460
+ }
161461
+ }
161462
+ }
161463
+ }
161464
+ handleCrosshairCleared() {
161465
+ this.crosshairActive = false;
161466
+ if (this.tooltipEl) this.tooltipEl.style.display = "none";
161467
+ this.flushPendingRealtimePrune();
161468
+ }
161469
+ clearCrosshairForDataReplacement() {
161470
+ this.pendingRealtimePrune = false;
161471
+ this.chart?.clearCrosshairPosition();
161472
+ this.crosshairActive = false;
161473
+ if (this.tooltipEl) this.tooltipEl.style.display = "none";
161474
+ }
161475
+ flushPendingRealtimePrune() {
161476
+ if (!this.pendingRealtimePrune || this.crosshairActive || !this.chart || !this.realtimeMode || this.rollingWindow <= 0) return;
161477
+ const canonicalSeries = this.getCanonicalChartSeries(this.internalChartData);
161478
+ canonicalSeries.forEach((series, index3) => {
161479
+ const api = this.seriesApis.get(this.getSeriesKey(series, index3));
161480
+ if (api) api.setData(this.convertDataToLC(series.data));
161481
+ });
161482
+ this.pendingRealtimePrune = false;
161483
+ }
161319
161484
  computeStats(chartSeries) {
161320
161485
  const isDark = !this.goBright;
161321
161486
  this.seriesStats = chartSeries.map((s9, index3) => {
@@ -161375,13 +161540,16 @@ var _DeesChartArea = class _DeesChartArea extends (_a56 = DeesElement, _chart_de
161375
161540
  this.tooltipEl = document.createElement("div");
161376
161541
  this.tooltipEl.className = "lw-tooltip";
161377
161542
  this.tooltipEl.style.display = "none";
161378
- this.shadowRoot.querySelector(".chartContainer")?.appendChild(this.tooltipEl);
161379
- this.chart.subscribeCrosshairMove((param) => {
161543
+ this.chartContainer = this.shadowRoot.querySelector(".chartContainer");
161544
+ this.chartContainer?.appendChild(this.tooltipEl);
161545
+ this.chartContainer?.addEventListener("mouseleave", this.chartMouseLeaveHandler);
161546
+ this.crosshairMoveHandler = (param) => {
161380
161547
  if (!this.tooltipEl) return;
161381
- if (!param.point || !param.time || param.point.x < 0 || param.point.y < 0) {
161382
- this.tooltipEl.style.display = "none";
161548
+ if (!param.point || param.time === void 0 || param.point.x < 0 || param.point.y < 0) {
161549
+ this.handleCrosshairCleared();
161383
161550
  return;
161384
161551
  }
161552
+ this.crosshairActive = true;
161385
161553
  const isDark = !this.goBright;
161386
161554
  const bgColor = isDark ? "hsl(0 0% 9%)" : "hsl(0 0% 100%)";
161387
161555
  const textColor = isDark ? "hsl(0 0% 95%)" : "hsl(0 0% 9%)";
@@ -161389,11 +161557,13 @@ var _DeesChartArea = class _DeesChartArea extends (_a56 = DeesElement, _chart_de
161389
161557
  let html8 = "";
161390
161558
  let idx = 0;
161391
161559
  let hasData = false;
161392
- for (const [name, api] of this.seriesApis) {
161560
+ for (const api of this.seriesApis.values()) {
161393
161561
  const data = param.seriesData.get(api);
161394
161562
  if (data && "value" in data && data.value !== void 0) {
161395
161563
  hasData = true;
161396
- const color2 = this.resolveSeriesColor(this.chartSeries[idx], idx, isDark);
161564
+ const series = this.internalChartData[idx];
161565
+ const name = series ? this.getSeriesName(series, idx) : `series-${idx}`;
161566
+ const color2 = this.resolveSeriesColor(series, idx, isDark);
161397
161567
  const formatted = this.yAxisFormatter(data.value);
161398
161568
  html8 += `<div style="display:flex;align-items:center;gap:8px;margin:${idx > 0 ? "6px" : "0"} 0;">
161399
161569
  <span style="display:inline-block;width:10px;height:10px;background:${color2};border-radius:2px;"></span>
@@ -161419,13 +161589,17 @@ var _DeesChartArea = class _DeesChartArea extends (_a56 = DeesElement, _chart_de
161419
161589
  if (left + 200 > containerWidth) left = param.point.x - 216;
161420
161590
  this.tooltipEl.style.left = `${left}px`;
161421
161591
  this.tooltipEl.style.top = `${param.point.y - 16}px`;
161422
- });
161592
+ };
161593
+ this.chart.subscribeCrosshairMove(this.crosshairMoveHandler);
161423
161594
  }
161424
161595
  // --- Lifecycle ---
161425
161596
  async firstUpdated() {
161426
161597
  await this.domtoolsPromise;
161598
+ if (!this.isConnected) return;
161427
161599
  this.lcBundle = await DeesServiceLibLoader.getInstance().loadLightweightCharts();
161600
+ if (!this.isConnected) return;
161428
161601
  await new Promise((resolve2) => requestAnimationFrame(resolve2));
161602
+ if (!this.isConnected) return;
161429
161603
  const chartContainer = this.shadowRoot.querySelector(".chartContainer");
161430
161604
  if (!chartContainer) return;
161431
161605
  const isDark = !this.goBright;
@@ -161480,9 +161654,11 @@ var _DeesChartArea = class _DeesChartArea extends (_a56 = DeesElement, _chart_de
161480
161654
  ]
161481
161655
  }
161482
161656
  ];
161483
- this.internalChartData = chartSeries;
161484
- this.recreateSeries(chartSeries);
161657
+ const canonicalSeries = this.getCanonicalChartSeries(chartSeries);
161658
+ this.internalChartData = canonicalSeries;
161659
+ this.recreateSeries(canonicalSeries);
161485
161660
  this.setupTooltip();
161661
+ this.syncAutoScroll();
161486
161662
  } catch (error) {
161487
161663
  console.error("Failed to initialize chart:", error);
161488
161664
  }
@@ -161492,23 +161668,26 @@ var _DeesChartArea = class _DeesChartArea extends (_a56 = DeesElement, _chart_de
161492
161668
  if (changedProperties.has("goBright") && this.chart) {
161493
161669
  this.applyTheme();
161494
161670
  }
161495
- if (changedProperties.has("series") && this.chart && this.series.length > 0) {
161671
+ const seriesChanged = changedProperties.has("series") && this.series.length > 0;
161672
+ if (seriesChanged && this.chart) {
161496
161673
  await this.updateSeries(this.series);
161497
161674
  }
161498
161675
  if (changedProperties.has("yAxisFormatter") && this.chart) {
161499
161676
  }
161500
- if (changedProperties.has("realtimeMode") && this.chart) {
161501
- if (this.realtimeMode && this.rollingWindow > 0 && this.autoScrollInterval > 0) {
161502
- this.startAutoScroll();
161677
+ const realtimeConfigurationChanged = changedProperties.has("realtimeMode") || changedProperties.has("rollingWindow");
161678
+ const autoScrollConfigurationChanged = realtimeConfigurationChanged || changedProperties.has("autoScrollInterval");
161679
+ if (this.chart && realtimeConfigurationChanged) {
161680
+ if (!seriesChanged && this.internalChartData.length > 0) {
161681
+ await this.updateSeries(this.internalChartData);
161682
+ }
161683
+ if (this.realtimeMode && this.rollingWindow > 0) {
161684
+ await this.updateTimeWindow();
161503
161685
  } else {
161504
- this.stopAutoScroll();
161686
+ this.chart.timeScale().fitContent();
161505
161687
  }
161506
161688
  }
161507
- if (changedProperties.has("autoScrollInterval") && this.chart) {
161508
- this.stopAutoScroll();
161509
- if (this.realtimeMode && this.rollingWindow > 0 && this.autoScrollInterval > 0) {
161510
- this.startAutoScroll();
161511
- }
161689
+ if (this.chart && autoScrollConfigurationChanged) {
161690
+ this.syncAutoScroll();
161512
161691
  }
161513
161692
  if (changedProperties.has("chartLines") && this.chart) {
161514
161693
  this.refreshPriceLines();
@@ -161529,77 +161708,76 @@ var _DeesChartArea = class _DeesChartArea extends (_a56 = DeesElement, _chart_de
161529
161708
  async updateSeries(newSeries, animate = true) {
161530
161709
  if (!this.chart) return;
161531
161710
  try {
161532
- this.internalChartData = newSeries;
161533
- if (this.rollingWindow > 0 && this.realtimeMode) {
161534
- const now3 = Date.now();
161535
- const cutoffTime = now3 - this.rollingWindow;
161536
- if (newSeries.length !== this.seriesApis.size) {
161537
- this.recreateSeries(newSeries);
161538
- } else {
161539
- const isDark = !this.goBright;
161540
- newSeries.forEach((s9, index3) => {
161541
- const name = s9.name || `series-${index3}`;
161542
- const api = this.seriesApis.get(name);
161543
- if (!api) return;
161544
- const filtered = s9.data.filter((point4) => {
161545
- const ms = typeof point4.x === "number" ? point4.x : new Date(point4.x).getTime();
161546
- return ms > cutoffTime;
161547
- });
161548
- api.setData(this.convertDataToLC(filtered));
161549
- const color2 = this.resolveSeriesColor(s9, index3, isDark);
161550
- api.applyOptions({
161551
- topColor: this.colorToRgba(color2, isDark ? 0.4 : 0.5),
161552
- bottomColor: this.colorToRgba(color2, 0),
161553
- lineColor: color2
161554
- });
161555
- this.updatePriceLines(name, api, filtered, color2);
161556
- });
161557
- this.computeStats(newSeries);
161558
- }
161559
- try {
161560
- this.chart.timeScale().setVisibleRange({
161561
- from: Math.floor(cutoffTime / 1e3),
161562
- to: Math.floor(now3 / 1e3)
161563
- });
161564
- } catch (e10) {
161565
- }
161566
- if (this.yAxisScaling === "dynamic") {
161567
- const allValues = newSeries.flatMap(
161568
- (s9) => s9.data.filter((p6) => {
161569
- const ms = typeof p6.x === "number" ? p6.x : new Date(p6.x).getTime();
161570
- return ms > cutoffTime;
161571
- }).map((d5) => d5.y)
161572
- );
161573
- if (allValues.length > 0) {
161574
- const dynamicMax = Math.ceil(Math.max(...allValues) * 1.1);
161575
- for (const [, api] of this.seriesApis) {
161576
- api.applyOptions({
161577
- autoscaleInfoProvider: /* @__PURE__ */ __name(() => ({ priceRange: { minValue: 0, maxValue: dynamicMax } }), "autoscaleInfoProvider")
161578
- });
161579
- }
161580
- }
161711
+ void animate;
161712
+ const canonicalSeries = this.getCanonicalChartSeries(newSeries);
161713
+ this.internalChartData = canonicalSeries;
161714
+ const renderedKeys = [...this.seriesApis.keys()];
161715
+ const canonicalKeys = canonicalSeries.map((series, index3) => this.getSeriesKey(series, index3));
161716
+ if (!haveSameSeriesLayout(renderedKeys, canonicalKeys)) {
161717
+ this.clearCrosshairForDataReplacement();
161718
+ this.recreateSeries(canonicalSeries);
161719
+ this.updateSeriesPresentation(canonicalSeries);
161720
+ return;
161721
+ }
161722
+ if (!this.realtimeMode || this.rollingWindow <= 0) {
161723
+ this.clearCrosshairForDataReplacement();
161724
+ canonicalSeries.forEach((series, index3) => {
161725
+ this.seriesApis.get(this.getSeriesKey(series, index3)).setData(this.convertDataToLC(series.data));
161726
+ });
161727
+ this.pendingRealtimePrune = false;
161728
+ this.updateSeriesPresentation(canonicalSeries);
161729
+ return;
161730
+ }
161731
+ const plannedUpdates = canonicalSeries.map((series, index3) => {
161732
+ const api = this.seriesApis.get(this.getSeriesKey(series, index3));
161733
+ const canonicalData = this.convertDataToLC(series.data).map((point4) => ({ time: point4.time, value: point4.value }));
161734
+ return {
161735
+ api,
161736
+ canonicalData,
161737
+ plan: planRealtimeChartUpdates(this.getRenderedSeriesData(api), canonicalData)
161738
+ };
161739
+ });
161740
+ if (plannedUpdates.some(({ plan }) => plan.replacementRequired)) {
161741
+ this.clearCrosshairForDataReplacement();
161742
+ for (const { api, canonicalData } of plannedUpdates) {
161743
+ api.setData(canonicalData.map((point4) => ({
161744
+ time: point4.time,
161745
+ value: point4.value
161746
+ })));
161581
161747
  }
161748
+ this.pendingRealtimePrune = false;
161582
161749
  } else {
161583
- if (newSeries.length !== this.seriesApis.size) {
161584
- this.recreateSeries(newSeries);
161585
- } else {
161586
- const isDark = !this.goBright;
161587
- newSeries.forEach((s9, index3) => {
161588
- const name = s9.name || `series-${index3}`;
161589
- const api = this.seriesApis.get(name);
161590
- if (!api) return;
161591
- api.setData(this.convertDataToLC(s9.data));
161592
- const color2 = this.resolveSeriesColor(s9, index3, isDark);
161593
- api.applyOptions({
161594
- topColor: this.colorToRgba(color2, isDark ? 0.4 : 0.5),
161595
- bottomColor: this.colorToRgba(color2, 0),
161596
- lineColor: color2
161597
- });
161598
- this.updatePriceLines(name, api, s9.data, color2);
161599
- });
161600
- this.computeStats(newSeries);
161601
- }
161602
- }
161750
+ for (const { api, plan } of plannedUpdates) {
161751
+ for (const update of plan.updates) {
161752
+ api.update({
161753
+ time: update.point.time,
161754
+ value: update.point.value
161755
+ }, update.historicalUpdate);
161756
+ }
161757
+ }
161758
+ const pruneRequired = plannedUpdates.some(({ plan }) => plan.pruneRequired);
161759
+ const pruneRecommended = plannedUpdates.some(({ plan }) => plan.pruneRecommended);
161760
+ if (pruneRequired) {
161761
+ this.clearCrosshairForDataReplacement();
161762
+ for (const { api, canonicalData } of plannedUpdates) {
161763
+ api.setData(canonicalData.map((point4) => ({
161764
+ time: point4.time,
161765
+ value: point4.value
161766
+ })));
161767
+ }
161768
+ } else if (pruneRecommended && this.crosshairActive) {
161769
+ this.pendingRealtimePrune = true;
161770
+ } else if (pruneRecommended) {
161771
+ for (const { api, canonicalData } of plannedUpdates) {
161772
+ api.setData(canonicalData.map((point4) => ({
161773
+ time: point4.time,
161774
+ value: point4.value
161775
+ })));
161776
+ }
161777
+ this.pendingRealtimePrune = false;
161778
+ }
161779
+ }
161780
+ this.updateSeriesPresentation(canonicalSeries);
161603
161781
  } catch (error) {
161604
161782
  console.error("Failed to update chart series:", error);
161605
161783
  }
@@ -161618,15 +161796,26 @@ var _DeesChartArea = class _DeesChartArea extends (_a56 = DeesElement, _chart_de
161618
161796
  }
161619
161797
  async appendData(newData) {
161620
161798
  if (!this.chart) return;
161799
+ const nextSeries = this.internalChartData.map((series) => ({
161800
+ ...series,
161801
+ data: [...series.data]
161802
+ }));
161803
+ const namedOccurrences = /* @__PURE__ */ new Map();
161621
161804
  newData.forEach((s9, index3) => {
161622
- const name = s9.name || `series-${index3}`;
161623
- const api = this.seriesApis.get(name);
161624
- if (!api || s9.data.length === 0) return;
161625
- for (const point4 of s9.data) {
161626
- const lcPoints = this.convertDataToLC([point4]);
161627
- if (lcPoints.length > 0) api.update(lcPoints[0]);
161628
- }
161805
+ let targetIndex = index3;
161806
+ if (s9.name) {
161807
+ const occurrence = namedOccurrences.get(s9.name) ?? 0;
161808
+ namedOccurrences.set(s9.name, occurrence + 1);
161809
+ const matchingIndices = this.internalChartData.map((series, seriesIndex) => series.name === s9.name ? seriesIndex : -1).filter((seriesIndex) => seriesIndex >= 0);
161810
+ const matchingIndex = matchingIndices[occurrence];
161811
+ if (matchingIndex === void 0) return;
161812
+ targetIndex = matchingIndex;
161813
+ }
161814
+ const targetSeries = nextSeries[targetIndex];
161815
+ if (!targetSeries || s9.data.length === 0) return;
161816
+ targetSeries.data.push(...s9.data);
161629
161817
  });
161818
+ await this.updateSeries(nextSeries);
161630
161819
  }
161631
161820
  async updateOptions(options2) {
161632
161821
  if (!this.chart) return;
@@ -161663,25 +161852,31 @@ var _DeesChartArea = class _DeesChartArea extends (_a56 = DeesElement, _chart_de
161663
161852
  }
161664
161853
  refreshPriceLines() {
161665
161854
  const isDark = !this.goBright;
161666
- this.chartSeries.forEach((s9, index3) => {
161667
- const name = s9.name || `series-${index3}`;
161668
- const api = this.seriesApis.get(name);
161855
+ this.getCanonicalChartSeries(this.internalChartData).forEach((s9, index3) => {
161856
+ const seriesKey = this.getSeriesKey(s9, index3);
161857
+ const api = this.seriesApis.get(seriesKey);
161669
161858
  if (!api) return;
161670
- this.updatePriceLines(name, api, s9.data, this.resolveSeriesColor(s9, index3, isDark));
161859
+ this.updatePriceLines(seriesKey, api, s9.data, this.resolveSeriesColor(s9, index3, isDark));
161671
161860
  });
161672
161861
  }
161673
161862
  startAutoScroll() {
161674
- if (this.autoScrollTimer) return;
161863
+ if (this.autoScrollTimer !== null) return;
161675
161864
  this.autoScrollTimer = window.setInterval(() => {
161676
161865
  this.updateTimeWindow();
161677
161866
  }, this.autoScrollInterval);
161678
161867
  }
161679
161868
  stopAutoScroll() {
161680
- if (this.autoScrollTimer) {
161869
+ if (this.autoScrollTimer !== null) {
161681
161870
  window.clearInterval(this.autoScrollTimer);
161682
161871
  this.autoScrollTimer = null;
161683
161872
  }
161684
161873
  }
161874
+ syncAutoScroll() {
161875
+ this.stopAutoScroll();
161876
+ if (this.realtimeMode && this.rollingWindow > 0 && this.autoScrollInterval > 0) {
161877
+ this.startAutoScroll();
161878
+ }
161879
+ }
161685
161880
  };
161686
161881
  _init57 = __decoratorStart(_a56);
161687
161882
  _chart = new WeakMap();
@@ -198026,7 +198221,7 @@ init_group_runtime();
198026
198221
  // ts_web/00_commitinfo_data.ts
198027
198222
  var commitinfo = {
198028
198223
  name: "@design.estate/dees-catalog",
198029
- version: "3.98.0",
198224
+ version: "3.98.1",
198030
198225
  description: "A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript."
198031
198226
  };
198032
198227
 
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@design.estate/dees-catalog',
6
- version: '3.98.0',
6
+ version: '3.98.1',
7
7
  description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHNfd2ViLzAwX2NvbW1pdGluZm9fZGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRztJQUN4QixJQUFJLEVBQUUsNkJBQTZCO0lBQ25DLE9BQU8sRUFBRSxRQUFRO0lBQ2pCLFdBQVcsRUFBRSxzSkFBc0o7Q0FDcEssQ0FBQSJ9
@@ -59,15 +59,28 @@ export declare class DeesChartArea extends DeesElement {
59
59
  private seriesApis;
60
60
  private priceLines;
61
61
  private tooltipEl;
62
+ private crosshairActive;
63
+ private pendingRealtimePrune;
64
+ private crosshairMoveHandler;
65
+ private chartContainer;
66
+ private readonly chartMouseLeaveHandler;
62
67
  constructor();
63
68
  static styles: import("@design.estate/dees-element").CSSResult[];
64
69
  render(): TemplateResult;
65
70
  private convertDataToLC;
71
+ private getSeriesName;
72
+ private getSeriesKey;
73
+ private getCanonicalChartSeries;
74
+ private getRenderedSeriesData;
66
75
  private colorToRgba;
67
76
  private getSeriesColors;
68
77
  private resolveSeriesColor;
69
78
  private applyTheme;
70
79
  private recreateSeries;
80
+ private updateSeriesPresentation;
81
+ private handleCrosshairCleared;
82
+ private clearCrosshairForDataReplacement;
83
+ private flushPendingRealtimePrune;
71
84
  private computeStats;
72
85
  private updatePriceLines;
73
86
  private setupTooltip;
@@ -89,4 +102,5 @@ export declare class DeesChartArea extends DeesElement {
89
102
  private refreshPriceLines;
90
103
  private startAutoScroll;
91
104
  private stopAutoScroll;
105
+ private syncAutoScroll;
92
106
  }