lightweight-charts icon indicating copy to clipboard operation
lightweight-charts copied to clipboard

A way to set PriceScale width - currently there's no way to keep two charts' PriceScale width in sync one above the other

Open quakemmo opened this issue 2 years ago • 13 comments

Screenshot from 2022-04-16 17-58-43

I have two charts (one for price, one for volume). I keep them in sync by usingthe various API observer functions. Works wonders.

Except the price scale width - I can get it using the priceScale('right').width() call, but I don't see any way to set it. I'd like to be able to keep the width of both chart's price scales in sync (and keep them set to the max width of the two).

Thanks!

quakemmo avatar Apr 16 '22 16:04 quakemmo

Bump!

quakemmo avatar May 03 '22 08:05 quakemmo

Screenshot from 2022-04-16 17-58-43

I have two charts (one for price, one for volume). I keep them in sync by usingthe various API observer functions. Works wonders.

Except the price scale width - I can get it using the priceScale('right').width() call, but I don't see any way to set it. I'd like to be able to keep the width of both chart's price scales in sync (and keep them set to the max width of the two).

Thanks!

Man, how did you display two panels on one chart?

matthewwwz avatar May 05 '22 19:05 matthewwwz

@matthewwwz It's two different charts...

quakemmo avatar May 08 '22 14:05 quakemmo

Hi @quakemmo!

Have you got a jsfiddle or something else where we could reproduce the issue and check how to fix it if possible?

romfrancois avatar May 09 '22 08:05 romfrancois

@romfrancois Hello, and thank you for the reply.

I don't think there's need for a jsfiddle - you can just grab any working LWC and the issue will apply to it - ie: you cannot manually adjust price scale width.

I just need a way to set the price scale width (so I can have several charts, find the widest price scale, and set all the charts' price scale to that width).

Something like myChart.priceScale('right').setWidth(param), where param could be either 'XYZpx', or 'auto', would be awesome.

quakemmo avatar May 15 '22 07:05 quakemmo

@romfrancois Bump <3 Do you need me to set a jsfiddle up?

quakemmo avatar May 22 '22 12:05 quakemmo

Unfortunately that's not possible at the moment.

romfrancois avatar May 23 '22 13:05 romfrancois

@romfrancois I see, thank you for your reply. Is it a feature that you guys might consider adding?

quakemmo avatar May 26 '22 07:05 quakemmo

Not in the near future no but we've tagged this ticket to keep an eye on it.

romfrancois avatar May 26 '22 10:05 romfrancois

@romfrancois Thank you.

So right now, the recommended way to display a candlestick price graph along with a bar volume graph (for example), one below the other, is to just create ONE chart with two data series?

I took the approach of creating two different charts, and listening to their scrolling/zooming events to keep them in sync, did I go an unnecessary complicated route?

I'd like to achieve a result similar to what you can see here: https://www.kucoin.com/trade/BTC-USDT As you can see they seem to use two different charts that are kept in sync, yet somehow manage to keep the right price scale at the same width.

quakemmo avatar May 27 '22 07:05 quakemmo

@quakemmo

It is not currently possible to exactly match what you can see on the link you share but Lightweight Charts does support volume series within the same chart so you don't need to manually synchronise anything.

Check out this example https://jsfiddle.net/TradingView/cnbamtuh/

edew avatar May 27 '22 11:05 edew

Bump. I'd like to do this but not with volume, but arbitrary indicators, plotted below and synced.

dsimic avatar Jul 27 '22 20:07 dsimic

Related: https://stackoverflow.com/a/73209722/1934064

SlicedSilver avatar Aug 26 '22 16:08 SlicedSilver

Hi @quakemmo

I have two charts (one for price, one for volume). I keep them in sync by usingthe various API observer functions. Works wonders. I took the approach of creating two different charts, and listening to their scrolling/zooming events to keep them in sync, did I go an unnecessary complicated route?

Do you mind to share more details about this? some code example maybe? I also need to keep the 2 separated charts in sync, and it seems that it is more complicated than I thought. Thank you very much!

tsunamilx avatar Mar 05 '23 15:03 tsunamilx

Looking forwards for merge #1412

As a temporary solution I found effective adding extra symbols in price formatter. For example knowing that you have large digit (i.e. bitcoin 30,000.00), you can kind of create min width for the priceScale panel

Of course not ideal and resulting string width highly depends on the font

			localization: {
				priceFormatter: (price: number) => {
					let priceStr = formatPrice(price);
					const distance = 9 - priceStr.length;

					if (distance > 0) {
						const whitespaces = [...new Array(distance)].map((_) => '_').join('');
						priceStr = `${priceStr}${whitespaces}`;
					}
					return priceStr;
				}
			}

dpmango avatar Sep 13 '23 18:09 dpmango

@edew With the minimumWidth option this still doesn't address syncing the charts. I rather not set both charts with a fixed min width, and instead have them use the max of either.

To sync a 2nd chart with a 1st, I've come up with this:

setTimeout(() => {
    chart2.priceScale('right').applyOptions({
        minimumWidth: chart1.priceScale('right').width(),
    })
}, 0)

However, chart1.priceScale('right').width() is returning 0 for me, so I had to put it in a setTimeout to have it execute on the next loop. Should I open a new issue, or could this be re-opened?

mozeryansky avatar Oct 25 '23 07:10 mozeryansky

priceScale('right').width() returning 0 before the chart has been rendered is expected. If you need to measure the width at startup then using setTimeout is the correct approach.

I rather not set both charts with a fixed min width, and instead have them use the max of either.

Setting the minimum width of the one chart to the width of the other (wider) chart does allow you to ensure that both price scales are the same width (maximum of the two).

You can use the subscribeSizeChange event on the timescale to assist with keeping all the price scales in sync.

SlicedSilver avatar Oct 25 '23 08:10 SlicedSilver

I guess I was over thinking something like minWidthRef: otherChartRef. I've changed my code to adjust the minimumWidth on the subscribeSizeChange callback, and now no timeout tricks needed.

Is there a subscription for price scale change? I noticed if I scaled the price from 3 to 4 digits on the top chart then I need to adjust the minimumWidth again for the bottom chart.

mozeryansky avatar Oct 25 '23 09:10 mozeryansky

You should be able to use the subscribeSizeChange for knowing when the price scale width changes since if the chart width is constant then the time scale width needs to change if the price scale width changes. Hope that is making sense.

SlicedSilver avatar Oct 25 '23 10:10 SlicedSilver

I have 2 charts and the top chart I have disabled the timescale as I use the bottom charts timescale. For the top chart, I get a single callback with (width: 0, height: 0) when I have the option { timeScale: { visible: false } }, but I do get calls when it's set to true.

Is there not a way to get the visible price range, like onVisibleLogicalRangeChange?

mozeryansky avatar Oct 26 '23 01:10 mozeryansky

There is a paneSize method which you could use to get the width of the chart pane (which would be the same as the time scale if it was visible).

If you need a utility for visible price range then you could try this plugin: lwc-plugin-visible-price-range-util

A similar approach could be used to create a plugin which provides a subscriber for paneSize changes, or PriceScale width changes.

SlicedSilver avatar Oct 26 '23 08:10 SlicedSilver

Thanks, lwc-plugin-visible-price-range-util works great!

mozeryansky avatar Oct 27 '23 05:10 mozeryansky