From 1a0e89d07e4b314f1ce5fec832566a3dfd9c4975 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Mon, 21 Mar 2022 09:20:54 -0400 Subject: [PATCH] Even more correct "default view" snap-to-pp-marker This makes the `'r'` hotkey snap the last bar to the middle of the pp line arrow marker no matter the zoom level. Now we also boot with approximately the most number of x units on screen that keep the bars graphics drawn in full (just before downsampling to a line). Moved some internals around to get this all in place, - drop `_anchors.marker_right_points()` and move it to a chart method. - change `.pre_l1_x()` -> `.pre_l1_xs()` and just have it return the two view-mapped x values from the former method. --- piker/ui/_anchors.py | 28 --------------- piker/ui/_annotate.py | 6 ++-- piker/ui/_chart.py | 80 ++++++++++++++++++++++++++++++------------- piker/ui/_lines.py | 7 ++-- 4 files changed, 61 insertions(+), 60 deletions(-) diff --git a/piker/ui/_anchors.py b/piker/ui/_anchors.py index 2d4345e2..5d8217c8 100644 --- a/piker/ui/_anchors.py +++ b/piker/ui/_anchors.py @@ -29,34 +29,6 @@ if TYPE_CHECKING: from ._label import Label -def marker_right_points( - chart: ChartPlotWidget, # noqa - marker_size: int = 20, - -) -> (float, float, float): - ''' - Return x-dimension, y-axis-aware, level-line marker oriented scene - values. - - X values correspond to set the end of a level line, end of - a paried level line marker, and the right most side of the "right" - axis respectively. - - ''' - # TODO: compute some sensible maximum value here - # and use a humanized scheme to limit to that length. - l1_len = chart._max_l1_line_len - ryaxis = chart.getAxis('right') - - r_axis_x = ryaxis.pos().x() - up_to_l1_sc = r_axis_x - l1_len - 10 - - marker_right = up_to_l1_sc - (1.375 * 2 * marker_size) - line_end = marker_right - (6/16 * marker_size) - - return line_end, marker_right, r_axis_x - - def vbr_left( label: Label, diff --git a/piker/ui/_annotate.py b/piker/ui/_annotate.py index 6af8ffe7..6e0e84d1 100644 --- a/piker/ui/_annotate.py +++ b/piker/ui/_annotate.py @@ -26,8 +26,6 @@ from PyQt5.QtWidgets import QGraphicsPathItem from pyqtgraph import Point, functions as fn, Color import numpy as np -from ._anchors import marker_right_points - def mk_marker_path( @@ -116,7 +114,7 @@ class LevelMarker(QGraphicsPathItem): self.get_level = get_level self._on_paint = on_paint - self.scene_x = lambda: marker_right_points(chart)[1] + self.scene_x = lambda: chart.marker_right_points()[1] self.level: float = 0 self.keep_in_view = keep_in_view @@ -169,7 +167,7 @@ class LevelMarker(QGraphicsPathItem): vr = view.state['viewRange'] ymn, ymx = vr[1] - # _, marker_right, _ = marker_right_points(line._chart) + # _, marker_right, _ = line._chart.marker_right_points() x = self.scene_x() if self.style == '>|': # short style, points "down-to" line diff --git a/piker/ui/_chart.py b/piker/ui/_chart.py index 705e3c84..b208cece 100644 --- a/piker/ui/_chart.py +++ b/piker/ui/_chart.py @@ -844,31 +844,52 @@ class ChartPlotWidget(pg.PlotWidget): QLineF(lbar, 0, rbar, 0) ).length() - def pre_l1_x( - self, - view_coords: bool = False, - - ) -> tuple[float, float]: + def pre_l1_xs(self) -> tuple[float, float]: ''' - Return the scene x-coord for the value just before + Return the view x-coord for the value just before the L1 labels on the y-axis as well as the length of that L1 label from the y-axis. ''' + line_end, marker_right, yaxis_x = self.marker_right_points() + view = self.view + line = view.mapToView( + QLineF(line_end, 0, yaxis_x, 0) + ) + return line.x1(), line.length() + + def marker_right_points( + self, + marker_size: int = 20, + + ) -> (float, float, float): + ''' + Return x-dimension, y-axis-aware, level-line marker oriented scene + values. + + X values correspond to set the end of a level line, end of + a paried level line marker, and the right most side of the "right" + axis respectively. + + ''' + # TODO: compute some sensible maximum value here + # and use a humanized scheme to limit to that length. l1_len = self._max_l1_line_len ryaxis = self.getAxis('right') - ryaxis_x = ryaxis.pos().x() - up_to_l1_sc = ryaxis_x - l1_len - if not view_coords: - return up_to_l1_sc, l1_len - else: - view = self.view - line = view.mapToView( - QLineF(up_to_l1_sc, 0, ryaxis_x, 0) - ) - return line.x1(), line.length() - def default_view(self) -> None: + r_axis_x = ryaxis.pos().x() + up_to_l1_sc = r_axis_x - l1_len - 10 + + marker_right = up_to_l1_sc - (1.375 * 2 * marker_size) + line_end = marker_right - (6/16 * marker_size) + + return line_end, marker_right, r_axis_x + + def default_view( + self, + steps_on_screen: Optional[int] = None + + ) -> None: ''' Set the view box to the "default" startup view of the scene. @@ -880,15 +901,25 @@ class ChartPlotWidget(pg.PlotWidget): return xfirst, xlast = index[0], index[-1] - view = self.view - vr = view.viewRange() - marker_pos, l1_len = self.pre_l1_x(view_coords=True) - end = xlast + l1_len - xl = vr[0][0] - begin = max(xl, xfirst) + brange = l, lbar, rbar, r = self.bars_range() + marker_pos, l1_len = self.pre_l1_xs() + end = xlast + l1_len + + if ( + rbar < 0 + or l < xfirst + ): + # set fixed bars count on screen that approx includes as + # many bars as possible before a downsample line is shown. + begin = xlast - round(6116 / 6) + + else: + begin = end - (r - l) + + # for debugging # print( - # f'view range: {vr}\n' + # f'bars range: {brange}\n' # f'xlast: {xlast}\n' # f'marker pos: {marker_pos}\n' # f'l1 len: {l1_len}\n' @@ -900,6 +931,7 @@ class ChartPlotWidget(pg.PlotWidget): if self._static_yrange == 'axis': self._static_yrange = None + view = self.view view.setXRange( min=begin, max=end, diff --git a/piker/ui/_lines.py b/piker/ui/_lines.py index df29e350..421d4ec8 100644 --- a/piker/ui/_lines.py +++ b/piker/ui/_lines.py @@ -29,7 +29,6 @@ from PyQt5.QtCore import QPointF from ._annotate import qgo_draw_markers, LevelMarker from ._anchors import ( - marker_right_points, vbr_left, right_axis, gpath_pin, @@ -333,7 +332,7 @@ class LevelLine(pg.InfiniteLine): vb_left, vb_right = self._endPoints vb = self.getViewBox() - line_end, marker_right, r_axis_x = marker_right_points(self._chart) + line_end, marker_right, r_axis_x = self._chart.marker_right_points() if self.show_markers and self.markers: @@ -399,7 +398,7 @@ class LevelLine(pg.InfiniteLine): def scene_endpoint(self) -> QPointF: if not self._right_end_sc: - line_end, _, _ = marker_right_points(self._chart) + line_end, _, _ = self._chart.marker_right_points() self._right_end_sc = line_end - 10 return QPointF(self._right_end_sc, self.scene_y()) @@ -417,7 +416,7 @@ class LevelLine(pg.InfiniteLine): self.getViewBox().scene().addItem(path) # place to just-left of L1 labels - rsc = self._chart.pre_l1_x()[0] + rsc = self._chart.pre_l1_xs()[0] path.setPos(QPointF(rsc, self.scene_y())) return path