Add proper x-axis time-stamping
							parent
							
								
									ea2a675adf
								
							
						
					
					
						commit
						17d205f773
					
				|  | @ -1,12 +1,17 @@ | |||
| """ | ||||
| Chart axes graphics and behavior. | ||||
| """ | ||||
| import time | ||||
| from functools import partial | ||||
| from typing import List | ||||
| 
 | ||||
| 
 | ||||
| # import numpy as np | ||||
| import pandas as pd | ||||
| import pyqtgraph as pg | ||||
| from PyQt5 import QtCore, QtGui | ||||
| from PyQt5.QtCore import QPointF | ||||
| 
 | ||||
| 
 | ||||
| # from .quantdom.base import Quotes | ||||
| from .quantdom.utils import fromtimestamp | ||||
| from ._style import _font, hcolor | ||||
| 
 | ||||
|  | @ -15,7 +20,6 @@ class PriceAxis(pg.AxisItem): | |||
| 
 | ||||
|     def __init__( | ||||
|         self, | ||||
|         # chart: 'ChartPlotWidget', | ||||
|     ) -> None: | ||||
|         super().__init__(orientation='right') | ||||
|         self.setStyle(**{ | ||||
|  | @ -28,10 +32,7 @@ class PriceAxis(pg.AxisItem): | |||
|         }) | ||||
|         self.setLabel(**{'font-size': '10pt'}) | ||||
|         self.setTickFont(_font) | ||||
|         self.setWidth(150) | ||||
|         # self.chart = chart | ||||
|         # accesed normally via | ||||
|         # .getAxis('right') | ||||
|         self.setWidth(125) | ||||
| 
 | ||||
|     # XXX: drop for now since it just eats up h space | ||||
| 
 | ||||
|  | @ -43,9 +44,20 @@ class PriceAxis(pg.AxisItem): | |||
| 
 | ||||
| 
 | ||||
| class DynamicDateAxis(pg.AxisItem): | ||||
|     tick_tpl = {'D1': '%Y-%b-%d'} | ||||
|     # time formats mapped by seconds between bars | ||||
|     tick_tpl = { | ||||
|         60*60*24: '%Y-%b-%d', | ||||
|         60: '%H:%M', | ||||
|         30: '%H:%M:%S', | ||||
|         5: '%H:%M:%S', | ||||
|     } | ||||
| 
 | ||||
|     def __init__(self, linked_charts, *args, **kwargs): | ||||
|     def __init__( | ||||
|         self, | ||||
|         linked_charts, | ||||
|         *args, | ||||
|         **kwargs | ||||
|     ) -> None: | ||||
|         super().__init__(*args, **kwargs) | ||||
|         self.linked_charts = linked_charts | ||||
|         self.setTickFont(_font) | ||||
|  | @ -59,24 +71,25 @@ class DynamicDateAxis(pg.AxisItem): | |||
|         ) | ||||
|         # self.setHeight(35) | ||||
| 
 | ||||
|     def tickStrings(self, values, scale, spacing): | ||||
|         # if len(values) > 1 or not values: | ||||
|         #     values = Quotes.time | ||||
| 
 | ||||
|         # strings = super().tickStrings(values, scale, spacing) | ||||
|         s_period = 'D1' | ||||
|         strings = [] | ||||
|     def _indexes_to_timestrs( | ||||
|         self, | ||||
|         indexes: List[int], | ||||
|     ) -> List[str]: | ||||
|         bars = self.linked_charts.chart._array | ||||
|         quotes_count = len(bars) - 1 | ||||
|         times = bars['time'] | ||||
|         bars_len = len(bars) | ||||
|         delay = times[-1] - times[times != times[-1]][-1] | ||||
| 
 | ||||
