implement fill color option for boxes, start wx integration
This commit is contained in:
@ -7,7 +7,7 @@ import pandas as pd
|
||||
|
||||
from .table import Table
|
||||
from .toolbox import ToolBox
|
||||
from .drawings import HorizontalLine, TwoPointDrawing, VerticalSpan
|
||||
from .drawings import Box, HorizontalLine, TrendLine, TwoPointDrawing, VerticalSpan
|
||||
from .topbar import TopBar
|
||||
from .util import (
|
||||
Pane, Events, IDGen, as_enum, jbool, js_json, TIME, NUM, FLOAT,
|
||||
@ -45,9 +45,9 @@ class Window:
|
||||
return
|
||||
self.loaded = True
|
||||
|
||||
# TODO this wont work for anything which isnt pywebview :( put it in the chart class ?
|
||||
while not self.run_script_and_get('document.readyState == "complete"'):
|
||||
continue # scary, but works
|
||||
if hasattr(self, '_return_q'):
|
||||
while not self.run_script_and_get('document.readyState == "complete"'):
|
||||
continue # scary, but works
|
||||
|
||||
initial_script = ''
|
||||
self.scripts.extend(self.final_scripts)
|
||||
@ -283,13 +283,13 @@ class SeriesCommon(Pane):
|
||||
:return: The id of the marker placed.
|
||||
"""
|
||||
try:
|
||||
time = self._last_bar['time'] if not time else self._single_datetime_format(time)
|
||||
formatted_time = self._last_bar['time'] if not time else self._single_datetime_format(time)
|
||||
except TypeError:
|
||||
raise TypeError('Chart marker created before data was set.')
|
||||
marker_id = self.win._id_gen.generate()
|
||||
self.run_script(f"""
|
||||
{self.id}.markers.push({{
|
||||
time: {time if isinstance(time, float) else f"'{time}'"},
|
||||
time: {time if isinstance(formatted_time, float) else f"'{formatted_time}'"},
|
||||
position: '{marker_position(position)}',
|
||||
color: '{color}',
|
||||
shape: '{marker_shape(shape)}',
|
||||
@ -719,11 +719,11 @@ class AbstractChart(Candlestick, Pane):
|
||||
end_time: TIME,
|
||||
end_value: NUM,
|
||||
round: bool = False,
|
||||
color: str = '#1E80F0',
|
||||
line_color: str = '#1E80F0',
|
||||
width: int = 2,
|
||||
style: LINE_STYLE = 'solid',
|
||||
) -> TwoPointDrawing:
|
||||
return TwoPointDrawing("TrendLine", *locals().values())
|
||||
return TrendLine(*locals().values())
|
||||
|
||||
def box(
|
||||
self,
|
||||
@ -733,10 +733,11 @@ class AbstractChart(Candlestick, Pane):
|
||||
end_value: NUM,
|
||||
round: bool = False,
|
||||
color: str = '#1E80F0',
|
||||
fill_color: str = 'rgba(255, 255, 255, 0.2)',
|
||||
width: int = 2,
|
||||
style: LINE_STYLE = 'solid',
|
||||
) -> TwoPointDrawing:
|
||||
return TwoPointDrawing("Box", *locals().values())
|
||||
return Box(*locals().values())
|
||||
|
||||
def ray_line(
|
||||
self,
|
||||
|
||||
@ -6,11 +6,11 @@ from typing import Union, Optional
|
||||
|
||||
from lightweight_charts.util import js_json
|
||||
|
||||
from .util import NUM, Pane, as_enum, LINE_STYLE, TIME
|
||||
from .util import NUM, Pane, as_enum, LINE_STYLE, TIME, snake_to_camel
|
||||
|
||||
|
||||
class Drawing(Pane):
|
||||
def __init__(self, chart, color, width, style, func=None):
|
||||
def __init__(self, chart, func=None):
|
||||
super().__init__(chart.win)
|
||||
self.chart = chart
|
||||
|
||||
@ -34,13 +34,10 @@ class TwoPointDrawing(Drawing):
|
||||
end_time: TIME,
|
||||
end_value: NUM,
|
||||
round: bool,
|
||||
color,
|
||||
width,
|
||||
style,
|
||||
options: dict,
|
||||
func=None
|
||||
):
|
||||
super().__init__(chart, color, width, style, func)
|
||||
|
||||
super().__init__(chart, func)
|
||||
|
||||
def make_js_point(time, price):
|
||||
formatted_time = self.chart._single_datetime_format(time)
|
||||
@ -54,14 +51,14 @@ class TwoPointDrawing(Drawing):
|
||||
"price": {price}
|
||||
}}'''
|
||||
|
||||
options_string = '\n'.join(f'{key}: {val},' for key, val in options.items())
|
||||
|
||||
self.run_script(f'''
|
||||
{self.id} = new {drawing_type}(
|
||||
{make_js_point(start_time, start_value)},
|
||||
{make_js_point(end_time, end_value)},
|
||||
{{
|
||||
lineColor: '{color}',
|
||||
lineStyle: {as_enum(style, LINE_STYLE)},
|
||||
width: {width},
|
||||
{options_string}
|
||||
}}
|
||||
)
|
||||
{chart.id}.series.attachPrimitive({self.id})
|
||||
@ -70,7 +67,7 @@ class TwoPointDrawing(Drawing):
|
||||
|
||||
class HorizontalLine(Drawing):
|
||||
def __init__(self, chart, price, color, width, style, text, axis_label_visible, func):
|
||||
super().__init__(chart, color, width, style, func)
|
||||
super().__init__(chart, func)
|
||||
self.price = price
|
||||
self.run_script(f'''
|
||||
|
||||
@ -113,7 +110,7 @@ class HorizontalLine(Drawing):
|
||||
|
||||
class VerticalLine(Drawing):
|
||||
def __init__(self, chart, time, color, width, style, text, axis_label_visible, func):
|
||||
super().__init__(chart, color, width, style, func)
|
||||
super().__init__(chart, func)
|
||||
self.time = time
|
||||
self.run_script(f'''
|
||||
|
||||
@ -136,7 +133,68 @@ class VerticalLine(Drawing):
|
||||
def label(self, text: str): # TODO
|
||||
self.run_script(f'{self.id}.updateLabel("{text}")')
|
||||
|
||||
|
||||
|
||||
class Box(TwoPointDrawing):
|
||||
def __init__(self,
|
||||
chart,
|
||||
start_time: TIME,
|
||||
start_value: NUM,
|
||||
end_time: TIME,
|
||||
end_value: NUM,
|
||||
round: bool,
|
||||
line_color: str,
|
||||
fill_color: str,
|
||||
width: int,
|
||||
style: LINE_STYLE,
|
||||
func=None):
|
||||
|
||||
super().__init__(
|
||||
"Box",
|
||||
chart,
|
||||
start_time,
|
||||
start_value,
|
||||
end_time,
|
||||
end_value,
|
||||
round,
|
||||
{
|
||||
"lineColor": f'"{line_color}"',
|
||||
"fillColor": f'"{fill_color}"',
|
||||
"width": width,
|
||||
"lineStyle": as_enum(style, LINE_STYLE)
|
||||
},
|
||||
func
|
||||
)
|
||||
|
||||
|
||||
class TrendLine(TwoPointDrawing):
|
||||
def __init__(self,
|
||||
chart,
|
||||
start_time: TIME,
|
||||
start_value: NUM,
|
||||
end_time: TIME,
|
||||
end_value: NUM,
|
||||
round: bool,
|
||||
line_color: str,
|
||||
width: int,
|
||||
style: LINE_STYLE,
|
||||
func=None):
|
||||
|
||||
super().__init__(
|
||||
"TrendLine",
|
||||
chart,
|
||||
start_time,
|
||||
start_value,
|
||||
end_time,
|
||||
end_value,
|
||||
round,
|
||||
{
|
||||
"lineColor": f'"line_color"',
|
||||
"width": width,
|
||||
"lineStyle": as_enum(style, LINE_STYLE)
|
||||
},
|
||||
func
|
||||
)
|
||||
|
||||
class VerticalSpan(Pane):
|
||||
def __init__(self, series: 'SeriesCommon', start_time: Union[TIME, tuple, list], end_time: Optional[TIME] = None,
|
||||
color: str = 'rgba(252, 219, 3, 0.2)'):
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -247,7 +247,7 @@ class PolygonAPI:
|
||||
|
||||
df = await async_get_bar_data(ticker, timeframe, start_date, end_date, limit)
|
||||
|
||||
self._chart.set(df, render_drawings=_tickers.get(self._chart) == ticker)
|
||||
self._chart.set(df, keep_drawings=_tickers.get(self._chart) == ticker)
|
||||
_tickers[self._chart] = ticker
|
||||
|
||||
if not live:
|
||||
|
||||
@ -63,8 +63,8 @@ class WxChart(abstract.AbstractChart):
|
||||
self.webview.Bind(wx.html2.EVT_WEBVIEW_LOADED, lambda e: wx.CallLater(500, self.win.on_js_load))
|
||||
self.webview.Bind(wx.html2.EVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, lambda e: emit_callback(self, e.GetString()))
|
||||
self.webview.AddScriptMessageHandler('wx_msg')
|
||||
self.webview.SetPage(abstract.TEMPLATE, '')
|
||||
self.webview.AddUserScript(abstract.JS['toolbox']) if toolbox else None
|
||||
self.webview.LoadURL(f'file:///{abstract.INDEX}')
|
||||
# self.webview.AddUserScript(abstract.JS['toolbox']) if toolbox else None
|
||||
|
||||
def get_webview(self): return self.webview
|
||||
|
||||
|
||||
Reference in New Issue
Block a user