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.mkts_backup
parent
4af941566a
commit
3b96b52474
|
@ -29,34 +29,6 @@ if TYPE_CHECKING:
|
||||||
from ._label import Label
|
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(
|
def vbr_left(
|
||||||
label: Label,
|
label: Label,
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,6 @@ from PyQt5.QtWidgets import QGraphicsPathItem
|
||||||
from pyqtgraph import Point, functions as fn, Color
|
from pyqtgraph import Point, functions as fn, Color
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from ._anchors import marker_right_points
|
|
||||||
|
|
||||||
|
|
||||||
def mk_marker_path(
|
def mk_marker_path(
|
||||||
|
|
||||||
|
@ -116,7 +114,7 @@ class LevelMarker(QGraphicsPathItem):
|
||||||
|
|
||||||
self.get_level = get_level
|
self.get_level = get_level
|
||||||
self._on_paint = on_paint
|
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.level: float = 0
|
||||||
self.keep_in_view = keep_in_view
|
self.keep_in_view = keep_in_view
|
||||||
|
|
||||||
|
@ -169,7 +167,7 @@ class LevelMarker(QGraphicsPathItem):
|
||||||
vr = view.state['viewRange']
|
vr = view.state['viewRange']
|
||||||
ymn, ymx = vr[1]
|
ymn, ymx = vr[1]
|
||||||
|
|
||||||
# _, marker_right, _ = marker_right_points(line._chart)
|
# _, marker_right, _ = line._chart.marker_right_points()
|
||||||
x = self.scene_x()
|
x = self.scene_x()
|
||||||
|
|
||||||
if self.style == '>|': # short style, points "down-to" line
|
if self.style == '>|': # short style, points "down-to" line
|
||||||
|
|
|
@ -844,31 +844,52 @@ class ChartPlotWidget(pg.PlotWidget):
|
||||||
QLineF(lbar, 0, rbar, 0)
|
QLineF(lbar, 0, rbar, 0)
|
||||||
).length()
|
).length()
|
||||||
|
|
||||||
def pre_l1_x(
|
def pre_l1_xs(self) -> tuple[float, float]:
|
||||||
self,
|
|
||||||
view_coords: bool = False,
|
|
||||||
|
|
||||||
) -> 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
|
the L1 labels on the y-axis as well as the length
|
||||||
of that L1 label from the y-axis.
|
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
|
l1_len = self._max_l1_line_len
|
||||||
ryaxis = self.getAxis('right')
|
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.
|
Set the view box to the "default" startup view of the scene.
|
||||||
|
|
||||||
|
@ -880,15 +901,25 @@ class ChartPlotWidget(pg.PlotWidget):
|
||||||
return
|
return
|
||||||
|
|
||||||
xfirst, xlast = index[0], index[-1]
|
xfirst, xlast = index[0], index[-1]
|
||||||
view = self.view
|
brange = l, lbar, rbar, r = self.bars_range()
|
||||||
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)
|
|
||||||
|
|
||||||
|
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(
|
# print(
|
||||||
# f'view range: {vr}\n'
|
# f'bars range: {brange}\n'
|
||||||
# f'xlast: {xlast}\n'
|
# f'xlast: {xlast}\n'
|
||||||
# f'marker pos: {marker_pos}\n'
|
# f'marker pos: {marker_pos}\n'
|
||||||
# f'l1 len: {l1_len}\n'
|
# f'l1 len: {l1_len}\n'
|
||||||
|
@ -900,6 +931,7 @@ class ChartPlotWidget(pg.PlotWidget):
|
||||||
if self._static_yrange == 'axis':
|
if self._static_yrange == 'axis':
|
||||||
self._static_yrange = None
|
self._static_yrange = None
|
||||||
|
|
||||||
|
view = self.view
|
||||||
view.setXRange(
|
view.setXRange(
|
||||||
min=begin,
|
min=begin,
|
||||||
max=end,
|
max=end,
|
||||||
|
|
|
@ -29,7 +29,6 @@ from PyQt5.QtCore import QPointF
|
||||||
|
|
||||||
from ._annotate import qgo_draw_markers, LevelMarker
|
from ._annotate import qgo_draw_markers, LevelMarker
|
||||||
from ._anchors import (
|
from ._anchors import (
|
||||||
marker_right_points,
|
|
||||||
vbr_left,
|
vbr_left,
|
||||||
right_axis,
|
right_axis,
|
||||||
gpath_pin,
|
gpath_pin,
|
||||||
|
@ -333,7 +332,7 @@ class LevelLine(pg.InfiniteLine):
|
||||||
vb_left, vb_right = self._endPoints
|
vb_left, vb_right = self._endPoints
|
||||||
vb = self.getViewBox()
|
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:
|
if self.show_markers and self.markers:
|
||||||
|
|
||||||
|
@ -399,7 +398,7 @@ class LevelLine(pg.InfiniteLine):
|
||||||
def scene_endpoint(self) -> QPointF:
|
def scene_endpoint(self) -> QPointF:
|
||||||
|
|
||||||
if not self._right_end_sc:
|
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
|
self._right_end_sc = line_end - 10
|
||||||
|
|
||||||
return QPointF(self._right_end_sc, self.scene_y())
|
return QPointF(self._right_end_sc, self.scene_y())
|
||||||
|
@ -417,7 +416,7 @@ class LevelLine(pg.InfiniteLine):
|
||||||
self.getViewBox().scene().addItem(path)
|
self.getViewBox().scene().addItem(path)
|
||||||
|
|
||||||
# place to just-left of L1 labels
|
# 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()))
|
path.setPos(QPointF(rsc, self.scene_y()))
|
||||||
|
|
||||||
return path
|
return path
|
||||||
|
|
Loading…
Reference in New Issue