|         for ibar in values: | ||||
|             if ibar > quotes_count: | ||||
|                 return strings | ||||
|             dt_tick = fromtimestamp(bars[int(ibar)]['time']) | ||||
|             strings.append( | ||||
|                 dt_tick.strftime(self.tick_tpl[s_period]) | ||||
|             ) | ||||
|         return strings | ||||
|         epochs = times[list( | ||||
|             map(int, filter(lambda i: i < bars_len, indexes)) | ||||
|         )] | ||||
|         # TODO: **don't** have this hard coded shift to EST | ||||
|         dts = pd.to_datetime(epochs, unit='s') - 4*pd.offsets.Hour() | ||||
|         return dts.strftime(self.tick_tpl[delay]) | ||||
| 
 | ||||
| 
 | ||||
|     def tickStrings(self, values: List[float], scale, spacing): | ||||
|         return self._indexes_to_timestrs(values) | ||||
| 
 | ||||
| 
 | ||||
| class AxisLabel(pg.GraphicsObject): | ||||
|  | @ -88,7 +101,7 @@ class AxisLabel(pg.GraphicsObject): | |||
|     def __init__( | ||||
|         self, | ||||
|         parent=None, | ||||
|         digits=1, | ||||
|         digits=2, | ||||
|         color=None, | ||||
|         opacity=1, | ||||
|         **kwargs | ||||
|  | @ -128,6 +141,7 @@ class AxisLabel(pg.GraphicsObject): | |||
|         p.drawText(option.rect, self.text_flags, self.label_str) | ||||
| 
 | ||||
|     # uggggghhhh | ||||
| 
 | ||||
|     def tick_to_string(self, tick_pos): | ||||
|         raise NotImplementedError() | ||||
| 
 | ||||
|  | @ -160,24 +174,20 @@ class XAxisLabel(AxisLabel): | |||
|     ) | ||||
|     # text_flags = _common_text_flags | ||||
| 
 | ||||
|     def tick_to_string(self, tick_pos): | ||||
|         # TODO: change to actual period | ||||
|         tpl = self.parent.tick_tpl['D1'] | ||||
|         bars = self.parent.linked_charts.chart._array | ||||
|         if tick_pos > len(bars): | ||||
|             return 'Unknown Time' | ||||
|         return fromtimestamp(bars[round(tick_pos)]['time']).strftime(tpl) | ||||
| 
 | ||||
|     def boundingRect(self):  # noqa | ||||
|         return QtCore.QRectF(0, 0, 145, 40) | ||||
|         # TODO: we need to get the parent axe's dimensions transformed | ||||
|         # to abs coords to be 100% correct here: | ||||
|         # self.parent.boundingRect() | ||||
|         return QtCore.QRectF(0, 0, 100, 31) | ||||
| 
 | ||||
|     def update_label(self, abs_pos, data): | ||||
|         # ibar = view_pos.x() | ||||
|         # if ibar > self.quotes_count: | ||||
|         #     return | ||||
|         self.label_str = self.tick_to_string(data) | ||||
|     def update_label( | ||||
|         self, | ||||
|         abs_pos: QPointF,  # scene coords | ||||
|         data: float,  # data for text | ||||
|         offset: int = 0  # if have margins, k? | ||||
|     ) -> None: | ||||
|         self.label_str = self.parent._indexes_to_timestrs([int(data)])[0] | ||||
|         width = self.boundingRect().width() | ||||
|         offset = 0  # if have margins | ||||
|         new_pos = QPointF(abs_pos.x() - width / 2 - offset, 0) | ||||
|         self.setPos(new_pos) | ||||
| 
 | ||||
|  | @ -202,10 +212,10 @@ class YAxisLabel(AxisLabel): | |||
|         self, | ||||
|         abs_pos: QPointF,  # scene coords | ||||
|         data: float,  # data for text | ||||
|         offset: int = 0  # if have margins, k? | ||||
|     ) -> None: | ||||
|         self.label_str = self.tick_to_string(data) | ||||
|         height = self.boundingRect().height() | ||||
|         offset = 0  # if have margins | ||||
|         new_pos = QPointF(0, abs_pos.y() - height / 2 - offset) | ||||
|         self.setPos(new_pos) | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue