diff --git a/src/gui/price-axis-widget.ts b/src/gui/price-axis-widget.ts index 7adabfc66e..857522d1e9 100644 --- a/src/gui/price-axis-widget.ts +++ b/src/gui/price-axis-widget.ts @@ -66,16 +66,22 @@ function buildPriceAxisViewsGetter( }; } -function recalculateOverlapping(views: IPriceAxisView[], direction: 1 | -1, scaleHeight: number, rendererOptions: Readonly): void { +function recalculateOverlapping( + views: IPriceAxisView[], + direction: 1 | -1, + scaleHeight: number, + rendererOptions: Readonly +): void { if (!views.length) { return; } let currentGroupStart = 0; + const center = scaleHeight / 2; const initLabelHeight = views[0].height(rendererOptions, true); let spaceBeforeCurrentGroup = direction === 1 - ? scaleHeight / 2 - (views[0].getFixedCoordinate() - initLabelHeight / 2) - : views[0].getFixedCoordinate() - initLabelHeight / 2 - scaleHeight / 2; + ? center - (views[0].getFixedCoordinate() - initLabelHeight / 2) + : views[0].getFixedCoordinate() - initLabelHeight / 2 - center; spaceBeforeCurrentGroup = Math.max(0, spaceBeforeCurrentGroup); for (let i = 1; i < views.length; i++) { @@ -560,8 +566,6 @@ export class PriceAxisWidget implements IDestroyable { if (this._size === null || this._priceScale === null) { return; } - let center = this._size.height / 2; - const views: IPriceAxisView[] = []; const orderedSources = this._priceScale.orderedSources().slice(); // Copy of array const pane = this._pane; @@ -579,8 +583,6 @@ export class PriceAxisWidget implements IDestroyable { }); } - // we can use any, but let's use the first source as "center" one - const centerSource = this._priceScale.dataSources()[0]; const priceScale = this._priceScale; const updateForSources = (sources: IDataSource[]) => { @@ -593,9 +595,6 @@ export class PriceAxisWidget implements IDestroyable { views.push(view); } }); - if (centerSource === source && sourceViews.length > 0) { - center = sourceViews[0].coordinate(); - } }); }; @@ -609,26 +608,22 @@ export class PriceAxisWidget implements IDestroyable { return; } - this._fixLabelOverlap(views, rendererOptions, center); + this._fixLabelOverlap(views, rendererOptions); } - private _fixLabelOverlap(views: IPriceAxisView[], rendererOptions: Readonly, center: number): void { + private _fixLabelOverlap(views: IPriceAxisView[], rendererOptions: Readonly): void { if (this._size === null) { return; } + const center = this._size.height / 2; + // split into two parts const top = views.filter((view: IPriceAxisView) => view.coordinate() <= center); const bottom = views.filter((view: IPriceAxisView) => view.coordinate() > center); // sort top from center to top top.sort((l: IPriceAxisView, r: IPriceAxisView) => r.coordinate() - l.coordinate()); - - // share center label - if (top.length && bottom.length) { - bottom.push(top[0]); - } - bottom.sort((l: IPriceAxisView, r: IPriceAxisView) => l.coordinate() - r.coordinate()); for (const view of views) { diff --git a/tests/e2e/graphics/test-cases/price-scale/improve-alignment-2.js b/tests/e2e/graphics/test-cases/price-scale/improve-alignment-2.js new file mode 100644 index 0000000000..fd050db8ab --- /dev/null +++ b/tests/e2e/graphics/test-cases/price-scale/improve-alignment-2.js @@ -0,0 +1,78 @@ +function runTestCase(container) { + const chartOptions = { + height: 500, + width: 600, + rightPriceScale: { + scaleMargins: { + top: 0, + bottom: 0, + }, + entireTextOnly: true, + alignLabels: true, + }, + }; + + const chart = (window.chart = LightweightCharts.createChart( + container, + chartOptions + )); + + const levels = [ + 25.44, + 17.96, + 14.14, + 4.23, + 4.08, + 3.42, + 3.09, + 2.78, + 2.24, + 2.14, + 2.05, + 1.92, + 1.69, + 1.67, + 1.47, + 1.32, + 1.11, + 0.90712, + 0.63113, + 0.40527, + ].map(price => ({ price })); + + const colorByIndex = index => { + const r = index & 0b10000 >> 4; + const g = index & 0b01100 >> 2; + const b = index & 0b00011; + return `rgb(${Math.floor(r * 255)}, ${Math.floor(g * 255 / 4)}, ${Math.floor(b * 255 / 4)})`; + }; + + for (let i = 0; i < levels.length; i++) { + const s = chart.addLineSeries({ + color: colorByIndex(i), + }); + s.setData([ + { time: 10000, value: levels[i].price }, + { time: 20000, value: levels[i].price }, + ]); + levels[i].series = s; + } + + for (let i = 0; i < 4; i++) { + chart.removeSeries(levels[i].series); + delete levels[i].series; + } + + for (let i = 3; i >= 2; i--) { + const s = chart.addLineSeries({ + color: colorByIndex(i), + }); + s.setData([ + { time: 10000, value: levels[i].price }, + { time: 20000, value: levels[i].price }, + ]); + levels[i].series = s; + } + + chart.timeScale().fitContent(); +}