diff --git a/examples/plottingItems.py b/examples/plottingItems.py
index ffb808b5..a7926826 100644
--- a/examples/plottingItems.py
+++ b/examples/plottingItems.py
@@ -17,12 +17,14 @@ win.resize(1000,600)
pg.setConfigOptions(antialias=True)
p1 = win.addPlot(title="Plot Items example", y=np.random.normal(size=100))
-inf1 = pg.InfiniteLine(movable=True, angle=90, label=True, textPosition=[0.5, 0.2], textColor=(200,200,100), textFill=(200,200,200,50))
-inf2 = pg.InfiniteLine(movable=True, angle=0, label=True, pen=(0, 0, 200), textColor=(200,0,0), bounds = [-2, 2], suffix="mm", hoverPen=(0,200,0), draggableLabel=True, textFill=0.5)
-inf3 = pg.InfiniteLine(movable=True, angle=45)
+inf1 = pg.InfiniteLine(movable=True, angle=90, text='x={value:0.2f}',
+ textOpts={'position':0.2, 'color': (200,200,100), 'fill': (200,200,200,50)})
+inf2 = pg.InfiniteLine(movable=True, angle=0, pen=(0, 0, 200), bounds = [-2, 2], hoverPen=(0,200,0), text='y={value:0.2f}mm',
+ textOpts={'color': (200,0,0), 'movable': True, 'fill': 0.5})
+inf3 = pg.InfiniteLine(movable=True, angle=45, text='diagonal', textOpts={'rotateAxis': [1, 0]})
inf1.setPos([2,2])
-inf1.setTextLocation(position=0.75)
-inf2.setTextLocation(shift=0.8)
+#inf1.setTextLocation(position=0.75)
+#inf2.setTextLocation(shift=0.8)
p1.addItem(inf1)
p1.addItem(inf2)
p1.addItem(inf3)
diff --git a/examples/text.py b/examples/text.py
index 23f527e3..43302e96 100644
--- a/examples/text.py
+++ b/examples/text.py
@@ -23,7 +23,7 @@ plot.setWindowTitle('pyqtgraph example: text')
curve = plot.plot(x,y) ## add a single curve
## Create text object, use HTML tags to specify color/size
-text = pg.TextItem(html='
This is the
PEAK
', anchor=(-0.3,1.3), border='w', fill=(0, 0, 255, 100))
+text = pg.TextItem(html='This is the
PEAK
', anchor=(-0.3,0.5), angle=45, border='w', fill=(0, 0, 255, 100))
plot.addItem(text)
text.setPos(0, y.max())
diff --git a/pyqtgraph/graphicsItems/InfiniteLine.py b/pyqtgraph/graphicsItems/InfiniteLine.py
index f4b25860..e7cc12ce 100644
--- a/pyqtgraph/graphicsItems/InfiniteLine.py
+++ b/pyqtgraph/graphicsItems/InfiniteLine.py
@@ -31,9 +31,7 @@ class InfiniteLine(GraphicsObject):
sigPositionChanged = QtCore.Signal(object)
def __init__(self, pos=None, angle=90, pen=None, movable=False, bounds=None,
- hoverPen=None, label=False, textColor=None, textFill=None,
- textPosition=[0.05, 0.5], textFormat="{:.3f}", draggableLabel=False,
- suffix=None, name='InfiniteLine'):
+ hoverPen=None, text=None, textOpts=None, name=None):
"""
=============== ==================================================================
**Arguments:**
@@ -49,21 +47,12 @@ class InfiniteLine(GraphicsObject):
Default pen is red.
bounds Optional [min, max] bounding values. Bounds are only valid if the
line is vertical or horizontal.
- label if True, a label is displayed next to the line to indicate its
- location in data coordinates
- textColor color of the label. Can be any argument fn.mkColor can understand.
- textFill A brush to use when filling within the border of the text.
- textPosition list of float (0-1) that defines when the precise location of the
- label. The first float governs the location of the label in the
- direction of the line, whereas the second one governs the shift
- of the label from one side of the line to the other in the
- orthogonal direction.
- textFormat Any new python 3 str.format() format.
- draggableLabel Bool. If True, the user can relocate the label during the dragging.
- If set to True, the first entry of textPosition is no longer
- useful.
- suffix If not None, corresponds to the unit to show next to the label
- name name of the item
+ text Text to be displayed in a label attached to the line, or
+ None to show no label (default is None). May optionally
+ include formatting strings to display the line value.
+ textOpts A dict of keyword arguments to use when constructing the
+ text label. See :class:`InfLineLabel`.
+ name Name of the item
=============== ==================================================================
"""
@@ -79,18 +68,10 @@ class InfiniteLine(GraphicsObject):
self.p = [0, 0]
self.setAngle(angle)
- if textColor is None:
- textColor = (200, 200, 100)
- self.textColor = textColor
- self.textFill = textFill
- self.textPosition = textPosition
- self.suffix = suffix
-
-
- self.textItem = InfLineLabel(self, fill=textFill)
- self.textItem.setParentItem(self)
- self.setDraggableLabel(draggableLabel)
- self.showLabel(label)
+ if text is not None:
+ textOpts = {} if textOpts is None else textOpts
+ self.textItem = InfLineLabel(self, text=text, **textOpts)
+ self.textItem.setParentItem(self)
self.anchorLeft = (1., 0.5)
self.anchorRight = (0., 0.5)
@@ -110,8 +91,6 @@ class InfiniteLine(GraphicsObject):
self.setHoverPen(hoverPen)
self.currentPen = self.pen
- self.format = textFormat
-
self._name = name
# Cache complex value for drawing speed-up (#PR267)
@@ -308,46 +287,7 @@ class InfiniteLine(GraphicsObject):
(eg, the view range has changed or the view was resized)
"""
self._invalidateCache()
- self.textItem.updatePosition()
-
- def showLabel(self, state):
- """
- Display or not the label indicating the location of the line in data
- coordinates.
-
- ============== ======================================================
- **Arguments:**
- state If True, the label is shown. Otherwise, it is hidden.
- ============== ======================================================
- """
- self.textItem.setVisible(state)
-
- def setTextLocation(self, position=0.05, shift=0.5):
- """
- Set the parameters that defines the location of the label on the axis.
- The position *parameter* governs the location of the label in the
- direction of the line, whereas the *shift* governs the shift of the
- label from one side of the line to the other in the orthogonal
- direction.
-
- ============== ======================================================
- **Arguments:**
- position float (range of value = [0-1])
- shift float (range of value = [0-1]).
- ============== ======================================================
- """
- self.textItem.orthoPos = position
- self.textItem.shiftPos = shift
- self.textItem.updatePosition()
-
- def setDraggableLabel(self, state):
- """
- Set the state of the label regarding its behaviour during the dragging
- of the line. If True, then the location of the label change during the
- dragging of the line.
- """
- self.textItem.setMovable(state)
-
+
def setName(self, name):
self._name = name
@@ -356,13 +296,21 @@ class InfiniteLine(GraphicsObject):
class InfLineLabel(TextItem):
- # a text label that attaches itself to an InfiniteLine
- def __init__(self, line, **kwds):
+ """
+ A TextItem that attaches itself to an InfiniteLine.
+
+ This class extends TextItem with the following features:
+
+ * Automatically positions adjacent to the line at a fixed position along
+ the line and within the view box.
+ * Automatically reformats text when the line value has changed.
+ * Can optionally be dragged to change its location along the line.
+ """
+ def __init__(self, line, text="", movable=False, position=0.5, **kwds):
self.line = line
- self.movable = False
- self.dragAxis = None # 0=x, 1=y
- self.orthoPos = 0.5 # text will always be placed on the line at a position relative to view bounds
- self.format = "{value}"
+ self.movable = movable
+ self.orthoPos = position # text will always be placed on the line at a position relative to view bounds
+ self.format = text
self.line.sigPositionChanged.connect(self.valueChanged)
TextItem.__init__(self, **kwds)
self.valueChanged()
@@ -412,7 +360,7 @@ class InfLineLabel(TextItem):
return
rel = self._posToRel(ev.pos())
- self.orthoPos = self._startPosition + rel - self._cursorOffset
+ self.orthoPos = np.clip(self._startPosition + rel - self._cursorOffset, 0, 1)
self.updatePosition()
if ev.isFinish():
self._moving = False
@@ -427,6 +375,10 @@ class InfLineLabel(TextItem):
if not ev.isExit() and self.movable:
ev.acceptDrags(QtCore.Qt.LeftButton)
+ def viewTransformChanged(self):
+ self.updatePosition()
+ TextItem.viewTransformChanged(self)
+
def _posToRel(self, pos):
# convert local position to relative position along line between view bounds
view = self.getViewBox()
diff --git a/pyqtgraph/graphicsItems/TextItem.py b/pyqtgraph/graphicsItems/TextItem.py
index c29b4f44..657e425b 100644
--- a/pyqtgraph/graphicsItems/TextItem.py
+++ b/pyqtgraph/graphicsItems/TextItem.py
@@ -1,13 +1,16 @@
+import numpy as np
from ..Qt import QtCore, QtGui
from ..Point import Point
-from .UIGraphicsItem import *
from .. import functions as fn
+from .GraphicsObject import GraphicsObject
-class TextItem(UIGraphicsItem):
+
+class TextItem(GraphicsObject):
"""
GraphicsItem displaying unscaled text (the text will always appear normal even inside a scaled ViewBox).
"""
- def __init__(self, text='', color=(200,200,200), html=None, anchor=(0,0), border=None, fill=None, angle=0):
+ def __init__(self, text='', color=(200,200,200), html=None, anchor=(0,0),
+ border=None, fill=None, angle=0, rotateAxis=None):
"""
============== =================================================================================
**Arguments:**
@@ -20,16 +23,19 @@ class TextItem(UIGraphicsItem):
sets the lower-right corner.
*border* A pen to use when drawing the border
*fill* A brush to use when filling within the border
+ *angle* Angle in degrees to rotate text. Default is 0; text will be displayed upright.
+ *rotateAxis* If None, then a text angle of 0 always points along the +x axis of the scene.
+ If a QPointF or (x,y) sequence is given, then it represents a vector direction
+ in the parent's coordinate system that the 0-degree line will be aligned to. This
+ Allows text to follow both the position and orientation of its parent while still
+ discarding any scale and shear factors.
============== =================================================================================
"""
-
- ## not working yet
- #*angle* Angle in degrees to rotate text (note that the rotation assigned in this item's
- #transformation will be ignored)
self.anchor = Point(anchor)
+ self.rotateAxis = None if rotateAxis is None else Point(rotateAxis)
#self.angle = 0
- UIGraphicsItem.__init__(self)
+ GraphicsObject.__init__(self)
self.textItem = QtGui.QGraphicsTextItem()
self.textItem.setParentItem(self)
self._lastTransform = None
@@ -101,9 +107,8 @@ class TextItem(UIGraphicsItem):
self.updateText()
def setAngle(self, angle):
- self.textItem.resetTransform()
- self.textItem.rotate(angle)
- self.updateText()
+ self.angle = angle
+ self.updateTransform()
def updateText(self):
# update text position to obey anchor
@@ -120,9 +125,6 @@ class TextItem(UIGraphicsItem):
#s = self._exportOpts['resolutionScale']
#self.textItem.scale(s, s)
- def viewRangeChanged(self):
- self.updateText()
-
def boundingRect(self):
return self.textItem.mapToParent(self.textItem.boundingRect()).boundingRect()
@@ -160,7 +162,19 @@ class TextItem(UIGraphicsItem):
t = pt.inverted()[0]
# reset translation
t.setMatrix(t.m11(), t.m12(), t.m13(), t.m21(), t.m22(), t.m23(), 0, 0, t.m33())
+
+ # apply rotation
+ angle = -self.angle
+ if self.rotateAxis is not None:
+ d = pt.map(self.rotateAxis) - pt.map(Point(0, 0))
+ a = np.arctan2(d.y(), d.x()) * 180 / np.pi
+ angle += a
+ t.rotate(angle)
+
self.setTransform(t)
self._lastTransform = pt
+
+ self.updateText()
+
\ No newline at end of file