From cd5059efe6ca6844f423fd8bc85e959cf05a8abe Mon Sep 17 00:00:00 2001 From: gokulchittaranjan Date: Fri, 24 May 2024 00:24:26 +0530 Subject: [PATCH 1/4] add mouse move and click events on charts to utils.py --- lightweight_charts/util.py | 53 +++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/lightweight_charts/util.py b/lightweight_charts/util.py index ef3583c..a5baa78 100644 --- a/lightweight_charts/util.py +++ b/lightweight_charts/util.py @@ -149,5 +149,56 @@ def __init__(self, chart): '''), wrapper=lambda o, c, *arg: o(c, *[float(a) for a in arg]) ) - + self.mouse_move = JSEmitter(chart, f'mouse_move{chart.id}', + lambda o: chart.run_script(f''' + let checkMouseMove = (param) => {{ + {chart.id}.chart.unsubscribeCrosshairMove(checkMouseMove) + if ( + param.point === undefined || + !param.time || + param.point.x < 0 || + param.point.y < 0 + ) {{ + window.callbackFunction(`mouse_move{chart.id}_~_${{0}};;;${{0}};;;${{0}};;;${{0}};;;${{0}};;;${{0}}`) + }} else {{ + let x = param.point.x; + let dateStr = param.time; + let data = param.seriesData.get({chart.id}.series); + let open = data.open; + let high = data.high; + let low = data.low; + let close = data.close; + window.callbackFunction(`mouse_move{chart.id}_~_${{x}};;;${{dateStr}};;;${{open}};;;${{high}};;;${{low}};;;${{close}}`) + }} + setTimeout(() => {chart.id}.chart.subscribeCrosshairMove(checkMouseMove), 50) + }} + {chart.id}.chart.subscribeCrosshairMove(checkMouseMove) + '''), + wrapper=lambda o, c, *arg: o(c, *[float(a) for a in arg])) + self.click = JSEmitter(chart, f'click{chart.id}', + lambda o: chart.run_script(f''' + let checkClick = (param) => {{ + {chart.id}.chart.unsubscribeClick(checkClick) + if ( + param.point === undefined || + !param.time || + param.point.x < 0 || + param.point.y < 0 + ) {{ + window.callbackFunction(`click{chart.id}_~_${{0}};;;${{0}};;;${{0}};;;${{0}};;;${{0}};;;${{0}}`) + }} else {{ + let x = param.point.x; + let dateStr = param.time; + let data = param.seriesData.get({chart.id}.series); + let open = data.open; + let high = data.high; + let low = data.low; + let close = data.close; + window.callbackFunction(`click{chart.id}_~_${{x}};;;${{dateStr}};;;${{open}};;;${{high}};;;${{low}};;;${{close}}`) + }} + setTimeout(() => {chart.id}.chart.subscribeClick(checkClick), 50) + }} + {chart.id}.chart.subscribeClick(checkClick) + '''), + wrapper=lambda o, c, *arg: o(c, *[float(a) for a in arg])) From f163f8b51a4da9f8a121a05ba7816d868d3a7030 Mon Sep 17 00:00:00 2001 From: gokulchittaranjan Date: Thu, 13 Jun 2024 14:59:06 +0530 Subject: [PATCH 2/4] Util updated --- lightweight_charts/util.py | 52 ++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/lightweight_charts/util.py b/lightweight_charts/util.py index a5baa78..343b929 100644 --- a/lightweight_charts/util.py +++ b/lightweight_charts/util.py @@ -135,21 +135,22 @@ def __init__(self, chart): {chart.id}.search = makeSearchBox({chart.id}) ''') ) - self.range_change = JSEmitter(chart, f'range_change{chart.id}', + salt = chart.id[chart.id.index('.')+1:] + self.range_change = JSEmitter(chart, f'range_change{salt}', lambda o: chart.run_script(f''' - let checkLogicalRange = (logical) => {{ - {chart.id}.chart.timeScale().unsubscribeVisibleLogicalRangeChange(checkLogicalRange) + let checkLogicalRange{salt} = (logical) => {{ + {chart.id}.chart.timeScale().unsubscribeVisibleLogicalRangeChange(checkLogicalRange{salt}) let barsInfo = {chart.id}.series.barsInLogicalRange(logical) - if (barsInfo) window.callbackFunction(`range_change{chart.id}_~_${{barsInfo.barsBefore}};;;${{barsInfo.barsAfter}}`) + if (barsInfo) window.callbackFunction(`range_change{salt}_~_${{barsInfo.barsBefore}};;;${{barsInfo.barsAfter}}`) - setTimeout(() => {chart.id}.chart.timeScale().subscribeVisibleLogicalRangeChange(checkLogicalRange), 50) + setTimeout(() => {chart.id}.chart.timeScale().subscribeVisibleLogicalRangeChange(checkLogicalRange{salt}), 50) }} - {chart.id}.chart.timeScale().subscribeVisibleLogicalRangeChange(checkLogicalRange) + {chart.id}.chart.timeScale().subscribeVisibleLogicalRangeChange(checkLogicalRange{salt}) '''), wrapper=lambda o, c, *arg: o(c, *[float(a) for a in arg]) ) - self.mouse_move = JSEmitter(chart, f'mouse_move{chart.id}', + self.mouse_move = JSEmitter(chart, f'mouse_move{salt}', lambda o: chart.run_script(f''' let checkMouseMove = (param) => {{ {chart.id}.chart.unsubscribeCrosshairMove(checkMouseMove) @@ -159,7 +160,7 @@ def __init__(self, chart): param.point.x < 0 || param.point.y < 0 ) {{ - window.callbackFunction(`mouse_move{chart.id}_~_${{0}};;;${{0}};;;${{0}};;;${{0}};;;${{0}};;;${{0}}`) + window.callbackFunction(`mouse_move{salt}_~_${{0}};;;${{0}};;;${{0}};;;${{0}};;;${{0}};;;${{0}}`) }} else {{ let x = param.point.x; let dateStr = param.time; @@ -170,22 +171,22 @@ def __init__(self, chart): let close = data.close; window.callbackFunction(`mouse_move{chart.id}_~_${{x}};;;${{dateStr}};;;${{open}};;;${{high}};;;${{low}};;;${{close}}`) }} - setTimeout(() => {chart.id}.chart.subscribeCrosshairMove(checkMouseMove), 50) + setTimeout(() => {chart.id}.chart.subscribeCrosshairMove(checkMouseMove{salt}), 50) }} - {chart.id}.chart.subscribeCrosshairMove(checkMouseMove) + {chart.id}.chart.subscribeCrosshairMove(checkMouseMove{salt}) '''), wrapper=lambda o, c, *arg: o(c, *[float(a) for a in arg])) - self.click = JSEmitter(chart, f'click{chart.id}', + self.click = JSEmitter(chart, f'click{salt}', lambda o: chart.run_script(f''' let checkClick = (param) => {{ - {chart.id}.chart.unsubscribeClick(checkClick) + {salt}.chart.unsubscribeClick(checkClick) if ( param.point === undefined || !param.time || param.point.x < 0 || param.point.y < 0 ) {{ - window.callbackFunction(`click{chart.id}_~_${{0}};;;${{0}};;;${{0}};;;${{0}};;;${{0}};;;${{0}}`) + window.callbackFunction(`click{salt}_~_${{0}};;;${{0}};;;${{0}};;;${{0}};;;${{0}};;;${{0}}`) }} else {{ let x = param.point.x; let dateStr = param.time; @@ -194,11 +195,30 @@ def __init__(self, chart): let high = data.high; let low = data.low; let close = data.close; - window.callbackFunction(`click{chart.id}_~_${{x}};;;${{dateStr}};;;${{open}};;;${{high}};;;${{low}};;;${{close}}`) + let y = param.point.y + let price = {chart.id}.series.coordinateToPrice(param.point.y); + window.callbackFunction(`click{salt}_~_${{x}};;;${{dateStr}};;;${{open}};;;${{high}};;;${{low}};;;${{close}};;;${{y}};;;${{price}}`) }} - setTimeout(() => {chart.id}.chart.subscribeClick(checkClick), 50) + setTimeout(() => {chart.id}.chart.subscribeClick(checkClick{salt}), 50) }} - {chart.id}.chart.subscribeClick(checkClick) + {chart.id}.chart.subscribeClick(checkClick{salt}) '''), wrapper=lambda o, c, *arg: o(c, *[float(a) for a in arg])) + +class BulkRunScript: + def __init__(self, script_func): + self.enabled = False + self.scripts = [] + self.script_func = script_func + + def __enter__(self): + self.enabled = True + + def __exit__(self, *args): + self.enabled = False + self.script_func('\n'.join(self.scripts)) + self.scripts = [] + + def add_script(self, script): + self.scripts.append(script) From add0a98becbfec668195888bb4fc9312491209f1 Mon Sep 17 00:00:00 2001 From: gokulchittaranjan Date: Thu, 13 Jun 2024 15:06:27 +0530 Subject: [PATCH 3/4] minor fix --- lightweight_charts/util.py | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/lightweight_charts/util.py b/lightweight_charts/util.py index e09181a..0f7bb75 100644 --- a/lightweight_charts/util.py +++ b/lightweight_charts/util.py @@ -187,8 +187,8 @@ def __init__(self, chart): wrapper=lambda o, c, *arg: o(c, *[float(a) for a in arg])) self.click = JSEmitter(chart, f'click{salt}', lambda o: chart.run_script(f''' - let checkClick = (param) => {{ - {salt}.chart.unsubscribeClick(checkClick) + let checkClick{salt} = (param) => {{ + {chart.id}.chart.unsubscribeClick(checkClick) if ( param.point === undefined || !param.time || @@ -214,19 +214,6 @@ def __init__(self, chart): '''), wrapper=lambda o, c, *arg: o(c, *[float(a) for a in arg])) - self.click = JSEmitter(chart, f'subscribe_click{salt}', - lambda o: chart.run_script(f''' - let clickHandler{salt} = (param) => {{ - if (!param.point) return; - const time = {chart.id}.chart.timeScale().coordinateToTime(param.point.x) - const price = {chart.id}.series.coordinateToPrice(param.point.y); - window.callbackFunction(`subscribe_click{salt}_~_${{time}};;;${{price}}`) - }} - {chart.id}.chart.subscribeClick(clickHandler{salt}) - '''), - wrapper=lambda func, c, *args: func(c, *[float(a) for a in args]) - ) - class BulkRunScript: def __init__(self, script_func): self.enabled = False From 9e8a93391e8e136c7a7978835b846e9d63acc030 Mon Sep 17 00:00:00 2001 From: gokulchittaranjan Date: Thu, 13 Jun 2024 15:09:46 +0530 Subject: [PATCH 4/4] minor fix --- lightweight_charts/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lightweight_charts/util.py b/lightweight_charts/util.py index 0f7bb75..69fb5ca 100644 --- a/lightweight_charts/util.py +++ b/lightweight_charts/util.py @@ -188,7 +188,7 @@ def __init__(self, chart): self.click = JSEmitter(chart, f'click{salt}', lambda o: chart.run_script(f''' let checkClick{salt} = (param) => {{ - {chart.id}.chart.unsubscribeClick(checkClick) + {chart.id}.chart.unsubscribeClick(checkClick{salt}) if ( param.point === undefined || !param.time ||