From da2a5103fab1ae493fe07577bc21a5a58258f194 Mon Sep 17 00:00:00 2001 From: louisnw Date: Sun, 10 Dec 2023 19:48:27 +0000 Subject: [PATCH] Enhancements & Bug Fixes - Added the `color_based_on_candle` parameter to the legend, which will color the percentage change based on the candle color underneath the crosshair. (#210) - Fixed a bug which prevented the legend from turning off. (#216) --- docs/source/reference/abstract_chart.md | 2 +- lightweight_charts/abstract.py | 10 +++- lightweight_charts/js/funcs.js | 78 ++++++++++++++++--------- setup.py | 2 +- 4 files changed, 60 insertions(+), 32 deletions(-) diff --git a/docs/source/reference/abstract_chart.md b/docs/source/reference/abstract_chart.md index 5722392..13067d6 100644 --- a/docs/source/reference/abstract_chart.md +++ b/docs/source/reference/abstract_chart.md @@ -273,7 +273,7 @@ ___ -```{py:method} legend(visible: bool, ohlc: bool, percent: bool, lines: bool, color: COLOR, font_size: int, font_family: str, text: str) +```{py:method} legend(visible: bool, ohlc: bool, percent: bool, lines: bool, color: COLOR, font_size: int, font_family: str, text: str, color_based_on_candle: bool) Configures the legend of the chart. ``` diff --git a/lightweight_charts/abstract.py b/lightweight_charts/abstract.py index fcd2f46..d2737f5 100644 --- a/lightweight_charts/abstract.py +++ b/lightweight_charts/abstract.py @@ -904,19 +904,25 @@ class AbstractChart(Candlestick, Pane): def legend(self, visible: bool = False, ohlc: bool = True, percent: bool = True, lines: bool = True, color: str = 'rgb(191, 195, 203)', font_size: int = 11, font_family: str = 'Monaco', - text: str = ''): + text: str = '', color_based_on_candle: bool = False): """ Configures the legend of the chart. """ l_id = f'{self.id}.legend' if not visible: - self.run_script(f'{l_id}.div.style.display = "none"') + self.run_script(f''' + {l_id}.div.style.display = "none" + {l_id}.ohlcEnabled = false + {l_id}.percentEnabled = false + {l_id}.linesEnabled = false + ''') return self.run_script(f''' {l_id}.div.style.display = 'flex' {l_id}.ohlcEnabled = {jbool(ohlc)} {l_id}.percentEnabled = {jbool(percent)} {l_id}.linesEnabled = {jbool(lines)} + {l_id}.colorBasedOnCandle = {jbool(color_based_on_candle)} {l_id}.div.style.color = '{color}' {l_id}.color = '{color}' {l_id}.div.style.fontSize = '{font_size}px' diff --git a/lightweight_charts/js/funcs.js b/lightweight_charts/js/funcs.js index 12c1917..67a5ed6 100644 --- a/lightweight_charts/js/funcs.js +++ b/lightweight_charts/js/funcs.js @@ -185,6 +185,7 @@ if (!window.Chart) { this.ohlcEnabled = false this.percentEnabled = false this.linesEnabled = false + this.colorBasedOnCandle = false this.div = document.createElement('div') this.div.style.position = 'absolute' @@ -219,40 +220,61 @@ if (!window.Chart) { } chart.chart.subscribeCrosshairMove((param) => { - if (param.time) { - let data = param.seriesData.get(chart.series); - let finalString = '' - if (data) { - this.candle.style.color = '' - let ohlc = `O ${legendItemFormat(data.open, chart.precision)} - | H ${legendItemFormat(data.high, chart.precision)} - | L ${legendItemFormat(data.low, chart.precision)} - | C ${legendItemFormat(data.close, chart.precision)} ` - let percentMove = ((data.close - data.open) / data.open) * 100 - let percent = `| ${percentMove >= 0 ? '+' : ''}${percentMove.toFixed(2)} %` - finalString += this.ohlcEnabled ? ohlc : '' - finalString += this.percentEnabled ? percent : '' - - let volumeData = param.seriesData.get(chart.volumeSeries) - if (volumeData) finalString += this.ohlcEnabled ? `
V ${shorthandFormat(volumeData.value)}` : '' + let options = chart.series.options() + if (!param.time) { + this.candle.style.color = 'transparent' + this.candle.innerHTML = this.candle.innerHTML.replace(options['upColor'], '').replace(options['downColor'], '') + return + } + let data = param.seriesData.get(chart.series); + this.candle.style.color = '' + let str = '' + if (data) { + if (this.ohlcEnabled) { + str += `O ${legendItemFormat(data.open, chart.precision)} ` + str += `| H ${legendItemFormat(data.high, chart.precision)} ` + str += `| L ${legendItemFormat(data.low, chart.precision)} ` + str += `| C ${legendItemFormat(data.close, chart.precision)} ` } - this.candle.innerHTML = finalString + '' - this.lines.forEach((line) => { - if (!param.seriesData.get(line.line.series)) return - let price = param.seriesData.get(line.line.series).value - if (line.line.type === 'histogram') { - price = shorthandFormat(price) + if (this.percentEnabled) { + let percentMove = ((data.close - data.open) / data.open) * 100 + let color = percentMove > 0 ? options['upColor'] : options['downColor'] + let percentStr = `${percentMove >= 0 ? '+' : ''}${percentMove.toFixed(2)} %` + + if (this.colorBasedOnCandle) { + str += `| ${percentStr}` } else { - price = legendItemFormat(price, line.line.precision) + str += '| ' + percentStr } - line.div.innerHTML = ` ${line.line.name} : ${price}` - }) - - } else { - this.candle.style.color = 'transparent' + } + let volumeData = param.seriesData.get(chart.volumeSeries) + if (volumeData) { + str += this.ohlcEnabled ? `
V ${shorthandFormat(volumeData.value)}` : '' + } } + this.candle.innerHTML = str + '
' + + this.lines.forEach((line) => { + if (!this.linesEnabled) { + line.row.style.display = 'none' + return + } + line.row.style.display = 'flex' + if (!param.seriesData.get(line.line.series)) return + let price = param.seriesData.get(line.line.series).value + + if (line.line.type === 'histogram') { + price = shorthandFormat(price) + } + else { + price = legendItemFormat(price, line.line.precision) + } + line.div.innerHTML = ` ${line.line.name} : ${price}` + }) + + }); } diff --git a/setup.py b/setup.py index 66b7ea9..9359e59 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ with open('README.md', 'r', encoding='utf-8') as f: setup( name='lightweight_charts', - version='1.0.18.6', + version='1.0.18.8', packages=find_packages(), python_requires='>=3.8', install_requires=[