Add `Viz.index_field: str`, pass to graphics objs

In an effort to make it easy to override the indexing scheme.

Further, this repairs the `.datums_range()` special case to handle when
the view box is to-the-right-of the data set (i.e. l > datum_start).
multichartz
Tyler Goodlet 2022-11-30 10:14:04 -05:00
parent 2368ddadf2
commit 3633acb3c5
1 changed files with 63 additions and 28 deletions

View File

@ -103,6 +103,7 @@ def render_baritems(
shm=viz.shm, shm=viz.shm,
viz=viz, viz=viz,
_last_read=read, _last_read=read,
index_field=viz.index_field,
), ),
) )
@ -112,6 +113,7 @@ def render_baritems(
shm=viz.shm, shm=viz.shm,
viz=viz, viz=viz,
_last_read=read, _last_read=read,
index_field=viz.index_field,
), ),
) )
@ -230,6 +232,8 @@ class Viz(msgspec.Struct): # , frozen=True):
is_ohlc: bool = False is_ohlc: bool = False
render: bool = True # toggle for display loop render: bool = True # toggle for display loop
_index_field: str = 'index'
# downsampling state # downsampling state
_last_uppx: float = 0 _last_uppx: float = 0
_in_ds: bool = False _in_ds: bool = False
@ -254,6 +258,10 @@ class Viz(msgspec.Struct): # , frozen=True):
def shm(self) -> ShmArray: def shm(self) -> ShmArray:
return self._shm return self._shm
@property
def index_field(self) -> str:
return self._index_field
def maxmin( def maxmin(
self, self,
lbar: int, lbar: int,
@ -280,25 +288,24 @@ class Viz(msgspec.Struct): # , frozen=True):
arr = shm.array arr = shm.array
# get relative slice indexes into array # get relative slice indexes into array
# ( if self.index_field == 'time':
# abs_slc, (
# read_slc, abs_slc,
# mask, read_slc,
# ) = self.flume.slice_from_time( mask,
# arr, ) = self.flume.slice_from_time(
# start_t=lbar, arr,
# stop_t=rbar, start_t=lbar,
# ) stop_t=rbar,
# slice_view = arr[mask] )
slice_view = arr[mask]
# TODO: should we just add/use a method else:
# on the shm to do this? ifirst = arr[0]['index']
slice_view = arr[
ifirst = arr[0]['index'] lbar - ifirst:
slice_view = arr[ (rbar - ifirst) + 1
lbar - ifirst: ]
(rbar - ifirst) + 1
]
if not slice_view.size: if not slice_view.size:
return None return None
@ -318,7 +325,7 @@ class Viz(msgspec.Struct): # , frozen=True):
yhigh = np.max(view) yhigh = np.max(view)
mxmn = ylow, yhigh mxmn = ylow, yhigh
# print(f'{self.name} MANUAL maxmin: {mxmin}') # print(f'{self.name} MANUAL maxmin: {mxmn}')
# cache result for input range # cache result for input range
assert mxmn assert mxmn
@ -348,7 +355,7 @@ class Viz(msgspec.Struct): # , frozen=True):
def datums_range( def datums_range(
self, self,
index_field: str = 'index', index_field: str | None = None,
) -> tuple[ ) -> tuple[
int, int, int, int, int, int int, int, int, int, int, int
@ -359,20 +366,30 @@ class Viz(msgspec.Struct): # , frozen=True):
''' '''
l, r = self.view_range() l, r = self.view_range()
index_field: str = index_field or self.index_field
if index_field == 'index': if index_field == 'index':
l, r = round(l), round(r) l, r = round(l), round(r)
# # TODO: avoid this and have shm passed in earlier?
# if self.shm is None:
# # haven't initialized the viz yet
# return (0, l, 0, 0, r, 0)
array = self.shm.array array = self.shm.array
index = array[index_field] index = array[index_field]
start = index[0] start = index[0]
stop = index[-1] stop = index[-1]
datum_start = max(l, start)
datum_stop = min(r, stop) if (
l < 0
or r < l
or l < start
):
datum_start = start
datum_stop = stop
else:
datum_start = max(l, start)
datum_stop = r
if l < stop:
datum_stop = min(r, stop)
assert datum_start < datum_stop
return ( return (
start, start,
l, # left x-in-view l, # left x-in-view
@ -385,7 +402,7 @@ class Viz(msgspec.Struct): # , frozen=True):
def read( def read(
self, self,
array_field: Optional[str] = None, array_field: Optional[str] = None,
index_field: str = 'index', index_field: str | None = None,
) -> tuple[ ) -> tuple[
int, int, np.ndarray, int, int, np.ndarray,
@ -398,6 +415,8 @@ class Viz(msgspec.Struct): # , frozen=True):
which has been written to. which has been written to.
''' '''
index_field: str = index_field or self.index_field
# readable data # readable data
array = self.shm.array array = self.shm.array
@ -409,6 +428,8 @@ class Viz(msgspec.Struct): # , frozen=True):
r, r,
ilast, ilast,
) = self.datums_range(index_field=index_field) ) = self.datums_range(index_field=index_field)
# if rbar < lbar:
# breakpoint()
abs_slc = slice(ifirst, ilast) abs_slc = slice(ifirst, ilast)
@ -425,6 +446,17 @@ class Viz(msgspec.Struct): # , frozen=True):
) )
in_view = array[read_slc] in_view = array[read_slc]
# diff = rbar - lbar
# if (
# 'btc' in self.name
# and 'hist' not in self.shm.token
# ):
# print(
# f'{self.name}: len(iv) = {len(in_view)}\n'
# f'start/stop: {lbar},{rbar}\n',
# f'diff: {diff}\n',
# )
# array-index slicing # array-index slicing
# TODO: can we do time based indexing using arithmetic presuming # TODO: can we do time based indexing using arithmetic presuming
# a uniform time stamp step size? # a uniform time stamp step size?
@ -534,6 +566,7 @@ class Viz(msgspec.Struct): # , frozen=True):
shm=self.shm, shm=self.shm,
viz=self, viz=self,
_last_read=read, _last_read=read,
index_field=self.index_field,
), ),
) )
@ -670,6 +703,7 @@ class Viz(msgspec.Struct): # , frozen=True):
data, data,
reset, reset,
array_key, array_key,
index_field=self.index_field,
) )
graphics.update() graphics.update()
profiler('.update()') profiler('.update()')
@ -707,6 +741,7 @@ class Viz(msgspec.Struct): # , frozen=True):
src_array, src_array,
False, # never reset path False, # never reset path
array_key, array_key,
self.index_field,
) )
# the renderer is downsampling we choose # the renderer is downsampling we choose