Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ node_modules/
pyrightconfig.json

working/
.zed/
8 changes: 2 additions & 6 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import os.path

project = 'lightweight-charts-python'
copyright = '2023, louisnw'
copyright = '2024, louisnw'
author = 'louisnw'
release = '2.0.1'
release = '2.1'

extensions = [
"myst_parser",
Expand Down Expand Up @@ -104,7 +104,3 @@
},
],
}




6 changes: 3 additions & 3 deletions docs/source/reference/line.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# `Line`


````{py:class} Line(name: str, color: COLOR, style: LINE_STYLE, width: int, price_line: bool, price_label: bool)
````{py:class} Line(name: str, color: COLOR, style: LINE_STYLE, width: int, price_line: bool, price_label: bool, price_scale_id: str)

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:

Expand All @@ -12,7 +12,7 @@ ___



```{py:method} set(data: pd.DataFrame)
```{py:method} set(data: pd.DataFrame)

Sets the data for the line.

Expand Down Expand Up @@ -41,4 +41,4 @@ ___
Irreversibly deletes the line.

```
````
````
9 changes: 5 additions & 4 deletions lightweight_charts/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ def vertical_span(


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, price_scale_id=None, crosshair_marker=True):

super().__init__(chart, name)
self.color = color
Expand All @@ -439,6 +439,7 @@ def __init__(self, chart, name, color, style, width, price_line, price_label, cr
lastValueVisible: {jbool(price_label)},
priceLineVisible: {jbool(price_line)},
crosshairMarkerVisible: {jbool(crosshair_marker)},
priceScaleId: {f'"{price_scale_id}"' if price_scale_id else 'undefined'}
{"""autoscaleInfoProvider: () => ({
priceRange: {
minValue: 1_000_000_000,
Expand Down Expand Up @@ -515,7 +516,7 @@ def delete(self):
if ({self.id}legendItem) {{
{self._chart.id}.legend.div.removeChild({self.id}legendItem.row)
}}

{self._chart.id}.chart.removeSeries({self.id}.series)
delete {self.id}legendItem
delete {self.id}
Expand Down Expand Up @@ -721,12 +722,12 @@ def fit(self):
def create_line(
self, name: str = '', color: str = 'rgba(214, 237, 255, 0.6)',
style: LINE_STYLE = 'solid', width: int = 2,
price_line: bool = True, price_label: bool = True
price_line: bool = True, price_label: bool = True, price_scale_id: Optional[str] = None
) -> Line:
"""
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, price_scale_id))
return self._lines[-1]

def create_histogram(
Expand Down
34 changes: 19 additions & 15 deletions lightweight_charts/drawings.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,29 @@

from .util import NUM, Pane, as_enum, LINE_STYLE, TIME, snake_to_camel

def make_js_point(chart, time, price):
formatted_time = chart._single_datetime_format(time)
return f'''{{
"time": {formatted_time},
"logical": {chart.id}.chart.timeScale()
.coordinateToLogical(
{chart.id}.chart.timeScale()
.timeToCoordinate({formatted_time})
),
"price": {price}
}}'''

class Drawing(Pane):
def __init__(self, chart, func=None):
super().__init__(chart.win)
self.chart = chart

def update(self, *points):
js_json_string = f'JSON.parse({json.dumps(points)})'
self.run_script(f'{self.id}.updatePoints(...{js_json_string})')
formatted_points = []
for i in range(0, len(points), 2):
formatted_points.append(make_js_point(self.chart, points[i], points[i + 1]))
self.run_script(f'{self.id}.updatePoints({", ".join(formatted_points)})')
print(f'{self.id}.updatePoints({", ".join(formatted_points)})')

def delete(self):
"""
Expand Down Expand Up @@ -46,24 +60,14 @@ def __init__(
):
super().__init__(chart, func)

def make_js_point(time, price):
formatted_time = self.chart._single_datetime_format(time)
return f'''{{
"time": {formatted_time},
"logical": {self.chart.id}.chart.timeScale()
.coordinateToLogical(
{self.chart.id}.chart.timeScale()
.timeToCoordinate({formatted_time})
),
"price": {price}
}}'''


options_string = '\n'.join(f'{key}: {val},' for key, val in options.items())

self.run_script(f'''
{self.id} = new Lib.{drawing_type}(
{make_js_point(start_time, start_value)},
{make_js_point(end_time, end_value)},
{make_js_point(self.chart, start_time, start_value)},
{make_js_point(self.chart, end_time, end_value)},
{{
{options_string}
}}
Expand Down
2 changes: 1 addition & 1 deletion lightweight_charts/js/bundle.js

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions lightweight_charts/js/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,16 @@ body {
display: none;
flex-direction: column;
}
.series-container {
display: flex;
flex-direction: column;
pointer-events: auto;
overflow-y: auto;
max-height: 80vh;
}
.series-container::-webkit-scrollbar {
width: 0px;
}
.legend-toggle-switch {
border-radius: 4px;
margin-left: 10px;
Expand Down
4 changes: 2 additions & 2 deletions lightweight_charts/topbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ def set(self, option):
raise ValueError(f"Option {option} not in menu options ({self.options})")
self.value = option
self.run_script(f'''
{self.id}.updateMenu("{option}")
{self.id}._clickHandler("{option}")
''')
self.win.handlers[self.id](option)
# self.win.handlers[self.id](option)

def update_items(self, *items: str):
self.options = list(items)
Expand Down
2 changes: 1 addition & 1 deletion lightweight_charts/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ def __init__(self, chart):
}}
{chart.id}.chart.subscribeClick(clickHandler{salt})
'''),
wrapper=lambda func, c, *args: func(c, *[float(a) for a in args])
wrapper=lambda func, c, *args: func(c, *[float(a) if a != 'null' else None for a in args])
)

class BulkRunScript:
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setup(
name='lightweight_charts',
version='2.0.1',
version='2.1',
packages=find_packages(),
python_requires='>=3.8',
install_requires=[
Expand Down
17 changes: 13 additions & 4 deletions src/general/legend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ interface LineElement {
export class Legend {
private handler: Handler;
public div: HTMLDivElement;
public seriesContainer: HTMLDivElement

private ohlcEnabled: boolean = false;
private percentEnabled: boolean = false;
Expand All @@ -35,16 +36,24 @@ export class Legend {
this.colorBasedOnCandle = false

this.div = document.createElement('div');
this.div.classList.add('legend');
this.div.classList.add("legend")
this.div.style.maxWidth = `${(handler.scale.width * 100) - 8}vw`
this.div.style.display = 'none';

const seriesWrapper = document.createElement('div');
seriesWrapper.style.display = 'flex';
seriesWrapper.style.flexDirection = 'row';
this.seriesContainer = document.createElement("div");
this.seriesContainer.classList.add("series-container");

this.text = document.createElement('span')
this.text.style.lineHeight = '1.8'
this.candle = document.createElement('div')


seriesWrapper.appendChild(this.seriesContainer);
this.div.appendChild(this.text)
this.div.appendChild(this.candle)
this.div.appendChild(seriesWrapper)
handler.div.appendChild(this.div)

// this.makeSeriesRows(handler);
Expand Down Expand Up @@ -108,9 +117,9 @@ export class Legend {
toggle.appendChild(svg);
row.appendChild(div)
row.appendChild(toggle)
this.div.appendChild(row)
this.seriesContainer.appendChild(row)

const color = series.options().baseLineColor;
const color = series.options().color;
this._lines.push({
name: name,
div: div,
Expand Down
12 changes: 8 additions & 4 deletions src/general/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,19 @@ export class Menu {
items.forEach(text => {
let button = this.makeButton(text, null, false, false)
button.elem.addEventListener('click', () => {
this.widget.elem.innerText = button.elem.innerText+' ↓'
window.callbackFunction(`${this.callbackName}_~_${button.elem.innerText}`)
this.div.style.display = 'none'
this.isOpen = false
this._clickHandler(button.elem.innerText);
});
button.elem.style.margin = '4px 4px'
button.elem.style.padding = '2px 2px'
this.div.appendChild(button.elem)
})
this.widget.elem.innerText = items[0]+' ↓';
}

private _clickHandler(name: string) {
this.widget.elem.innerText = name+' ↓'
window.callbackFunction(`${this.callbackName}_~_${name}`)
this.div.style.display = 'none'
this.isOpen = false
}
}
10 changes: 10 additions & 0 deletions src/general/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,16 @@ body {
display: none;
flex-direction: column;
}
.series-container {
display: flex;
flex-direction: column;
pointer-events: auto;
overflow-y: auto;
max-height: 80vh;
}
.series-container::-webkit-scrollbar {
width: 0px;
}
.legend-toggle-switch {
border-radius: 4px;
margin-left: 10px;
Expand Down