subscribeClick
Description
Need to get the value and time of the series from the point of click, for further calculation purpose in the strategy
Code example
No response
Method of implementation
No response
Hey, this has been posted previously somewhere around here and I used it since then.
def subscribe_click(chart, *, callback):
js = (
'function clickHandler(param) {'
'if (!param.point) {'
'return;'
'}'
f'const time = {chart.id}.chart.timeScale().coordinateToTime(param.point.x);'
f'const price = {chart.id}.series.coordinateToPrice(param.point.y);'
'const data = JSON.stringify({time: time, price: price});'
'window.callbackFunction(`on_click_~_${data}`);'
'}'
f'{chart.id}.chart.subscribeClick(clickHandler);'
)
def decorated_callback(data):
data = json.loads(data)
data = {
'timestamp': pd.to_datetime(data['time'], unit='s'),
'price': data['price'],
}
return callback(data, chart, chart.candle_data)
chart.win.handlers['on_click'] = decorated_callback
chart.win.run_script(js)
def on_chart_click(data, chart, candle_data): print(data['timestamp'])
subscribe_click(chart, callback=on_chart_click)
hey @emma-uw any idea on how to exit that callback state ? once i trigger the function using a topbar switcher state, the click feed keep giving information on clicks, even if i change that switcher's state
@Iss-in Hey. Hard to tell what you meant without looking into the implementation. But there is a new built-in function in version 2.0. Maybe it will work better for you?
def on_chart_click(chart, timestamp, price):
print(chart, timestamp, price)
chart.events.click += on_chart_click
@emma-uw can you please explain how this works , with some working example if possible?
simply using that code , and clicking on graph doesnt do anything
actually scratch that, here is my implementation for a replay of graph
chart.topbar.switcher('click', ('c1', 'c2'), default='c1',
func=on_click)
def on_chart_click(chart, timestamp, price):
print(chart, timestamp, price)
dt_object = datetime.fromtimestamp(timestamp, tz=timezone.utc)
dt_string = dt_object.strftime('%Y-%m-%d %H:%M:%S')
print("Datetime string:", dt_string)
ind = df[df['date'] == dt_string].index.tolist()[0]
print(f"index to start replay is {ind} with timestamp {timestamp}")
for i in range(ind,len(df.index)):
df2 = df.head(i)
time.sleep(2)
chart.set(df2)
state = chart.topbar['click'].value
if state == 'c1':
break
print(state)
def on_click(chart):
state = chart.topbar['click'].value
if state == 'c2':
print(f"start click")
chart.events.click += on_chart_click
if i select state c2, and then click on graph, replay happens, but when change state back to c1, it doesnt stop is there a way to accomplish this
@Iss-in That's because replay is running synchronously, so until your loop isn't done - any other execution is blocked. You will need your replay function to run separately. Something like this.
from datetime import datetime, timezone
from lightweight_charts import Chart
import pandas as pd
import asyncio
async def start_replay(replay_data):
for i in range(replay_data.index[0], replay_data.index[-1]):
df2 = df.head(i)
await asyncio.sleep(2)
chart.set(df2)
state = chart.topbar['click'].value
if state == 'c1':
break
print(state)
def on_chart_click(chart, timestamp, price):
state = chart.topbar['click'].value
if state == 'c2':
print(chart, timestamp, price)
dt_object = datetime.fromtimestamp(timestamp, tz=timezone.utc)
dt_string = dt_object.strftime('%Y-%m-%d %H:%M:%S')
candle_data = chart.candle_data
print("Datetime string:", dt_string)
replay_data = candle_data[candle_data['time'] > timestamp]
print(f"index to start replay is {replay_data.index[0]} with timestamp {timestamp}")
asyncio.create_task(start_replay(replay_data))
def on_click(chart):
state = chart.topbar['click'].value
print(state)
if __name__ == '__main__':
chart = Chart()
chart.topbar.switcher('click', ('c1', 'c2'), default='c1', func=on_click)
chart.events.click += on_chart_click
df = pd.read_csv('ohlcv.csv')
chart.set(df)
chart.show(block=True)
thanks a lot, this helped :)