Only draw mx/mn line for last uppx's worth of datums
When using m4, we downsample to the max and min of each pixel-column's-worth of data thus preserving range / dispersion details whilst not drawing more graphics then can be displayed by the available amount of horizontal pixels. Take and apply this exact same concept to the "last datum" graphics elements for any `Flow` that is reported as being in a downsampled state: - take the xy output from the `Curve.draw_last_datum()`, - slice out all data that fits in the last pixel's worth of x-range by using the uppx, - compute the highest and lowest value from that data, - draw a singe line segment which spans this yrange thus creating a simple vertical set of pixels which are "filled in" and show the entire y-range for the most recent data "contained with that pixel".incremental_update_paths
parent
e5f96391e3
commit
99965e7601
|
@ -654,6 +654,19 @@ def graphics_update_cycle(
|
||||||
|
|
||||||
# run synchronous update on all linked flows
|
# run synchronous update on all linked flows
|
||||||
for curve_name, flow in chart._flows.items():
|
for curve_name, flow in chart._flows.items():
|
||||||
|
|
||||||
|
if (
|
||||||
|
not (do_rt_update or do_append)
|
||||||
|
and liv
|
||||||
|
# even if we're downsampled bigly
|
||||||
|
# draw the last datum in the final
|
||||||
|
# px column to give the user the mx/mn
|
||||||
|
# range of that set.
|
||||||
|
):
|
||||||
|
# always update the last datum-element
|
||||||
|
# graphic for all flows
|
||||||
|
flow.draw_last(array_key=curve_name)
|
||||||
|
|
||||||
# TODO: should the "main" (aka source) flow be special?
|
# TODO: should the "main" (aka source) flow be special?
|
||||||
if curve_name == chart.data_key:
|
if curve_name == chart.data_key:
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -34,6 +34,7 @@ import numpy as np
|
||||||
from numpy.lib import recfunctions as rfn
|
from numpy.lib import recfunctions as rfn
|
||||||
import pyqtgraph as pg
|
import pyqtgraph as pg
|
||||||
from PyQt5.QtGui import QPainterPath
|
from PyQt5.QtGui import QPainterPath
|
||||||
|
from PyQt5.QtCore import QLineF
|
||||||
|
|
||||||
from ..data._sharedmem import (
|
from ..data._sharedmem import (
|
||||||
ShmArray,
|
ShmArray,
|
||||||
|
@ -335,12 +336,6 @@ class Flow(msgspec.Struct): # , frozen=True):
|
||||||
graphics: Curve
|
graphics: Curve
|
||||||
_shm: ShmArray
|
_shm: ShmArray
|
||||||
|
|
||||||
draw_last: Optional[
|
|
||||||
Callable[
|
|
||||||
[np.ndarray, str],
|
|
||||||
tuple[np.ndarray]
|
|
||||||
]
|
|
||||||
] = None
|
|
||||||
is_ohlc: bool = False
|
is_ohlc: bool = False
|
||||||
render: bool = True # toggle for display loop
|
render: bool = True # toggle for display loop
|
||||||
|
|
||||||
|
@ -594,7 +589,6 @@ class Flow(msgspec.Struct): # , frozen=True):
|
||||||
# TODO: append logic inside ``.render()`` isn't
|
# TODO: append logic inside ``.render()`` isn't
|
||||||
# correct yet for step curves.. remove this to see it.
|
# correct yet for step curves.. remove this to see it.
|
||||||
should_redraw = True
|
should_redraw = True
|
||||||
# draw_last = True
|
|
||||||
slice_to_head = -2
|
slice_to_head = -2
|
||||||
|
|
||||||
# downsampling incremental state checking
|
# downsampling incremental state checking
|
||||||
|
@ -690,8 +684,47 @@ class Flow(msgspec.Struct): # , frozen=True):
|
||||||
graphics.update()
|
graphics.update()
|
||||||
profiler('.update()')
|
profiler('.update()')
|
||||||
|
|
||||||
|
# track downsampled state
|
||||||
|
self._in_ds = r._in_ds
|
||||||
|
|
||||||
return graphics
|
return graphics
|
||||||
|
|
||||||
|
def draw_last(
|
||||||
|
self,
|
||||||
|
array_key: Optional[str] = None,
|
||||||
|
|
||||||
|
) -> None:
|
||||||
|
|
||||||
|
# shm read and slice to view
|
||||||
|
(
|
||||||
|
xfirst, xlast, src_array,
|
||||||
|
ivl, ivr, in_view,
|
||||||
|
) = self.read()
|
||||||
|
|
||||||
|
g = self.graphics
|
||||||
|
array_key = array_key or self.name
|
||||||
|
x, y = g.draw_last_datum(
|
||||||
|
g.path,
|
||||||
|
src_array,
|
||||||
|
src_array,
|
||||||
|
False, # never reset path
|
||||||
|
array_key,
|
||||||
|
)
|
||||||
|
|
||||||
|
if self._in_ds:
|
||||||
|
# we only care about the last pixel's
|
||||||
|
# worth of data since that's all the screen
|
||||||
|
# can represent on the last column where
|
||||||
|
# the most recent datum is being drawn.
|
||||||
|
uppx = self._last_uppx
|
||||||
|
y = y[-uppx:]
|
||||||
|
ymn, ymx = y.min(), y.max()
|
||||||
|
# print(f'drawing uppx={uppx} mxmn line: {ymn}, {ymx}')
|
||||||
|
g._last_line = QLineF(
|
||||||
|
x[-2], ymn,
|
||||||
|
x[-1], ymx,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def by_index_and_key(
|
def by_index_and_key(
|
||||||
renderer: Renderer,
|
renderer: Renderer,
|
||||||
|
|
Loading…
Reference in New Issue