Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding markers to chart with many datapoints causes significant performance issues. #1808

Open
jackroc97 opened this issue Feb 11, 2025 · 2 comments
Labels
enhancement Feature requests, and general improvements.

Comments

@jackroc97
Copy link

jackroc97 commented Feb 11, 2025

Lightweight Charts™ Version: 5.0.X (lastet version via CDN)

Steps/code to reproduce:
I am using lightweight charts to produce a chart that plots candles for an index at the 5-minute interval for the course of whole year. This is around 60,0000+ candles on one chart, and it performs just fine with all candles loaded (meaning that I can scroll, zoom, move my cursor with no noticeable lag). However, adding just one marker to this chart makes it unusably slow to react to input (scrolling, zooming, moving the cursor is extremely laggy.

Are there any recommendations for how to deal with large data sets with markers, without tanking performance? I have done some rough experimentation with this, and the performance seems to begin to drop off around 15000 data points (with one marker added to the chart).

Actual behavior:

Adding one marker to a chart with a large data set (10s of thousands) causes significant performance issues compared to a chart with the same data set, but no markers.

Expected behavior:

Adding just one marker to a chart should not cause performance issues. Scrolling, zooming, and using the cursor should be as responsive as using the same chart with no markers.

@SlicedSilver
Copy link
Contributor

I created a small example, and I can confirm there is a noticeable decrease in rendering performance when the series marker plugin is used on a chart with thousands of data points.

https://glitch.com/edit/#!/lwc-1808-issue

It seems that the issue is the running of _recalculateMarkers within

private _recalculateMarkers(): void {
on every pane update. We could optimise this by only running this calculation when the data changes (or markers are adjusted).

We will look into this in more detail but the following code seems to improve the situation:

diff --git a/src/plugins/series-markers/primitive.ts b/src/plugins/series-markers/primitive.ts
index e792785a7..faf932c98 100644
--- a/src/plugins/series-markers/primitive.ts
+++ b/src/plugins/series-markers/primitive.ts
@@ -31,6 +31,7 @@ export class SeriesMarkersPrimitive<HorzScaleItem> implements ISeriesPrimitive<H
 	private _autoScaleMargins: AutoScaleMargins | null = null;
 	private _markersPositions: MarkerPositions | null = null;
 	private _cachedBarSpacing: number | null = null;
+	private _recalculationRequired: boolean = true;
 
 	public attached(param: SeriesAttachedParameter<HorzScaleItem>): void {
 		this._recalculateMarkers();
@@ -39,6 +40,7 @@ export class SeriesMarkersPrimitive<HorzScaleItem> implements ISeriesPrimitive<H
 		this._paneView = new SeriesMarkersPaneView(this._series, ensureNotNull(this._chart));
 		this._requestUpdate = param.requestUpdate;
 		this._series.subscribeDataChanged((scope: DataChangedScope) => this._onDataChanged(scope));
+		this._recalculationRequired = true;
 		this.requestUpdate();
 	}
 
@@ -59,6 +61,7 @@ export class SeriesMarkersPrimitive<HorzScaleItem> implements ISeriesPrimitive<H
 	}
 
 	public setMarkers(markers: SeriesMarker<HorzScaleItem>[]): void {
+		this._recalculationRequired = true;
 		this._markers = markers;
 		this._recalculateMarkers();
 		this._autoScaleMarginsInvalidated = true;
@@ -142,7 +145,7 @@ export class SeriesMarkersPrimitive<HorzScaleItem> implements ISeriesPrimitive<H
 	}
 
 	private _recalculateMarkers(): void {
-		if (!this._chart || !this._series) {
+		if (!this._recalculationRequired || !this._chart || !this._series) {
 			return;
 		}
 		const timeScale = this._chart.timeScale();
@@ -172,6 +175,7 @@ export class SeriesMarkersPrimitive<HorzScaleItem> implements ISeriesPrimitive<H
 				originalTime: marker.time,
 			};
 		});
+		this._recalculationRequired = false;
 	}
 
 	private _updateAllViews(updateType?: UpdateType): void {
@@ -183,6 +187,7 @@ export class SeriesMarkersPrimitive<HorzScaleItem> implements ISeriesPrimitive<H
 	}
 
 	private _onDataChanged(scope: DataChangedScope): void {
+		this._recalculationRequired = true;
 		this.requestUpdate();
 	}
 }

lwc-1808.patch

@SlicedSilver SlicedSilver added the enhancement Feature requests, and general improvements. label Feb 11, 2025
@jackroc97
Copy link
Author

Thank you @SlicedSilver! I have tried out the patch you provided and it seems to remedy the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Feature requests, and general improvements.
Projects
None yet
Development

No branches or pull requests

2 participants