Enhancements:
- Added the `title` parameter to `Chart`. Bug Fixes: - When passing a timestamp format to `set`, `update`, or `update_from_tick`, the unit is now by default milliseconds rather than nanoseconds. - When using `update`, if a time is passed that occurs before the current last datapoint, an error will be raised.
This commit is contained in:
@ -6,7 +6,7 @@ They inherit from [AbstractChart](#AbstractChart).
|
|||||||
|
|
||||||
___
|
___
|
||||||
|
|
||||||
`````{py:class} Chart(width: int, height: int, x: int, y: int, screen: int, on_top: bool, maximize: bool, debug: bool, toolbox: bool, inner_width: float, inner_height: float, scale_candles_only: bool)
|
`````{py:class} Chart(width: int, height: int, x: int, y: int, title: str, screen: int, on_top: bool, maximize: bool, debug: bool, toolbox: bool, inner_width: float, inner_height: float, scale_candles_only: bool)
|
||||||
|
|
||||||
The main object used for the normal functionality of lightweight-charts-python, built on the pywebview library.
|
The main object used for the normal functionality of lightweight-charts-python, built on the pywebview library.
|
||||||
|
|
||||||
|
|||||||
@ -210,7 +210,7 @@ class SeriesCommon(Pane):
|
|||||||
|
|
||||||
def _single_datetime_format(self, arg):
|
def _single_datetime_format(self, arg):
|
||||||
if isinstance(arg, (str, int, float)) or not pd.api.types.is_datetime64_any_dtype(arg):
|
if isinstance(arg, (str, int, float)) or not pd.api.types.is_datetime64_any_dtype(arg):
|
||||||
arg = pd.to_datetime(arg)
|
arg = pd.to_datetime(arg, unit='ms')
|
||||||
arg = self._interval * (arg.timestamp() // self._interval)+self.offset
|
arg = self._interval * (arg.timestamp() // self._interval)+self.offset
|
||||||
return arg
|
return arg
|
||||||
|
|
||||||
@ -620,6 +620,11 @@ class Candlestick(SeriesCommon):
|
|||||||
:param cumulative_volume: Adds the given volume onto the latest bar.
|
:param cumulative_volume: Adds the given volume onto the latest bar.
|
||||||
"""
|
"""
|
||||||
series = self._series_datetime_format(series)
|
series = self._series_datetime_format(series)
|
||||||
|
if series['time'] < self._last_bar['time']:
|
||||||
|
raise ValueError(
|
||||||
|
f'Trying to update tick of time "{pd.to_datetime(series["time"])}", '
|
||||||
|
f'which occurs before the last bar time of '
|
||||||
|
f'"{pd.to_datetime(self._last_bar["time"])}".')
|
||||||
bar = pd.Series()
|
bar = pd.Series()
|
||||||
if series['time'] == self._last_bar['time']:
|
if series['time'] == self._last_bar['time']:
|
||||||
bar = self._last_bar
|
bar = self._last_bar
|
||||||
|
|||||||
@ -16,7 +16,7 @@ class CallbackAPI:
|
|||||||
|
|
||||||
class PyWV:
|
class PyWV:
|
||||||
def __init__(self, q, start_ev, exit_ev, loaded, emit_queue, return_queue, html, debug,
|
def __init__(self, q, start_ev, exit_ev, loaded, emit_queue, return_queue, html, debug,
|
||||||
width, height, x, y, screen, on_top, maximize):
|
width, height, x, y, screen, on_top, maximize, title):
|
||||||
self.queue = q
|
self.queue = q
|
||||||
self.return_queue = return_queue
|
self.return_queue = return_queue
|
||||||
self.exit = exit_ev
|
self.exit = exit_ev
|
||||||
@ -25,13 +25,13 @@ class PyWV:
|
|||||||
self.html = html
|
self.html = html
|
||||||
|
|
||||||
self.windows = []
|
self.windows = []
|
||||||
self.create_window(width, height, x, y, screen, on_top, maximize)
|
self.create_window(width, height, x, y, screen, on_top, maximize, title)
|
||||||
|
|
||||||
start_ev.wait()
|
start_ev.wait()
|
||||||
webview.start(debug=debug)
|
webview.start(debug=debug)
|
||||||
self.exit.set()
|
self.exit.set()
|
||||||
|
|
||||||
def create_window(self, width, height, x, y, screen=None, on_top=False, maximize=False):
|
def create_window(self, width, height, x, y, screen=None, on_top=False, maximize=False, title=''):
|
||||||
screen = webview.screens[screen] if screen is not None else None
|
screen = webview.screens[screen] if screen is not None else None
|
||||||
if maximize:
|
if maximize:
|
||||||
if screen is None:
|
if screen is None:
|
||||||
@ -40,7 +40,7 @@ class PyWV:
|
|||||||
else:
|
else:
|
||||||
width, height = screen.width, screen.height
|
width, height = screen.width, screen.height
|
||||||
self.windows.append(webview.create_window(
|
self.windows.append(webview.create_window(
|
||||||
'', html=self.html, js_api=self.callback_api,
|
title, html=self.html, js_api=self.callback_api,
|
||||||
width=width, height=height, x=x, y=y, screen=screen,
|
width=width, height=height, x=x, y=y, screen=screen,
|
||||||
on_top=on_top, background_color='#000000'))
|
on_top=on_top, background_color='#000000'))
|
||||||
self.windows[-1].events.loaded += lambda: self.loop(self.loaded[len(self.windows)-1])
|
self.windows[-1].events.loaded += lambda: self.loop(self.loaded[len(self.windows)-1])
|
||||||
@ -73,9 +73,10 @@ class Chart(abstract.AbstractChart):
|
|||||||
_q, _emit_q, _return_q = (mp.Queue() for _ in range(3))
|
_q, _emit_q, _return_q = (mp.Queue() for _ in range(3))
|
||||||
_loaded_list = [mp.Event() for _ in range(MAX_WINDOWS)]
|
_loaded_list = [mp.Event() for _ in range(MAX_WINDOWS)]
|
||||||
|
|
||||||
def __init__(self, width: int = 800, height: int = 600, x: int = None, y: int = None, screen: int = None,
|
def __init__(self, width: int = 800, height: int = 600, x: int = None, y: int = None, title: str = '',
|
||||||
on_top: bool = False, maximize: bool = False, debug: bool = False, toolbox: bool = False,
|
screen: int = None, on_top: bool = False, maximize: bool = False, debug: bool = False,
|
||||||
inner_width: float = 1.0, inner_height: float = 1.0, scale_candles_only: bool = False):
|
toolbox: bool = False, inner_width: float = 1.0, inner_height: float = 1.0,
|
||||||
|
scale_candles_only: bool = False):
|
||||||
self._i = Chart._window_num
|
self._i = Chart._window_num
|
||||||
self._loaded = Chart._loaded_list[self._i]
|
self._loaded = Chart._loaded_list[self._i]
|
||||||
abstract.Window._return_q = Chart._return_q
|
abstract.Window._return_q = Chart._return_q
|
||||||
@ -89,13 +90,13 @@ class Chart(abstract.AbstractChart):
|
|||||||
self._process = mp.Process(target=PyWV, args=(
|
self._process = mp.Process(target=PyWV, args=(
|
||||||
self._q, self._start, self._exit, Chart._loaded_list,
|
self._q, self._start, self._exit, Chart._loaded_list,
|
||||||
self._emit_q, self._return_q, abstract.TEMPLATE, debug,
|
self._emit_q, self._return_q, abstract.TEMPLATE, debug,
|
||||||
width, height, x, y, screen, on_top, maximize,
|
width, height, x, y, screen, on_top, maximize, title
|
||||||
), daemon=True)
|
), daemon=True)
|
||||||
self._process.start()
|
self._process.start()
|
||||||
else:
|
else:
|
||||||
window.handlers = Chart._main_window_handlers
|
window.handlers = Chart._main_window_handlers
|
||||||
super().__init__(window, inner_width, inner_height, scale_candles_only, toolbox)
|
super().__init__(window, inner_width, inner_height, scale_candles_only, toolbox)
|
||||||
self._q.put(('create_window', (width, height, x, y, screen, on_top, maximize)))
|
self._q.put(('create_window', (width, height, x, y, screen, on_top, maximize, title)))
|
||||||
|
|
||||||
def show(self, block: bool = False):
|
def show(self, block: bool = False):
|
||||||
"""
|
"""
|
||||||
|
|||||||
2
setup.py
2
setup.py
@ -5,7 +5,7 @@ with open('README.md', 'r', encoding='utf-8') as f:
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='lightweight_charts',
|
name='lightweight_charts',
|
||||||
version='1.0.18.5',
|
version='1.0.18.6',
|
||||||
packages=find_packages(),
|
packages=find_packages(),
|
||||||
python_requires='>=3.8',
|
python_requires='>=3.8',
|
||||||
install_requires=[
|
install_requires=[
|
||||||
|
|||||||
Reference in New Issue
Block a user