Enhancements:
- added the `create_histogram` method and the `Histogram` object. - added the `round` parameter to `trend_line` and `ray_line` - chart.set can now be given line data. Bug Fixes: - `NaN` values can now be given when setting data, and will leave a blank space in the data. - `resize` will now change the chart wrapper’s size as well as the chart itself.
This commit is contained in:
@ -59,7 +59,19 @@ ___
|
|||||||
|
|
||||||
Creates and returns a Line object, representing a `LineSeries` object in Lightweight Charts and can be used to create indicators. As well as the methods described below, the `Line` object also has access to:
|
Creates and returns a Line object, representing a `LineSeries` object in Lightweight Charts and can be used to create indicators. As well as the methods described below, the `Line` object also has access to:
|
||||||
|
|
||||||
[`marker`](#marker), [`horizontal_line`](#AbstractChart.horizontal_line) [`hide_data`](#hide_data), [`show_data`](#show_data) and[`price_line`](#price_line).
|
[`marker`](#marker), [`horizontal_line`](#AbstractChart.horizontal_line), [`hide_data`](#hide_data), [`show_data`](#show_data) and [`price_line`](#price_line).
|
||||||
|
|
||||||
|
Its instance should only be accessed from this method.
|
||||||
|
```
|
||||||
|
___
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```{py:method} create_histogram(name: str, color: COLOR, price_line: bool, price_label: bool, scale_margin_top: float, scale_margin_bottom: float) -> Histogram
|
||||||
|
|
||||||
|
Creates and returns a Histogram object, representing a `HistogramSeries` object in Lightweight Charts and can be used to create indicators. As well as the methods described below, the object also has access to:
|
||||||
|
|
||||||
|
[`horizontal_line`](#AbstractChart.horizontal_line), [`hide_data`](#hide_data), [`show_data`](#show_data) and [`price_line`](#price_line).
|
||||||
|
|
||||||
Its instance should only be accessed from this method.
|
Its instance should only be accessed from this method.
|
||||||
```
|
```
|
||||||
@ -76,7 +88,7 @@ ___
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
```{py:method} trend_line(start_time: str | datetime, start_value: NUM, end_time: str | datetime, end_value: NUM, color: COLOR, width: int, style: LINE_STYLE) -> Line
|
```{py:method} trend_line(start_time: str | datetime, start_value: NUM, end_time: str | datetime, end_value: NUM, color: COLOR, width: int, style: LINE_STYLE, round: bool) -> Line
|
||||||
|
|
||||||
Creates a trend line, drawn from the first point (`start_time`, `start_value`) to the last point (`end_time`, `end_value`).
|
Creates a trend line, drawn from the first point (`start_time`, `start_value`) to the last point (`end_time`, `end_value`).
|
||||||
|
|
||||||
@ -85,7 +97,7 @@ ___
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
```{py:method} ray_line(start_time: str | datetime, value: NUM, color: COLOR, width: int, style: LINE_STYLE) -> Line
|
```{py:method} ray_line(start_time: str | datetime, value: NUM, color: COLOR, width: int, style: LINE_STYLE, round: bool) -> Line
|
||||||
|
|
||||||
Creates a ray line, drawn from the first point (`start_time`, `value`) and onwards.
|
Creates a ray line, drawn from the first point (`start_time`, `value`) and onwards.
|
||||||
|
|
||||||
|
|||||||
51
docs/source/reference/histogram.md
Normal file
51
docs/source/reference/histogram.md
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# `Histogram`
|
||||||
|
|
||||||
|
|
||||||
|
````{py:class} Histogram(name: str, color: COLOR, style: LINE_STYLE, width: int, price_line: bool, price_label: bool)
|
||||||
|
|
||||||
|
The `Histogram` object represents a `HistogramSeries` object in Lightweight Charts and can be used to create indicators. As well as the methods described below, the `Line` object also has access to:
|
||||||
|
|
||||||
|
[`horizontal_line`](#AbstractChart.horizontal_line), [`hide_data`](#hide_data), [`show_data`](#show_data) and [`price_line`](#price_line).
|
||||||
|
|
||||||
|
Its instance should only be accessed from [`create_histogram`](#AbstractChart.create_histogram).
|
||||||
|
___
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```{py:method} set(data: pd.DataFrame)
|
||||||
|
|
||||||
|
Sets the data for the histogram.
|
||||||
|
|
||||||
|
When a name has not been set upon declaration, the columns should be named: `time | value` (Not case sensitive).
|
||||||
|
|
||||||
|
The column containing the data should be named after the string given in the `name`.
|
||||||
|
|
||||||
|
A `color` column can be used within the dataframe to specify the color of individual bars.
|
||||||
|
|
||||||
|
```
|
||||||
|
___
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```{py:method} update(series: pd.Series)
|
||||||
|
|
||||||
|
Updates the data for the histogram.
|
||||||
|
|
||||||
|
This should be given as a Series object, with labels akin to the `histogram.set` method.
|
||||||
|
```
|
||||||
|
___
|
||||||
|
|
||||||
|
|
||||||
|
```{py:method} scale(scale_margin_top: float, scale_margin_bottom: float)
|
||||||
|
Scales the margins of the histogram, as used within [`volume_config`](#AbstractChart.volume_config).
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
___
|
||||||
|
|
||||||
|
```{py:method} delete()
|
||||||
|
|
||||||
|
Irreversibly deletes the histogram.
|
||||||
|
|
||||||
|
```
|
||||||
|
````
|
||||||
@ -4,6 +4,7 @@
|
|||||||
:hidden:
|
:hidden:
|
||||||
abstract_chart
|
abstract_chart
|
||||||
line
|
line
|
||||||
|
histogram
|
||||||
horizontal_line
|
horizontal_line
|
||||||
charts
|
charts
|
||||||
events
|
events
|
||||||
|
|||||||
@ -5,9 +5,9 @@
|
|||||||
|
|
||||||
The `Line` object represents a `LineSeries` object in Lightweight Charts and can be used to create indicators. As well as the methods described below, the `Line` object also has access to:
|
The `Line` object represents a `LineSeries` object in Lightweight Charts and can be used to create indicators. As well as the methods described below, the `Line` object also has access to:
|
||||||
|
|
||||||
[`marker`](#marker), [`horizontal_line`](#AbstractChart.horizontal_line) [`hide_data`](#hide_data), [`show_data`](#show_data) and [`price_line`](#price_line).
|
[`marker`](#marker), [`horizontal_line`](#AbstractChart.horizontal_line), [`hide_data`](#hide_data), [`show_data`](#show_data) and [`price_line`](#price_line).
|
||||||
|
|
||||||
Its instance should only be accessed from [create_line](#AbstractChart.create_line).
|
Its instance should only be accessed from [`create_line`](#AbstractChart.create_line).
|
||||||
___
|
___
|
||||||
|
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ This should be given as a Series object, with labels akin to the `line.set()` fu
|
|||||||
|
|
||||||
___
|
___
|
||||||
|
|
||||||
```{py:method} line.delete()
|
```{py:method} delete()
|
||||||
|
|
||||||
Irreversibly deletes the line.
|
Irreversibly deletes the line.
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ from .topbar import TopBar
|
|||||||
from .util import (
|
from .util import (
|
||||||
IDGen, jbool, Pane, Events, TIME, NUM, FLOAT,
|
IDGen, jbool, Pane, Events, TIME, NUM, FLOAT,
|
||||||
LINE_STYLE, MARKER_POSITION, MARKER_SHAPE, CROSSHAIR_MODE, PRICE_SCALE_MODE,
|
LINE_STYLE, MARKER_POSITION, MARKER_SHAPE, CROSSHAIR_MODE, PRICE_SCALE_MODE,
|
||||||
line_style, marker_position, marker_shape, crosshair_mode, price_scale_mode,
|
line_style, marker_position, marker_shape, crosshair_mode, price_scale_mode, js_data,
|
||||||
)
|
)
|
||||||
|
|
||||||
JS = {}
|
JS = {}
|
||||||
@ -106,11 +106,15 @@ class Window:
|
|||||||
|
|
||||||
|
|
||||||
class SeriesCommon(Pane):
|
class SeriesCommon(Pane):
|
||||||
def __init__(self, chart: 'AbstractChart'):
|
def __init__(self, chart: 'AbstractChart', name: str = None):
|
||||||
super().__init__(chart.win)
|
super().__init__(chart.win)
|
||||||
self._chart = chart
|
self._chart = chart
|
||||||
self._interval = pd.Timedelta(seconds=1)
|
if hasattr(chart, '_interval'):
|
||||||
|
self._interval = chart._interval
|
||||||
|
else:
|
||||||
|
self._interval = pd.Timedelta(seconds=1)
|
||||||
self._last_bar = None
|
self._last_bar = None
|
||||||
|
self.name = name
|
||||||
self.num_decimals = 2
|
self.num_decimals = 2
|
||||||
|
|
||||||
def _set_interval(self, df: pd.DataFrame):
|
def _set_interval(self, df: pd.DataFrame):
|
||||||
@ -155,12 +159,33 @@ class SeriesCommon(Pane):
|
|||||||
return series
|
return series
|
||||||
|
|
||||||
def _single_datetime_format(self, arg):
|
def _single_datetime_format(self, arg):
|
||||||
if isinstance(arg, str) 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)
|
||||||
interval_seconds = self._interval.total_seconds()
|
interval_seconds = self._interval.total_seconds()
|
||||||
arg = interval_seconds * (arg.timestamp() // interval_seconds)
|
arg = interval_seconds * (arg.timestamp() // interval_seconds)
|
||||||
return arg
|
return arg
|
||||||
|
|
||||||
|
def set(self, df: pd.DataFrame = None, format_cols: bool = True):
|
||||||
|
if df is None or df.empty:
|
||||||
|
self.run_script(f'{self.id}.series.setData([])')
|
||||||
|
return
|
||||||
|
if format_cols:
|
||||||
|
df = self._df_datetime_format(df, exclude_lowercase=self.name)
|
||||||
|
if self.name:
|
||||||
|
if self.name not in df:
|
||||||
|
raise NameError(f'No column named "{self.name}".')
|
||||||
|
df = df.rename(columns={self.name: 'value'})
|
||||||
|
self._last_bar = df.iloc[-1]
|
||||||
|
self.run_script(f'{self.id}.series.setData({js_data(df)})')
|
||||||
|
|
||||||
|
def update(self, series: pd.Series):
|
||||||
|
series = self._series_datetime_format(series, exclude_lowercase=self.name)
|
||||||
|
if self.name in series.index:
|
||||||
|
series.rename({self.name: 'value'}, inplace=True)
|
||||||
|
self._last_bar = series
|
||||||
|
self.run_script(f'{self.id}.series.update({js_data(series)})')
|
||||||
|
|
||||||
|
|
||||||
def marker(self, time: datetime = None, position: MARKER_POSITION = 'below',
|
def marker(self, time: datetime = None, position: MARKER_POSITION = 'below',
|
||||||
shape: MARKER_SHAPE = 'arrow_up', color: str = '#2196F3', text: str = ''
|
shape: MARKER_SHAPE = 'arrow_up', color: str = '#2196F3', text: str = ''
|
||||||
) -> str:
|
) -> str:
|
||||||
@ -349,9 +374,8 @@ class VerticalSpan(Pane):
|
|||||||
|
|
||||||
class Line(SeriesCommon):
|
class Line(SeriesCommon):
|
||||||
def __init__(self, chart, name, color, style, width, price_line, price_label, crosshair_marker=True):
|
def __init__(self, chart, name, color, style, width, price_line, price_label, crosshair_marker=True):
|
||||||
super().__init__(chart)
|
super().__init__(chart, name)
|
||||||
self.color = color
|
self.color = color
|
||||||
self.name = name
|
|
||||||
self.run_script(f'''
|
self.run_script(f'''
|
||||||
{self.id} = {{
|
{self.id} = {{
|
||||||
series: {chart.id}.chart.addLineSeries({{
|
series: {chart.id}.chart.addLineSeries({{
|
||||||
@ -374,7 +398,7 @@ class Line(SeriesCommon):
|
|||||||
color: '{color}',
|
color: '{color}',
|
||||||
precision: 2,
|
precision: 2,
|
||||||
}}
|
}}
|
||||||
''')
|
null''')
|
||||||
|
|
||||||
def _push_to_legend(self):
|
def _push_to_legend(self):
|
||||||
self.run_script(f'''
|
self.run_script(f'''
|
||||||
@ -383,39 +407,18 @@ class Line(SeriesCommon):
|
|||||||
{self._chart.id}.legend.lines.push({self._chart.id}.legend.makeLineRow({self.id}))
|
{self._chart.id}.legend.lines.push({self._chart.id}.legend.makeLineRow({self.id}))
|
||||||
}}''')
|
}}''')
|
||||||
|
|
||||||
def set(self, df: pd.DataFrame = None):
|
def _set_trend(self, start_time, start_value, end_time, end_value, ray=False, round=False):
|
||||||
"""
|
if round:
|
||||||
Sets the line data.\n
|
start_time = self._single_datetime_format(start_time)
|
||||||
:param df: If the name parameter is not used, the columns should be named: date/time, value.
|
end_time = self._single_datetime_format(end_time)
|
||||||
"""
|
else:
|
||||||
if df is None or df.empty:
|
start_time, end_time = pd.to_datetime((start_time, end_time)).astype('int64') // 10 ** 9
|
||||||
self.run_script(f'{self.id}.series.setData([])')
|
|
||||||
return
|
|
||||||
df = self._df_datetime_format(df, exclude_lowercase=self.name)
|
|
||||||
if self.name:
|
|
||||||
if self.name not in df:
|
|
||||||
raise NameError(f'No column named "{self.name}".')
|
|
||||||
df = df.rename(columns={self.name: 'value'})
|
|
||||||
self._last_bar = df.iloc[-1]
|
|
||||||
self.run_script(f'{self.id}.series.setData({df.to_dict("records")})')
|
|
||||||
|
|
||||||
def update(self, series: pd.Series):
|
|
||||||
"""
|
|
||||||
Updates the line data.\n
|
|
||||||
:param series: labels: date/time, value
|
|
||||||
"""
|
|
||||||
series = self._series_datetime_format(series, exclude_lowercase=self.name)
|
|
||||||
if self.name in series.index:
|
|
||||||
series.rename({self.name: 'value'}, inplace=True)
|
|
||||||
self._last_bar = series
|
|
||||||
self.run_script(f'{self.id}.series.update({series.to_dict()})')
|
|
||||||
|
|
||||||
def _set_trend(self, start_time, start_value, end_time, end_value, ray=False):
|
|
||||||
self.run_script(f'''
|
self.run_script(f'''
|
||||||
{self._chart.id}.chart.timeScale().applyOptions({{shiftVisibleRangeOnNewBar: false}})
|
{self._chart.id}.chart.timeScale().applyOptions({{shiftVisibleRangeOnNewBar: false}})
|
||||||
{self.id}.series.setData(
|
{self.id}.series.setData(
|
||||||
calculateTrendLine({pd.to_datetime(start_time).timestamp()}, {start_value},
|
calculateTrendLine({start_time}, {start_value},
|
||||||
{pd.to_datetime(end_time).timestamp()}, {end_value},
|
{end_time}, {end_value},
|
||||||
{self._chart._interval.total_seconds() * 1000},
|
{self._chart._interval.total_seconds() * 1000},
|
||||||
{self._chart.id}, {jbool(ray)}))
|
{self._chart.id}, {jbool(ray)}))
|
||||||
{self._chart.id}.chart.timeScale().applyOptions({{shiftVisibleRangeOnNewBar: true}})
|
{self._chart.id}.chart.timeScale().applyOptions({{shiftVisibleRangeOnNewBar: true}})
|
||||||
@ -437,6 +440,44 @@ class Line(SeriesCommon):
|
|||||||
''')
|
''')
|
||||||
|
|
||||||
|
|
||||||
|
class Histogram(SeriesCommon):
|
||||||
|
def __init__(self, chart, name, color, price_line, price_label, scale_margin_top, scale_margin_bottom):
|
||||||
|
super().__init__(chart, name)
|
||||||
|
self.color = color
|
||||||
|
self.run_script(f'''
|
||||||
|
{self.id} = {{
|
||||||
|
series: {chart.id}.chart.addHistogramSeries({{
|
||||||
|
color: '{color}',
|
||||||
|
lastValueVisible: {jbool(price_label)},
|
||||||
|
priceLineVisible: {jbool(price_line)},
|
||||||
|
priceScaleId: '{self.id}'
|
||||||
|
}}),
|
||||||
|
markers: [],
|
||||||
|
horizontal_lines: [],
|
||||||
|
name: '{name}',
|
||||||
|
color: '{color}',
|
||||||
|
precision: 2,
|
||||||
|
}}
|
||||||
|
{self.id}.series.priceScale().applyOptions({{
|
||||||
|
scaleMargins: {{top:{scale_margin_top}, bottom: {scale_margin_bottom}}}
|
||||||
|
}})''')
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
"""
|
||||||
|
Irreversibly deletes the histogram.
|
||||||
|
"""
|
||||||
|
self.run_script(f'''
|
||||||
|
{self._chart.id}.chart.removeSeries({self.id}.series)
|
||||||
|
delete {self.id}
|
||||||
|
''')
|
||||||
|
|
||||||
|
def scale(self, scale_margin_top: float = 0.0, scale_margin_bottom: float = 0.0):
|
||||||
|
self.run_script(f'''
|
||||||
|
{self.id}.series.priceScale().applyOptions({{
|
||||||
|
scaleMargins: {{top: {scale_margin_top}, bottom: {scale_margin_bottom}}}
|
||||||
|
}})''')
|
||||||
|
|
||||||
|
|
||||||
class Candlestick(SeriesCommon):
|
class Candlestick(SeriesCommon):
|
||||||
def __init__(self, chart: 'AbstractChart'):
|
def __init__(self, chart: 'AbstractChart'):
|
||||||
super().__init__(chart)
|
super().__init__(chart)
|
||||||
@ -462,8 +503,7 @@ class Candlestick(SeriesCommon):
|
|||||||
self.candle_data = df.copy()
|
self.candle_data = df.copy()
|
||||||
self._last_bar = df.iloc[-1]
|
self._last_bar = df.iloc[-1]
|
||||||
|
|
||||||
bars = df.to_dict(orient='records')
|
self.run_script(f'{self.id}.candleData = {js_data(df)}; {self.id}.series.setData({self.id}.candleData)')
|
||||||
self.run_script(f'{self.id}.candleData = {bars}; {self.id}.series.setData({self.id}.candleData)')
|
|
||||||
toolbox_action = 'clearDrawings' if not render_drawings else 'renderDrawings'
|
toolbox_action = 'clearDrawings' if not render_drawings else 'renderDrawings'
|
||||||
self.run_script(f"if ('toolBox' in {self._chart.id}) {self._chart.id}.toolBox.{toolbox_action}()")
|
self.run_script(f"if ('toolBox' in {self._chart.id}) {self._chart.id}.toolBox.{toolbox_action}()")
|
||||||
if 'volume' not in df:
|
if 'volume' not in df:
|
||||||
@ -471,11 +511,12 @@ class Candlestick(SeriesCommon):
|
|||||||
volume = df.drop(columns=['open', 'high', 'low', 'close']).rename(columns={'volume': 'value'})
|
volume = df.drop(columns=['open', 'high', 'low', 'close']).rename(columns={'volume': 'value'})
|
||||||
volume['color'] = self._volume_down_color
|
volume['color'] = self._volume_down_color
|
||||||
volume.loc[df['close'] > df['open'], 'color'] = self._volume_up_color
|
volume.loc[df['close'] > df['open'], 'color'] = self._volume_up_color
|
||||||
self.run_script(f'{self.id}.volumeSeries.setData({volume.to_dict(orient="records")})')
|
self.run_script(f'{self.id}.volumeSeries.setData({js_data(volume)})')
|
||||||
|
|
||||||
# for line in self._lines:
|
for line in self._lines:
|
||||||
# if line.name in df.columns:
|
if line.name not in df.columns:
|
||||||
# line.set()
|
continue
|
||||||
|
line.set(df[['time', line.name]], format_cols=False)
|
||||||
|
|
||||||
def update(self, series: pd.Series, _from_tick=False):
|
def update(self, series: pd.Series, _from_tick=False):
|
||||||
"""
|
"""
|
||||||
@ -489,10 +530,9 @@ class Candlestick(SeriesCommon):
|
|||||||
self.candle_data = pd.concat([self.candle_data, series.to_frame().T], ignore_index=True)
|
self.candle_data = pd.concat([self.candle_data, series.to_frame().T], ignore_index=True)
|
||||||
self._chart.events.new_bar._emit(self)
|
self._chart.events.new_bar._emit(self)
|
||||||
self._last_bar = series
|
self._last_bar = series
|
||||||
|
bar = js_data(series)
|
||||||
bar = series.to_dict()
|
|
||||||
self.run_script(f'''
|
self.run_script(f'''
|
||||||
if (stampToDate(lastBar({self.id}.candleData).time).getTime() === stampToDate({bar['time']}).getTime()) {{
|
if (stampToDate(lastBar({self.id}.candleData).time).getTime() === stampToDate({series['time']}).getTime()) {{
|
||||||
{self.id}.candleData[{self.id}.candleData.length-1] = {bar}
|
{self.id}.candleData[{self.id}.candleData.length-1] = {bar}
|
||||||
}}
|
}}
|
||||||
else {self.id}.candleData.push({bar})
|
else {self.id}.candleData.push({bar})
|
||||||
@ -502,7 +542,7 @@ class Candlestick(SeriesCommon):
|
|||||||
return
|
return
|
||||||
volume = series.drop(['open', 'high', 'low', 'close']).rename({'volume': 'value'})
|
volume = series.drop(['open', 'high', 'low', 'close']).rename({'volume': 'value'})
|
||||||
volume['color'] = self._volume_up_color if series['close'] > series['open'] else self._volume_down_color
|
volume['color'] = self._volume_up_color if series['close'] > series['open'] else self._volume_down_color
|
||||||
self.run_script(f'{self.id}.volumeSeries.update({volume.to_dict()})')
|
self.run_script(f'{self.id}.volumeSeries.update({js_data(volume)})')
|
||||||
|
|
||||||
def update_from_tick(self, series: pd.Series, cumulative_volume: bool = False):
|
def update_from_tick(self, series: pd.Series, cumulative_volume: bool = False):
|
||||||
"""
|
"""
|
||||||
@ -626,12 +666,22 @@ class AbstractChart(Candlestick, Pane):
|
|||||||
price_line: bool = True, price_label: bool = True
|
price_line: bool = True, price_label: bool = True
|
||||||
) -> Line:
|
) -> Line:
|
||||||
"""
|
"""
|
||||||
Creates and returns a Line object.)\n
|
Creates and returns a Line object.
|
||||||
"""
|
"""
|
||||||
self._lines.append(Line(self, name, color, style, width, price_line, price_label))
|
self._lines.append(Line(self, name, color, style, width, price_line, price_label))
|
||||||
self._lines[-1]._push_to_legend()
|
self._lines[-1]._push_to_legend()
|
||||||
return self._lines[-1]
|
return self._lines[-1]
|
||||||
|
|
||||||
|
def create_histogram(
|
||||||
|
self, name: str = '', color: str = 'rgba(214, 237, 255, 0.6)',
|
||||||
|
price_line: bool = True, price_label: bool = True,
|
||||||
|
scale_margin_top: float = 0.0, scale_margin_bottom: float = 0.0
|
||||||
|
) -> Histogram:
|
||||||
|
"""
|
||||||
|
Creates and returns a Histogram object.
|
||||||
|
"""
|
||||||
|
return Histogram(self, name, color, price_line, price_label, scale_margin_top, scale_margin_bottom)
|
||||||
|
|
||||||
def lines(self) -> List[Line]:
|
def lines(self) -> List[Line]:
|
||||||
"""
|
"""
|
||||||
Returns all lines for the chart.
|
Returns all lines for the chart.
|
||||||
@ -639,20 +689,23 @@ class AbstractChart(Candlestick, Pane):
|
|||||||
return self._lines.copy()
|
return self._lines.copy()
|
||||||
|
|
||||||
def trend_line(self, start_time: TIME, start_value: NUM, end_time: TIME, end_value: NUM,
|
def trend_line(self, start_time: TIME, start_value: NUM, end_time: TIME, end_value: NUM,
|
||||||
color: str = '#1E80F0', width: int = 2, style: LINE_STYLE = 'solid'
|
round: bool = False, color: str = '#1E80F0', width: int = 2,
|
||||||
|
style: LINE_STYLE = 'solid',
|
||||||
) -> Line:
|
) -> Line:
|
||||||
line = Line(self, '', color, style, width, False, False, False)
|
line = Line(self, '', color, style, width, False, False, False)
|
||||||
line._set_trend(start_time, start_value, end_time, end_value)
|
line._set_trend(start_time, start_value, end_time, end_value, round=round)
|
||||||
return line
|
return line
|
||||||
|
|
||||||
def ray_line(self, start_time: TIME, value: NUM,
|
def ray_line(self, start_time: TIME, value: NUM, round: bool = False,
|
||||||
color: str = '#1E80F0', width: int = 2, style: LINE_STYLE = 'solid'
|
color: str = '#1E80F0', width: int = 2,
|
||||||
|
style: LINE_STYLE = 'solid'
|
||||||
) -> Line:
|
) -> Line:
|
||||||
line = Line(self, '', color, style, width, False, False, False)
|
line = Line(self, '', color, style, width, False, False, False)
|
||||||
line._set_trend(start_time, value, start_time, value, ray=True)
|
line._set_trend(start_time, value, start_time, value, ray=True, round=round)
|
||||||
return line
|
return line
|
||||||
|
|
||||||
def vertical_span(self, start_time: Union[TIME, tuple, list], end_time: TIME = None, color: str = 'rgba(252, 219, 3, 0.2)'):
|
def vertical_span(self, start_time: Union[TIME, tuple, list], end_time: TIME = None,
|
||||||
|
color: str = 'rgba(252, 219, 3, 0.2)'):
|
||||||
"""
|
"""
|
||||||
Creates a vertical line or span across the chart.\n
|
Creates a vertical line or span across the chart.\n
|
||||||
Start time and end time can be used together, or end_time can be
|
Start time and end time can be used together, or end_time can be
|
||||||
|
|||||||
@ -43,15 +43,13 @@ if (!window.Chart) {
|
|||||||
},
|
},
|
||||||
handleScroll: {vertTouchDrag: true},
|
handleScroll: {vertTouchDrag: true},
|
||||||
})
|
})
|
||||||
this.wrapper.style.width = `${100 * innerWidth}%`
|
|
||||||
this.wrapper.style.height = `${100 * innerHeight}%`
|
|
||||||
this.wrapper.style.display = 'flex'
|
this.wrapper.style.display = 'flex'
|
||||||
this.wrapper.style.flexDirection = 'column'
|
this.wrapper.style.flexDirection = 'column'
|
||||||
this.wrapper.style.position = 'relative'
|
this.wrapper.style.position = 'relative'
|
||||||
this.wrapper.style.float = position
|
this.wrapper.style.float = position
|
||||||
|
|
||||||
this.div.style.position = 'relative'
|
this.div.style.position = 'relative'
|
||||||
this.div.style.display = 'flex'
|
this.div.style.display = 'flex'
|
||||||
|
this.reSize()
|
||||||
this.wrapper.appendChild(this.div)
|
this.wrapper.appendChild(this.div)
|
||||||
document.getElementById('wrapper').append(this.wrapper)
|
document.getElementById('wrapper').append(this.wrapper)
|
||||||
|
|
||||||
@ -66,6 +64,8 @@ if (!window.Chart) {
|
|||||||
reSize() {
|
reSize() {
|
||||||
let topBarOffset = 'topBar' in this && this.scale.height !== 0 ? this.topBar.offsetHeight : 0
|
let topBarOffset = 'topBar' in this && this.scale.height !== 0 ? this.topBar.offsetHeight : 0
|
||||||
this.chart.resize(window.innerWidth * this.scale.width, (window.innerHeight * this.scale.height) - topBarOffset)
|
this.chart.resize(window.innerWidth * this.scale.width, (window.innerHeight * this.scale.height) - topBarOffset)
|
||||||
|
this.wrapper.style.width = `${100 * this.scale.width}%`
|
||||||
|
this.wrapper.style.height = `${100 * this.scale.height}%`
|
||||||
}
|
}
|
||||||
makeCandlestickSeries() {
|
makeCandlestickSeries() {
|
||||||
this.markers = []
|
this.markers = []
|
||||||
|
|||||||
@ -33,6 +33,11 @@ def parse_event_message(window, string):
|
|||||||
return func, args
|
return func, args
|
||||||
|
|
||||||
|
|
||||||
|
def js_data(data: Union[pd.DataFrame, pd.Series]):
|
||||||
|
orient = 'columns' if isinstance(data, pd.Series) else 'records'
|
||||||
|
return data.to_json(orient=orient, default_handler=lambda x: 'null' if pd.isna(x) else x)
|
||||||
|
|
||||||
|
|
||||||
def jbool(b: bool): return 'true' if b is True else 'false' if b is False else None
|
def jbool(b: bool): return 'true' if b is True else 'false' if b is False else None
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
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.17.2',
|
version='1.0.17.3',
|
||||||
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