diff --git a/lightweight_charts/abstract.py b/lightweight_charts/abstract.py index 2b21d2c..b3382c2 100644 --- a/lightweight_charts/abstract.py +++ b/lightweight_charts/abstract.py @@ -98,13 +98,14 @@ class Window: heading_background_colors, return_clicked_cells, func) def create_subchart(self, position: FLOAT = 'left', width: float = 0.5, height: float = 0.5, - sync_id: str = None, scale_candles_only: bool = False, toolbox: bool = False + sync_id: str = None, scale_candles_only: bool = False, + sync_crosshairs_only: bool = False, toolbox: bool = False ) -> 'AbstractChart': subchart = AbstractChart(self, width, height, scale_candles_only, toolbox, position=position) if not sync_id: return subchart self.run_script(f''' - syncCharts({subchart.id}, {sync_id}) + syncCharts({subchart.id}, {sync_id}, {jbool(sync_crosshairs_only)}) {subchart.id}.chart.timeScale().setVisibleLogicalRange( {sync_id}.chart.timeScale().getVisibleLogicalRange() ) @@ -1021,7 +1022,9 @@ class AbstractChart(Candlestick, Pane): def create_subchart(self, position: FLOAT = 'left', width: float = 0.5, height: float = 0.5, sync: Union[str, bool] = None, scale_candles_only: bool = False, + sync_crosshairs_only: bool = False, toolbox: bool = False) -> 'AbstractChart': if sync is True: sync = self.id - return self.win.create_subchart(position, width, height, sync, scale_candles_only, toolbox) + return self.win.create_subchart(position, width, height, sync, + scale_candles_only, sync_crosshairs_only, toolbox) diff --git a/lightweight_charts/js/funcs.js b/lightweight_charts/js/funcs.js index ec61abc..0e4a396 100644 --- a/lightweight_charts/js/funcs.js +++ b/lightweight_charts/js/funcs.js @@ -310,7 +310,7 @@ if (!window.Chart) { return num.toString().padStart(8, ' '); } - legendHandler(param) { + legendHandler(param, usingPoint= false) { let options = this.chart.series.options() if (!param.time) { @@ -319,8 +319,6 @@ if (!window.Chart) { return } - let usingPoint = !param.point && param.time - let data, logical if (usingPoint) { @@ -353,7 +351,14 @@ if (!window.Chart) { str += '| ' + percentStr } } - let volumeData = param.seriesData.get(this.chart.volumeSeries) + + let volumeData; + if (usingPoint) { + volumeData = this.chart.volumeSeries.dataByIndex(logical) + } + else { + volumeData = param.seriesData.get(this.chart.volumeSeries) + } if (volumeData) { str += this.ohlcEnabled ? `
V ${this.shorthandFormat(volumeData.value)}` : '' } @@ -390,7 +395,7 @@ if (!window.Chart) { window.Legend = Legend } -function syncCharts(childChart, parentChart) { +function syncCharts(childChart, parentChart, crosshairOnly= false) { function crosshairHandler(chart, point) { if (!point) { @@ -398,7 +403,7 @@ function syncCharts(childChart, parentChart) { return } chart.chart.setCrosshairPosition(point.value || point.close, point.time, chart.series); - chart.legend.legendHandler(point) + chart.legend.legendHandler(point, true) } function getPoint(series, param) { @@ -406,8 +411,15 @@ function syncCharts(childChart, parentChart) { return param.seriesData.get(series) || null; } - let setChildRange = (timeRange) => childChart.chart.timeScale().setVisibleLogicalRange(timeRange) - let setParentRange = (timeRange) => parentChart.chart.timeScale().setVisibleLogicalRange(timeRange) + let setChildRange, setParentRange; + if (crosshairOnly) { + setChildRange = (timeRange) => { } + setParentRange = (timeRange) => { } + } + else { + setChildRange = (timeRange) => childChart.chart.timeScale().setVisibleLogicalRange(timeRange) + setParentRange = (timeRange) => parentChart.chart.timeScale().setVisibleLogicalRange(timeRange) + } let setParentCrosshair = (param) => { crosshairHandler(parentChart, getPoint(childChart.series, param))