NEW FEATURE: Trendlines, Rays and the Toolbox
- Added `trend_line` and `ray_line` to the Common Methods.
- Added the `toolbox` parameter to chart declaration. This allows horizontal lines, trend lines and rays to be drawn on the chart using hotkeys and buttons.
- cmd-Z will delete the last drawing.
- Drawings can be moved by clicking and dragging.
- Added the `render_drawings` parameter to `set`, which will keep and re-render the drawings displayed on the chart (useful for multiple timeframes!)
Horizontal Lines
- The `horizontal_line` method now returns a HorizontalLine object, containing the methods `update` and `delete`.
- Added the `interactive` parameter to `horizontal_line`, allowing for callbacks to be emitted to the `on_horizontal_line_move` callback method when the line is dragged to a new price (stop losses, limit orders, etc.).
Enhancements:
- added the `precision` method to the Common Methods, allowing for the number of decimal places shown on the price scale to be declared.
- Lines displayed on legends now have toggle switches, allowing for their visibility to be controlled directly within the chart window.
- when using `set`, the column names can now be capitalised, and the `date` column can be the index.
Changes:
- Merged the `title` method into the `price_line` method.
This commit is contained in:
@ -29,7 +29,7 @@ try:
|
||||
except ImportError:
|
||||
HTML = None
|
||||
|
||||
from lightweight_charts.abstract import LWC, TopBar, JS
|
||||
from lightweight_charts.abstract import LWC, JS
|
||||
|
||||
|
||||
def _widget_message(chart, string):
|
||||
@ -47,40 +47,41 @@ def _widget_message(chart, string):
|
||||
|
||||
class WxChart(LWC):
|
||||
def __init__(self, parent, volume_enabled: bool = True, inner_width: float = 1.0, inner_height: float = 1.0,
|
||||
scale_candles_only: bool = False, api: object = None, topbar: bool = False, searchbox: bool = False):
|
||||
scale_candles_only: bool = False, api: object = None, topbar: bool = False, searchbox: bool = False,
|
||||
toolbox: bool = False):
|
||||
if wx is None:
|
||||
raise ModuleNotFoundError('wx.html2 was not found, and must be installed to use WxChart.')
|
||||
self.webview: wx.html2.WebView = wx.html2.WebView.New(parent)
|
||||
|
||||
super().__init__(volume_enabled, inner_width=inner_width, inner_height=inner_height, scale_candles_only=scale_candles_only)
|
||||
super().__init__(volume_enabled, inner_width=inner_width, inner_height=inner_height,
|
||||
scale_candles_only=scale_candles_only, topbar=topbar, searchbox=searchbox, toolbox=toolbox,
|
||||
_js_api_code='window.wx_msg.postMessage.bind(window.wx_msg)')
|
||||
self.api = api
|
||||
self._script_func = self.webview.RunScript
|
||||
self._js_api_code = 'window.wx_msg.postMessage.bind(window.wx_msg)'
|
||||
|
||||
self.webview.Bind(wx.html2.EVT_WEBVIEW_LOADED, lambda e: wx.CallLater(500, self._on_js_load))
|
||||
self.webview.Bind(wx.html2.EVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, lambda e: _widget_message(self, e.GetString()))
|
||||
self.webview.AddScriptMessageHandler('wx_msg')
|
||||
self.webview.SetPage(self._html, '')
|
||||
|
||||
self.webview.AddUserScript(JS['callback'])
|
||||
self._create_chart()
|
||||
self.topbar = TopBar(self) if topbar else None
|
||||
self._make_search_box() if searchbox else None
|
||||
self.webview.AddUserScript(JS['callback']) if topbar or searchbox else None
|
||||
self.webview.AddUserScript(JS['toolbox']) if toolbox else None
|
||||
|
||||
def get_webview(self): return self.webview
|
||||
|
||||
|
||||
class QtChart(LWC):
|
||||
def __init__(self, widget=None, api: object = None, topbar: bool = False, searchbox: bool = False,
|
||||
volume_enabled: bool = True, inner_width: float = 1.0, inner_height: float = 1.0, scale_candles_only: bool = False):
|
||||
def __init__(self, widget=None, volume_enabled: bool = True, inner_width: float = 1.0, inner_height: float = 1.0,
|
||||
scale_candles_only: bool = False, api: object = None, topbar: bool = False, searchbox: bool = False,
|
||||
toolbox: bool = False):
|
||||
if QWebEngineView is None:
|
||||
raise ModuleNotFoundError('QWebEngineView was not found, and must be installed to use QtChart.')
|
||||
self.webview = QWebEngineView(widget)
|
||||
|
||||
super().__init__(volume_enabled, inner_width=inner_width, inner_height=inner_height, scale_candles_only=scale_candles_only)
|
||||
super().__init__(volume_enabled, inner_width=inner_width, inner_height=inner_height,
|
||||
scale_candles_only=scale_candles_only, topbar=topbar, searchbox=searchbox, toolbox=toolbox,
|
||||
_js_api_code='window.pythonObject.callback')
|
||||
self.api = api
|
||||
self._script_func = self.webview.page().runJavaScript
|
||||
self._js_api_code = 'window.pythonObject.callback'
|
||||
|
||||
self.web_channel = QWebChannel()
|
||||
self.bridge = Bridge(self)
|
||||
@ -100,17 +101,12 @@ class QtChart(LWC):
|
||||
'''
|
||||
self.webview.page().setHtml(self._html)
|
||||
|
||||
self.run_script(JS['callback'])
|
||||
self._create_chart()
|
||||
self.topbar = TopBar(self) if topbar else None
|
||||
self._make_search_box() if searchbox else None
|
||||
|
||||
def get_webview(self): return self.webview
|
||||
|
||||
|
||||
class StaticLWC(LWC):
|
||||
def __init__(self, volume_enabled=True, width=None, height=None, inner_width=1, inner_height=1, scale_candles_only: bool = False):
|
||||
super().__init__(volume_enabled, inner_width, inner_height, scale_candles_only=scale_candles_only)
|
||||
def __init__(self, volume_enabled=True, width=None, height=None, inner_width=1, inner_height=1, scale_candles_only: bool = False, toolbox=False, autosize=True):
|
||||
super().__init__(volume_enabled, inner_width, inner_height, scale_candles_only=scale_candles_only, toolbox=toolbox, autosize=autosize)
|
||||
self.width = width
|
||||
self.height = height
|
||||
self._html = self._html.replace('</script>\n</body>\n</html>', '')
|
||||
@ -133,9 +129,8 @@ class StaticLWC(LWC):
|
||||
|
||||
|
||||
class StreamlitChart(StaticLWC):
|
||||
def __init__(self, volume_enabled=True, width=None, height=None, inner_width=1, inner_height=1, scale_candles_only: bool = False):
|
||||
super().__init__(volume_enabled, width, height, inner_width, inner_height, scale_candles_only)
|
||||
self._create_chart()
|
||||
def __init__(self, volume_enabled=True, width=None, height=None, inner_width=1, inner_height=1, scale_candles_only: bool = False, toolbox: bool = False):
|
||||
super().__init__(volume_enabled, width, height, inner_width, inner_height, scale_candles_only, toolbox)
|
||||
|
||||
def _load(self):
|
||||
if html is None:
|
||||
@ -144,11 +139,10 @@ class StreamlitChart(StaticLWC):
|
||||
|
||||
|
||||
class JupyterChart(StaticLWC):
|
||||
def __init__(self, volume_enabled=True, width=800, height=350, inner_width=1, inner_height=1, scale_candles_only: bool = False):
|
||||
super().__init__(volume_enabled, width, height, inner_width, inner_height, scale_candles_only)
|
||||
def __init__(self, volume_enabled=True, width: int = 800, height=350, inner_width=1, inner_height=1, scale_candles_only: bool = False, toolbox: bool = False):
|
||||
super().__init__(volume_enabled, width, height, inner_width, inner_height, scale_candles_only, toolbox, autosize=False)
|
||||
self._position = ""
|
||||
|
||||
self._create_chart(autosize=False)
|
||||
self.run_script(f'''
|
||||
for (var i = 0; i < document.getElementsByClassName("tv-lightweight-charts").length; i++) {{
|
||||
var element = document.getElementsByClassName("tv-lightweight-charts")[i];
|
||||
|
||||
Reference in New Issue
Block a user