diff --git a/piker/ui/_curve.py b/piker/ui/_curve.py index 9e1f684a..965d682c 100644 --- a/piker/ui/_curve.py +++ b/piker/ui/_curve.py @@ -84,8 +84,8 @@ class FastAppendCurve(pg.GraphicsObject): # brutaaalll, see comments within.. self.yData = None self.xData = None - self._vr: Optional[tuple] = None - self._avr: Optional[tuple] = None + # self._vr: Optional[tuple] = None + # self._avr: Optional[tuple] = None self._last_cap: int = 0 self._name = name @@ -99,12 +99,12 @@ class FastAppendCurve(pg.GraphicsObject): super().__init__(*args, **kwargs) # self._xrange: tuple[int, int] = self.dataBounds(ax=0) - self._xrange: Optional[tuple[int, int]] = None + # self._xrange: Optional[tuple[int, int]] = None # self._x_iv_range = None # self._last_draw = time.time() - self._in_ds: bool = False - self._last_uppx: float = 0 + # self._in_ds: bool = False + # self._last_uppx: float = 0 # all history of curve is drawn in single px thickness pen = pg.mkPen(hcolor(color)) @@ -161,8 +161,8 @@ class FastAppendCurve(pg.GraphicsObject): vr = self.viewRect() l, r = int(vr.left()), int(vr.right()) - if not self._xrange: - return 0 + # if not self._xrange: + # return 0 start, stop = self._xrange lbar = max(l, start) @@ -172,333 +172,6 @@ class FastAppendCurve(pg.GraphicsObject): QLineF(lbar, 0, rbar, 0) ).length() - # def update_from_array( - # self, - - # # full array input history - # x: np.ndarray, - # y: np.ndarray, - - # # pre-sliced array data that's "in view" - # x_iv: np.ndarray, - # y_iv: np.ndarray, - - # view_range: Optional[tuple[int, int]] = None, - # profiler: Optional[pg.debug.Profiler] = None, - # draw_last: bool = True, - # slice_to_head: int = -1, - # do_append: bool = True, - # should_redraw: bool = False, - - # ) -> QtGui.QPainterPath: - # ''' - # Update curve from input 2-d data. - - # Compare with a cached "x-range" state and (pre/a)ppend based on - # a length diff. - - # ''' - # profiler = profiler or pg.debug.Profiler( - # msg=f'FastAppendCurve.update_from_array(): `{self._name}`', - # disabled=not pg_profile_enabled(), - # ms_threshold=ms_slower_then, - # ) - # # flip_cache = False - - # if self._xrange: - # istart, istop = self._xrange - # else: - # self._xrange = istart, istop = x[0], x[-1] - - # # compute the length diffs between the first/last index entry in - # # the input data and the last indexes we have on record from the - # # last time we updated the curve index. - # prepend_length = int(istart - x[0]) - # append_length = int(x[-1] - istop) - - # # this is the diff-mode, "data"-rendered index - # # tracking var.. - # self._xrange = x[0], x[-1] - - # # print(f"xrange: {self._xrange}") - - # # XXX: lol brutal, the internals of `CurvePoint` (inherited by - # # our `LineDot`) required ``.getData()`` to work.. - # self.xData = x - # self.yData = y - - # # downsampling incremental state checking - # uppx = self.x_uppx() - # px_width = self.px_width() - # uppx_diff = (uppx - self._last_uppx) - - # new_sample_rate = False - # should_ds = self._in_ds - # showing_src_data = self._in_ds - # # should_redraw = False - - # # by default we only pull data up to the last (current) index - # x_out = x[:slice_to_head] - # y_out = y[:slice_to_head] - - # # if a view range is passed, plan to draw the - # # source ouput that's "in view" of the chart. - # if ( - # view_range - # # and not self._in_ds - # # and not prepend_length > 0 - # ): - # # print(f'{self._name} vr: {view_range}') - - # # by default we only pull data up to the last (current) index - # x_out, y_out = x_iv[:slice_to_head], y_iv[:slice_to_head] - # profiler(f'view range slice {view_range}') - - # vl, vr = view_range - - # # last_ivr = self._x_iv_range - # # ix_iv, iy_iv = self._x_iv_range = (x_iv[0], x_iv[-1]) - - # zoom_or_append = False - # last_vr = self._vr - # last_ivr = self._avr - - # if last_vr: - # # relative slice indices - # lvl, lvr = last_vr - # # abs slice indices - # al, ar = last_ivr - - # # append_length = int(x[-1] - istop) - # # append_length = int(x_iv[-1] - ar) - - # # left_change = abs(x_iv[0] - al) >= 1 - # # right_change = abs(x_iv[-1] - ar) >= 1 - - # if ( - # # likely a zoom view change - # (vr - lvr) > 2 or vl < lvl - # # append / prepend update - # # we had an append update where the view range - # # didn't change but the data-viewed (shifted) - # # underneath, so we need to redraw. - # # or left_change and right_change and last_vr == view_range - - # # not (left_change and right_change) and ivr - # # ( - # # or abs(x_iv[ivr] - livr) > 1 - # ): - # zoom_or_append = True - - # # if last_ivr: - # # liivl, liivr = last_ivr - - # if ( - # view_range != last_vr - # and ( - # append_length > 1 - # or zoom_or_append - # ) - # ): - # should_redraw = True - # # print("REDRAWING BRUH") - - # self._vr = view_range - # self._avr = x_iv[0], x_iv[slice_to_head] - - # # x_last = x_iv[-1] - # # y_last = y_iv[-1] - # # self._last_vr = view_range - - # # self.disable_cache() - # # flip_cache = True - - # if prepend_length > 0: - # should_redraw = True - - # # check for downsampling conditions - # if ( - # # std m4 downsample conditions - # abs(uppx_diff) >= 1 - # ): - # log.info( - # f'{self._name} sampler change: {self._last_uppx} -> {uppx}' - # ) - # self._last_uppx = uppx - # new_sample_rate = True - # showing_src_data = False - # should_redraw = True - # should_ds = True - - # elif ( - # uppx <= 2 - # and self._in_ds - # ): - # # we should de-downsample back to our original - # # source data so we clear our path data in prep - # # to generate a new one from original source data. - # should_redraw = True - # new_sample_rate = True - # should_ds = False - # showing_src_data = True - - # # no_path_yet = self.path is None - # if ( - # self.path is None - # or should_redraw - # or new_sample_rate - # or prepend_length > 0 - # ): - # if should_redraw: - # if self.path: - # self.path.clear() - # profiler('cleared paths due to `should_redraw=True`') - - # if self.fast_path: - # self.fast_path.clear() - - # profiler('cleared paths due to `should_redraw` set') - - # if new_sample_rate and showing_src_data: - # # if self._in_ds: - # log.info(f'DEDOWN -> {self._name}') - - # self._in_ds = False - - # elif should_ds and uppx > 1: - - # x_out, y_out = xy_downsample( - # x_out, - # y_out, - # uppx, - # ) - # profiler(f'FULL PATH downsample redraw={should_ds}') - # self._in_ds = True - - # self.path = pg.functions.arrayToQPath( - # x_out, - # y_out, - # connect='all', - # finiteCheck=False, - # path=self.path, - # ) - # self.prepareGeometryChange() - # profiler( - # 'generated fresh path. ' - # f'(should_redraw: {should_redraw} ' - # f'should_ds: {should_ds} new_sample_rate: {new_sample_rate})' - # ) - # # profiler(f'DRAW PATH IN VIEW -> {self._name}') - - # # reserve mem allocs see: - # # - https://doc.qt.io/qt-5/qpainterpath.html#reserve - # # - https://doc.qt.io/qt-5/qpainterpath.html#capacity - # # - https://doc.qt.io/qt-5/qpainterpath.html#clear - # # XXX: right now this is based on had hoc checks on a - # # hidpi 3840x2160 4k monitor but we should optimize for - # # the target display(s) on the sys. - # # if no_path_yet: - # # self.path.reserve(int(500e3)) - - # # TODO: get this piecewise prepend working - right now it's - # # giving heck on vwap... - # # elif prepend_length: - # # breakpoint() - - # # prepend_path = pg.functions.arrayToQPath( - # # x[0:prepend_length], - # # y[0:prepend_length], - # # connect='all' - # # ) - - # # # swap prepend path in "front" - # # old_path = self.path - # # self.path = prepend_path - # # # self.path.moveTo(new_x[0], new_y[0]) - # # self.path.connectPath(old_path) - - # elif ( - # append_length > 0 - # and do_append - # and not should_redraw - # # and not view_range - # ): - # print(f'{self._name} append len: {append_length}') - # new_x = x[-append_length - 2:slice_to_head] - # new_y = y[-append_length - 2:slice_to_head] - # profiler('sliced append path') - - # profiler( - # f'diffed array input, append_length={append_length}' - # ) - - # # if should_ds: - # # new_x, new_y = xy_downsample( - # # new_x, - # # new_y, - # # uppx, - # # ) - # # profiler(f'fast path downsample redraw={should_ds}') - - # append_path = pg.functions.arrayToQPath( - # new_x, - # new_y, - # connect='all', - # finiteCheck=False, - # path=self.fast_path, - # ) - # profiler('generated append qpath') - - # if self.use_fpath: - # # an attempt at trying to make append-updates faster.. - # if self.fast_path is None: - # self.fast_path = append_path - # # self.fast_path.reserve(int(6e3)) - # else: - # self.fast_path.connectPath(append_path) - # size = self.fast_path.capacity() - # profiler(f'connected fast path w size: {size}') - - # # print(f"append_path br: {append_path.boundingRect()}") - # # self.path.moveTo(new_x[0], new_y[0]) - # # path.connectPath(append_path) - - # # XXX: lol this causes a hang.. - # # self.path = self.path.simplified() - # else: - # size = self.path.capacity() - # profiler(f'connected history path w size: {size}') - # self.path.connectPath(append_path) - - # # other merging ideas: - # # https://stackoverflow.com/questions/8936225/how-to-merge-qpainterpaths - # # path.addPath(append_path) - # # path.closeSubpath() - - # # TODO: try out new work from `pyqtgraph` main which - # # should repair horrid perf: - # # https://github.com/pyqtgraph/pyqtgraph/pull/2032 - # # ok, nope still horrible XD - # # if self._fill: - # # # XXX: super slow set "union" op - # # self.path = self.path.united(append_path).simplified() - - # # self.disable_cache() - # # flip_cache = True - - # # if draw_last: - # # self.draw_last(x, y) - # # profiler('draw last segment') - - # # if flip_cache: - # # # # XXX: seems to be needed to avoid artifacts (see above). - # # self.setCacheMode(QGraphicsItem.DeviceCoordinateCache) - - # # trigger redraw of path - # # do update before reverting to cache mode - # self.update() - # profiler('.update()') - def draw_last( self, x: np.ndarray,