Move marker factory funcs to new mod

basic_orders
Tyler Goodlet 2021-03-18 16:59:22 -04:00
parent 55de079320
commit 5610807b8e
2 changed files with 146 additions and 120 deletions

View File

@ -0,0 +1,144 @@
# piker: trading gear for hackers
# Copyright (C) Tyler Goodlet (in stewardship for piker0)
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
Annotations for ur faces.
"""
from PyQt5 import QtCore, QtGui
from PyQt5.QtGui import QGraphicsPathItem
from pyqtgraph import Point, functions as fn, Color
import numpy as np
def mk_marker(
style,
size: float = 20.0,
use_qgpath: bool = True,
) -> QGraphicsPathItem:
"""Add a marker to be displayed on the line wrapped in a ``QGraphicsPathItem``
ready to be placed using scene coordinates (not view).
**Arguments**
style String indicating the style of marker to add:
``'<|'``, ``'|>'``, ``'>|'``, ``'|<'``, ``'<|>'``,
``'>|<'``, ``'^'``, ``'v'``, ``'o'``
size Size of the marker in pixels. Default is 10.0.
"""
path = QtGui.QPainterPath()
if style == 'o':
path.addEllipse(QtCore.QRectF(-0.5, -0.5, 1, 1))
# arrow pointing away-from the top of line
if '<|' in style:
p = QtGui.QPolygonF([Point(0.5, 0), Point(0, -0.5), Point(-0.5, 0)])
path.addPolygon(p)
path.closeSubpath()
# arrow pointing away-from the bottom of line
if '|>' in style:
p = QtGui.QPolygonF([Point(0.5, 0), Point(0, 0.5), Point(-0.5, 0)])
path.addPolygon(p)
path.closeSubpath()
# arrow pointing in-to the top of line
if '>|' in style:
p = QtGui.QPolygonF([Point(0.5, -0.5), Point(0, 0), Point(-0.5, -0.5)])
path.addPolygon(p)
path.closeSubpath()
# arrow pointing in-to the bottom of line
if '|<' in style:
p = QtGui.QPolygonF([Point(0.5, 0.5), Point(0, 0), Point(-0.5, 0.5)])
path.addPolygon(p)
path.closeSubpath()
if '^' in style:
p = QtGui.QPolygonF([Point(0, -0.5), Point(0.5, 0), Point(0, 0.5)])
path.addPolygon(p)
path.closeSubpath()
if 'v' in style:
p = QtGui.QPolygonF([Point(0, -0.5), Point(-0.5, 0), Point(0, 0.5)])
path.addPolygon(p)
path.closeSubpath()
# self._maxMarkerSize = max([m[2] / 2. for m in self.markers])
if use_qgpath:
path = QGraphicsPathItem(path)
path.scale(size, size)
return path
def qgo_draw_markers(
markers: list,
color: Color,
p: QtGui.QPainter,
left: float,
right: float,
right_offset: float,
) -> float:
"""Paint markers in ``pg.GraphicsItem`` style by first
removing the view transform for the painter, drawing the markers
in scene coords, then restoring the view coords.
"""
# paint markers in native coordinate system
orig_tr = p.transform()
start = orig_tr.map(Point(left, 0))
end = orig_tr.map(Point(right, 0))
up = orig_tr.map(Point(left, 1))
dif = end - start
# length = Point(dif).length()
angle = np.arctan2(dif.y(), dif.x()) * 180 / np.pi
p.resetTransform()
p.translate(start)
p.rotate(angle)
up = up - start
det = up.x() * dif.y() - dif.x() * up.y()
p.scale(1, 1 if det > 0 else -1)
p.setBrush(fn.mkBrush(color))
# p.setBrush(fn.mkBrush(self.currentPen.color()))
tr = p.transform()
sizes = []
for path, pos, size in markers:
p.setTransform(tr)
# XXX: we drop the "scale / %" placement
# x = length * pos
x = right_offset
p.translate(x, 0)
p.scale(size, size)
p.drawPath(path)
sizes.append(size)
p.setTransform(orig_tr)
return max(sizes)

View File

@ -23,10 +23,9 @@ from typing import Tuple, Optional, List
import pyqtgraph as pg
from pyqtgraph import Point, functions as fn
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QGraphicsPathItem
from PyQt5.QtCore import QPointF
import numpy as np
from .._annotate import mk_marker, qgo_draw_markers
from .._label import Label, vbr_left, right_axis
from .._style import (
hcolor,
@ -34,123 +33,6 @@ from .._style import (
)
def mk_marker(
style,
size: float = 20.0,
use_qgpath: bool = True,
) -> QGraphicsPathItem:
"""Add a marker to be displayed on the line wrapped in a ``QGraphicsPathItem``
ready to be placed using scene coordinates (not view).
**Arguments**
style String indicating the style of marker to add:
``'<|'``, ``'|>'``, ``'>|'``, ``'|<'``, ``'<|>'``,
``'>|<'``, ``'^'``, ``'v'``, ``'o'``
size Size of the marker in pixels. Default is 10.0.
"""
path = QtGui.QPainterPath()
if style == 'o':
path.addEllipse(QtCore.QRectF(-0.5, -0.5, 1, 1))
# arrow pointing away-from the top of line
if '<|' in style:
p = QtGui.QPolygonF([Point(0.5, 0), Point(0, -0.5), Point(-0.5, 0)])
path.addPolygon(p)
path.closeSubpath()
# arrow pointing away-from the bottom of line
if '|>' in style:
p = QtGui.QPolygonF([Point(0.5, 0), Point(0, 0.5), Point(-0.5, 0)])
path.addPolygon(p)
path.closeSubpath()
# arrow pointing in-to the top of line
if '>|' in style:
p = QtGui.QPolygonF([Point(0.5, -0.5), Point(0, 0), Point(-0.5, -0.5)])
path.addPolygon(p)
path.closeSubpath()
# arrow pointing in-to the bottom of line
if '|<' in style:
p = QtGui.QPolygonF([Point(0.5, 0.5), Point(0, 0), Point(-0.5, 0.5)])
path.addPolygon(p)
path.closeSubpath()
if '^' in style:
p = QtGui.QPolygonF([Point(0, -0.5), Point(0.5, 0), Point(0, 0.5)])
path.addPolygon(p)
path.closeSubpath()
if 'v' in style:
p = QtGui.QPolygonF([Point(0, -0.5), Point(-0.5, 0), Point(0, 0.5)])
path.addPolygon(p)
path.closeSubpath()
# self._maxMarkerSize = max([m[2] / 2. for m in self.markers])
if use_qgpath:
path = QGraphicsPathItem(path)
path.scale(size, size)
return path
def draw_markers(
markers: list,
color: pg.Color,
p: QtGui.QPainter,
left: float,
right: float,
right_offset: float,
) -> None:
"""Pain markers in ``pg.GraphicsItem`` style by first
removing the view transform for the painter, drawing the markers
in scene coords, then restoring the view coords.
"""
# paint markers in native coordinate system
orig_tr = p.transform()
start = orig_tr.map(Point(left, 0))
end = orig_tr.map(Point(right, 0))
up = orig_tr.map(Point(left, 1))
dif = end - start
# length = Point(dif).length()
angle = np.arctan2(dif.y(), dif.x()) * 180 / np.pi
p.resetTransform()
p.translate(start)
p.rotate(angle)
up = up - start
det = up.x() * dif.y() - dif.x() * up.y()
p.scale(1, 1 if det > 0 else -1)
p.setBrush(fn.mkBrush(color))
# p.setBrush(fn.mkBrush(self.currentPen.color()))
tr = p.transform()
sizes = []
for path, pos, size in markers:
p.setTransform(tr)
# XXX: we drop the "scale / %" placement
# x = length * pos
x = right_offset
p.translate(x, 0)
p.scale(size, size)
p.drawPath(path)
sizes.append(size)
p.setTransform(orig_tr)
return max(sizes)
# TODO: probably worth investigating if we can
# make .boundingRect() faster:
# https://stackoverflow.com/questions/26156486/determine-bounding-rect-of-line-in-qt
@ -506,7 +388,7 @@ class LevelLine(pg.InfiniteLine):
size = self.markers[0][2]
p.setPen(self.pen)
size = draw_markers(
size = qgo_draw_markers(
self.markers,
self.pen.color(),
p,