implement toggleable buttons; menu items can now be changed; add horizontal line and vertical line labels
This commit is contained in:
@ -8,7 +8,7 @@ import pandas as pd
|
||||
|
||||
from .table import Table
|
||||
from .toolbox import ToolBox
|
||||
from .drawings import Box, HorizontalLine, TrendLine, TwoPointDrawing, VerticalSpan
|
||||
from .drawings import Box, HorizontalLine, TrendLine, TwoPointDrawing, VerticalLine, VerticalSpan
|
||||
from .topbar import TopBar
|
||||
from .util import (
|
||||
BulkRunScript, Pane, Events, IDGen, as_enum, jbool, js_json, TIME, NUM, FLOAT,
|
||||
@ -728,10 +728,20 @@ class AbstractChart(Candlestick, Pane):
|
||||
width: int = 2,
|
||||
style: LINE_STYLE = 'solid'
|
||||
) -> Line:
|
||||
line = Line(self, '', color, style, width, False, False, False)
|
||||
line._set_trend(start_time, value, start_time, value, ray=True, round=round)
|
||||
# TODO
|
||||
line = RayLine(self, '', color, style, width, False, False, False)
|
||||
return line
|
||||
|
||||
def vertical_line(
|
||||
self,
|
||||
time: TIME,
|
||||
color: str = '#1E80F0',
|
||||
width: int = 2,
|
||||
style: LINE_STYLE ='solid',
|
||||
text: str = ''
|
||||
) -> VerticalLine:
|
||||
return VerticalLine(*locals().values())
|
||||
|
||||
def set_visible_range(self, start_time: TIME, end_time: TIME):
|
||||
self.run_script(f'''
|
||||
{self.id}.chart.timeScale().setVisibleRange({{
|
||||
|
||||
@ -24,6 +24,13 @@ class Drawing(Pane):
|
||||
"""
|
||||
self.run_script(f'{self.id}.detach()')
|
||||
|
||||
def options(self, color='#1E80F0', style='solid', width=4):
|
||||
self.run_script(f'''{self.id}.applyOptions({{
|
||||
lineColor: '{color}',
|
||||
lineStyle: {as_enum(style, LINE_STYLE)},
|
||||
width: {width},
|
||||
}})''')
|
||||
|
||||
class TwoPointDrawing(Drawing):
|
||||
def __init__(
|
||||
self,
|
||||
@ -76,6 +83,8 @@ class HorizontalLine(Drawing):
|
||||
{{
|
||||
lineColor: '{color}',
|
||||
lineStyle: {as_enum(style, LINE_STYLE)},
|
||||
width: {width},
|
||||
text: `{text}`,
|
||||
}},
|
||||
callbackName={f"'{self.id}'" if func else 'null'}
|
||||
)
|
||||
@ -103,22 +112,25 @@ class HorizontalLine(Drawing):
|
||||
# self.run_script(f'{self.id}.updatePrice({price})')
|
||||
self.price = price
|
||||
|
||||
def label(self, text: str): # TODO
|
||||
self.run_script(f'{self.id}.updateLabel("{text}")')
|
||||
def options(self, color='#1E80F0', style='solid', width=4, text=''):
|
||||
super().options(color, style, width)
|
||||
self.run_script(f'{self.id}.applyOptions({{text: `{text}`}})')
|
||||
|
||||
|
||||
|
||||
class VerticalLine(Drawing):
|
||||
def __init__(self, chart, time, color, width, style, text, axis_label_visible, func):
|
||||
def __init__(self, chart, time, color, width, style, text, func=None):
|
||||
super().__init__(chart, func)
|
||||
self.time = time
|
||||
self.run_script(f'''
|
||||
|
||||
{self.id} = new Lib.VerticalLine(
|
||||
{{time: {time}}},
|
||||
{{time: {self.chart._single_datetime_format(time)}}},
|
||||
{{
|
||||
lineColor: '{color}',
|
||||
lineStyle: {as_enum(style, LINE_STYLE)},
|
||||
width: {width},
|
||||
text: `{text}`,
|
||||
}},
|
||||
callbackName={f"'{self.id}'" if func else 'null'}
|
||||
)
|
||||
@ -130,8 +142,9 @@ class VerticalLine(Drawing):
|
||||
# self.run_script(f'{self.id}.updatePrice({price})')
|
||||
self.price = price
|
||||
|
||||
def label(self, text: str): # TODO
|
||||
self.run_script(f'{self.id}.updateLabel("{text}")')
|
||||
def options(self, color='#1E80F0', style='solid', width=4, text=''):
|
||||
super().options(color, style, width)
|
||||
self.run_script(f'{self.id}.applyOptions({{text: `{text}`}})')
|
||||
|
||||
|
||||
class Box(TwoPointDrawing):
|
||||
@ -188,13 +201,14 @@ class TrendLine(TwoPointDrawing):
|
||||
end_value,
|
||||
round,
|
||||
{
|
||||
"lineColor": f'"line_color"',
|
||||
"lineColor": f'"{line_color}"',
|
||||
"width": width,
|
||||
"lineStyle": as_enum(style, LINE_STYLE)
|
||||
},
|
||||
func
|
||||
)
|
||||
|
||||
# TODO reimplement/fix
|
||||
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
@ -8,12 +8,15 @@ ALIGN = Literal['left', 'right']
|
||||
|
||||
|
||||
class Widget(Pane):
|
||||
def __init__(self, topbar, value, func: callable = None):
|
||||
def __init__(self, topbar, value, func: callable = None, convert_boolean=False):
|
||||
super().__init__(topbar.win)
|
||||
self.value = value
|
||||
|
||||
def wrapper(v):
|
||||
self.value = v
|
||||
if convert_boolean:
|
||||
self.value = False if v == 'false' else True
|
||||
else:
|
||||
self.value = v
|
||||
func(topbar._chart)
|
||||
|
||||
async def async_wrapper(v):
|
||||
@ -54,6 +57,7 @@ class MenuWidget(Widget):
|
||||
{self.id} = {topbar.id}.makeMenu({list(options)}, "{default}", {jbool(separator)}, "{self.id}", "{align}")
|
||||
''')
|
||||
|
||||
# TODO this will probably need to be fixed
|
||||
def set(self, option):
|
||||
if option not in self.options:
|
||||
raise ValueError(f"Option {option} not in menu options ({self.options})")
|
||||
@ -63,15 +67,19 @@ class MenuWidget(Widget):
|
||||
''')
|
||||
self.win.handlers[self.id](option)
|
||||
|
||||
def update_items(self, *items: str):
|
||||
self.options = list(items)
|
||||
self.run_script(f'{self.id}.updateMenuItems({self.options})')
|
||||
|
||||
|
||||
class ButtonWidget(Widget):
|
||||
def __init__(self, topbar, button, separator, align, func):
|
||||
super().__init__(topbar, value=button, func=func)
|
||||
def __init__(self, topbar, button, separator, align, toggle, func):
|
||||
super().__init__(topbar, value=False, func=func, convert_boolean=toggle)
|
||||
self.run_script(
|
||||
f'{self.id} = {topbar.id}.makeButton("{button}", "{self.id}", {jbool(separator)}, true, "{align}")')
|
||||
f'{self.id} = {topbar.id}.makeButton("{button}", "{self.id}", {jbool(separator)}, true, "{align}", {jbool(toggle)})')
|
||||
|
||||
def set(self, string):
|
||||
self.value = string
|
||||
# self.value = string
|
||||
self.run_script(f'{self.id}.elem.innerText = "{string}"')
|
||||
|
||||
|
||||
@ -112,6 +120,6 @@ class TopBar(Pane):
|
||||
self._widgets[name] = TextWidget(self, initial_text, align)
|
||||
|
||||
def button(self, name, button_text: str, separator: bool = True,
|
||||
align: ALIGN = 'left', func: callable = None):
|
||||
align: ALIGN = 'left', toggle: bool = False, func: callable = None):
|
||||
self._create()
|
||||
self._widgets[name] = ButtonWidget(self, button_text, separator, align, func)
|
||||
self._widgets[name] = ButtonWidget(self, button_text, separator, align, toggle, func)
|
||||
|
||||
Reference in New Issue
Block a user