diff --git a/lightweight_charts/abstract.py b/lightweight_charts/abstract.py index 387a867..88f59e4 100644 --- a/lightweight_charts/abstract.py +++ b/lightweight_charts/abstract.py @@ -87,9 +87,13 @@ class Window: def create_table(self, width: NUM, height: NUM, headings: tuple, widths: tuple = None, alignments: tuple = None, position: FLOAT = 'left', draggable: bool = False, - func: callable = None + background_color: str = '#121417', border_color: str = 'rgb(70, 70, 70)', + border_width: int = 1, heading_text_colors: tuple = None, + heading_background_colors: tuple = None, func: callable = None ) -> 'Table': - return Table(self, width, height, headings, widths, alignments, position, draggable, func) + return Table(self, width, height, headings, widths, alignments, position, draggable, + background_color, border_color, border_width, heading_text_colors, + heading_background_colors, func) def create_subchart(self, position: FLOAT = 'left', width: float = 0.5, height: float = 0.5, sync_id: str = None, scale_candles_only: bool = False, toolbox: bool = False @@ -911,11 +915,15 @@ class AbstractChart(Candlestick, Pane): }})''') self.win.handlers[f'{modifier_key, keys}'] = func - def create_table(self, width: NUM, height: NUM, - headings: tuple, widths: tuple = None, alignments: tuple = None, - position: FLOAT = 'left', draggable: bool = False, func: callable = None + def create_table( + self, width: NUM, height: NUM, headings: tuple, widths: tuple = None, alignments: tuple = None, + position: FLOAT = 'left', draggable: bool = False, background_color: str = '#121417', + border_color: str = 'rgb(70, 70, 70)', border_width: int = 1, heading_text_colors: tuple = None, + heading_background_colors: tuple = None, func: callable = None ) -> Table: - return self.win.create_table(width, height, headings, widths, alignments, position, draggable, func) + return self.win.create_table(width, height, headings, widths, alignments, position, draggable, + background_color, border_color, border_width, heading_text_colors, + heading_background_colors, func) def screenshot(self) -> bytes: """ diff --git a/lightweight_charts/js/table.js b/lightweight_charts/js/table.js index b1ce890..ab6ceda 100644 --- a/lightweight_charts/js/table.js +++ b/lightweight_charts/js/table.js @@ -1,8 +1,11 @@ if (!window.Table) { class Table { - constructor(width, height, headings, widths, alignments, position, draggable = false) { + constructor(width, height, headings, widths, alignments, position, draggable = false, + tableBackgroundColor, borderColor, borderWidth, textColors, backgroundColors) { this.container = document.createElement('div') this.callbackName = null + this.borderColor = borderColor + this.borderWidth = borderWidth if (draggable) { this.container.style.position = 'absolute' @@ -11,7 +14,6 @@ if (!window.Table) { this.container.style.position = 'relative' this.container.style.float = position } - this.container.style.zIndex = '2000' this.container.style.width = width <= 1 ? width * 100 + '%' : width + 'px' this.container.style.height = height <= 1 ? height * 100 + '%' : height + 'px' @@ -19,7 +21,6 @@ if (!window.Table) { this.container.style.flexDirection = 'column' this.container.style.justifyContent = 'space-between' - this.container.style.backgroundColor = '#121417' this.container.style.borderRadius = '5px' this.container.style.color = 'white' this.container.style.fontSize = '12px' @@ -47,12 +48,17 @@ if (!window.Table) { th.style.padding = '0.2rem 0px' th.style.fontWeight = '500' th.style.textAlign = 'center' + if (i !== 0) th.style.borderLeft = borderWidth+'px solid '+borderColor + th.style.position = 'sticky' + th.style.top = '0' + th.style.backgroundColor = backgroundColors.length > 0 ? backgroundColors[i] : tableBackgroundColor + th.style.color = textColors[i] row.appendChild(th) - th.style.border = '1px solid rgb(70, 70, 70)' } let overflowWrapper = document.createElement('div') overflowWrapper.style.overflow = 'auto' + overflowWrapper.style.backgroundColor = tableBackgroundColor overflowWrapper.appendChild(this.table) this.container.appendChild(overflowWrapper) document.getElementById('wrapper').appendChild(this.container) @@ -93,7 +99,7 @@ if (!window.Table) { row[this.headings[i]] = row.insertCell() row[this.headings[i]].style.width = this.widths[i]; row[this.headings[i]].style.textAlign = this.alignments[i]; - row[this.headings[i]].style.border = '1px solid rgb(70, 70, 70)' + row[this.headings[i]].style.border = this.borderWidth+'px solid '+this.borderColor } row.addEventListener('mouseover', () => row.style.backgroundColor = 'rgba(60, 60, 60, 0.6)') row.addEventListener('mouseout', () => row.style.backgroundColor = 'transparent') @@ -121,20 +127,20 @@ if (!window.Table) { this.rows[rowId][column].textContent = val } - makeFooter(numBoxes) { - let footer = document.createElement('div') - footer.style.display = 'flex' - footer.style.width = '100%' - footer.style.padding = '3px 0px' - footer.style.backgroundColor = 'rgb(30, 30, 30)' - this.container.appendChild(footer) + makeSection(type, numBoxes) { + let section = document.createElement('div') + section.style.display = 'flex' + section.style.width = '100%' + section.style.padding = '3px 0px' + section.style.backgroundColor = 'rgb(30, 30, 30)' + type === 'footer' ? this.container.appendChild(section) : this.container.prepend(section) - this.footer = [] + this[type] = [] for (let i = 0; i < numBoxes; i++) { - this.footer.push(document.createElement('div')) - footer.appendChild(this.footer[i]) - this.footer[i].style.flex = '1' - this.footer[i].style.textAlign = 'center' + this[type].push(document.createElement('div')) + section.appendChild(this[type][i]) + this[type][i].style.flex = '1' + this[type][i].style.textAlign = 'center' } } } diff --git a/lightweight_charts/table.py b/lightweight_charts/table.py index 9b04868..54973e5 100644 --- a/lightweight_charts/table.py +++ b/lightweight_charts/table.py @@ -4,15 +4,16 @@ from typing import Union from .util import jbool, Pane, NUM -class Footer: - def __init__(self, table): +class Section: + def __init__(self, table, section_type): self._table = table - - def __setitem__(self, key, value): - self._table.run_script(f'{self._table.id}.footer[{key}].innerText = "{value}"') + self.type = section_type def __call__(self, number_of_text_boxes: int): - self._table.run_script(f'{self._table.id}.makeFooter({number_of_text_boxes})') + self._table.run_script(f'{self._table.id}.makeSection("{self.type}", {number_of_text_boxes})') + + def __setitem__(self, key, value): + self._table.run_script(f'{self._table.id}.{self.type}[{key}].innerText = "{value}"') class Row(dict): @@ -50,7 +51,13 @@ class Row(dict): class Table(Pane, dict): VALUE = 'CELL__~__VALUE__~__PLACEHOLDER' - def __init__(self, window, width: NUM, height: NUM, headings: tuple, widths: tuple = None, alignments: tuple = None, position='left', draggable: bool = False, func: callable = None): + def __init__( + self, window, width: NUM, height: NUM, headings: tuple, widths: tuple = None, + alignments: tuple = None, position='left', draggable: bool = False, + background_color: str = '#121417', border_color: str = 'rgb(70, 70, 70)', + border_width: int = 1, heading_text_colors: tuple = None, + heading_background_colors: tuple = None, func: callable = None + ): dict.__init__(self) Pane.__init__(self, window) self._formatters = {} @@ -60,10 +67,18 @@ class Table(Pane, dict): headings = list(headings) widths = list(widths) if widths else [] alignments = list(alignments) if alignments else [] + heading_text_colors = list(heading_text_colors) if heading_text_colors else [] + heading_background_colors = list(heading_background_colors) if heading_background_colors else [] - self.run_script(f'{self.id} = new Table({width}, {height}, {headings}, {widths}, {alignments}, "{position}", {jbool(draggable)})') + self.run_script(f''' + {self.id} = new Table( + {width}, {height}, {headings}, {widths}, {alignments}, '{position}', {jbool(draggable)}, + '{background_color}', '{border_color}', {border_width}, {heading_text_colors}, + {heading_background_colors} + )''') self.run_script(f'{self.id}.callbackName = "{self.id}"') if func else None - self.footer = Footer(self) + self.footer = Section(self, 'footer') + self.header = Section(self, 'header') def new_row(self, *values, id=None) -> Row: row_id = random.randint(0, 99_999_999) if not id else id