Skip to content

Commit 40f933c

Browse files
committed
Add an the option to append an infinite line going out from the lastest point into the future for ArchivePlotCurveItem
1 parent 239d255 commit 40f933c

File tree

1 file changed

+72
-3
lines changed

1 file changed

+72
-3
lines changed

pydm/widgets/archiver_time_plot.py

+72-3
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
import numpy as np
55
from collections import OrderedDict
66
from typing import List, Optional
7-
from pyqtgraph import DateAxisItem, ErrorBarItem
7+
from pyqtgraph import DateAxisItem, ErrorBarItem, mkPen
88
from pydm.utilities import remove_protocol, is_qt_designer
99
from pydm.widgets.channel import PyDMChannel
1010
from pydm.widgets.timeplot import TimePlotCurveItem
1111
from pydm.widgets import PyDMTimePlot
12-
from qtpy.QtCore import QObject, QTimer, Property, Signal, Slot
12+
from qtpy.QtCore import QObject, QTimer, Property, Signal, Slot, Qt
1313
from qtpy.QtGui import QColor
1414
import logging
1515
from math import * # noqa
@@ -51,9 +51,15 @@ class ArchivePlotCurveItem(TimePlotCurveItem):
5151
archive_data_received_signal = Signal()
5252
archive_channel_connection = Signal(bool)
5353
prompt_archive_request = Signal()
54+
axis_time_plot = Signal(str)
5455

5556
def __init__(
56-
self, channel_address: Optional[str] = None, use_archive_data: bool = True, liveData: bool = True, **kws
57+
self,
58+
channel_address: Optional[str] = None,
59+
use_archive_data: bool = True,
60+
liveData: bool = True,
61+
current_point_always_vis: bool = False,
62+
**kws
5763
):
5864
self.archive_channel = None
5965
super(ArchivePlotCurveItem, self).__init__(**kws)
@@ -62,6 +68,11 @@ def __init__(
6268
self._archiveBufferSize = DEFAULT_ARCHIVE_BUFFER_SIZE
6369
self.archive_data_buffer = np.zeros((2, self._archiveBufferSize), order="f", dtype=float)
6470
self._liveData = liveData
71+
self.current_point_always_vis = current_point_always_vis
72+
self._extension_line = BasePlotCurveItem()
73+
74+
if not self.current_point_always_vis:
75+
self._extension_line.hide()
6576

6677
# When optimized or mean value data is requested, we can display error bars representing
6778
# the full range of values retrieved
@@ -242,10 +253,46 @@ def redrawCurve(self, min_x=None, max_x=None) -> None:
242253
)
243254

244255
self.setData(y=y, x=x)
256+
257+
if self.current_point_always_vis:
258+
self.add_infinite_line()
259+
else:
260+
self._extension_line.hide()
261+
245262
except (ZeroDivisionError, OverflowError, TypeError):
246263
# Solve an issue with pyqtgraph and initial downsampling
247264
pass
248265

266+
def add_infinite_line(self) -> None:
267+
"""
268+
Creates a dotted line from the lastest point in the buffer
269+
(live or archived depending on if live data is active).
270+
"""
271+
if self._liveData:
272+
if self.data_buffer.size == 0:
273+
return
274+
x_last = self.data_buffer[:, -1]
275+
y_last = self.data_buffer[:, -1]
276+
else:
277+
if self.archive_data_buffer.size == 0:
278+
return
279+
x_last = self.archive_data_buffer[:, -1]
280+
y_last = self.archive_data_buffer[:, -1]
281+
282+
x_infinity = x_last[0] + APPROX_SECONDS_300_YEARS
283+
284+
x_line = np.array([x_last[0], x_infinity])
285+
y_line = np.array([y_last[1], y_last[1]])
286+
287+
dotted_pen = mkPen(self._pen.color(), width=self._pen.width(), style=Qt.DotLine)
288+
289+
self._extension_line.setFillLevel = None
290+
self._extension_line.setBrush = None
291+
self._extension_line.setPen(dotted_pen)
292+
self._extension_line.setData(x_line, y_line)
293+
294+
self._extension_line.show()
295+
249296
def initializeArchiveBuffer(self) -> None:
250297
"""
251298
Initialize the archive data buffer used for this curve.
@@ -319,6 +366,18 @@ def receiveNewValue(self, new_value):
319366
if self._liveData:
320367
super().receiveNewValue(new_value)
321368

369+
@BasePlotCurveItem.y_axis_name.setter
370+
def y_axis_name(self, axis_name: str) -> None:
371+
"""
372+
Set the name of the y-axis that should be associated with this curve.
373+
Also move's the curve's error bar item.
374+
Parameters
375+
----------
376+
axis_name: str
377+
"""
378+
BasePlotCurveItem.y_axis_name.fset(self, axis_name)
379+
self.axis_time_plot.emit(axis_name)
380+
322381

323382
class FormulaCurveItem(BasePlotCurveItem):
324383
"""
@@ -1009,10 +1068,20 @@ def addYChannel(
10091068
)
10101069
if not is_qt_designer():
10111070
self.requestDataFromArchiver()
1071+
1072+
if yAxisName is not None:
1073+
self.plotItem.linkDataToAxis(curve._extension_line, yAxisName)
1074+
curve.axis_time_plot.connect(self.moveExtensionLine)
1075+
10121076
return curve
10131077

10141078
def addFormulaChannel(self, yAxisName: str, **kwargs) -> FormulaCurveItem:
10151079
"""Creates a FormulaCurveItem and links it to the given y axis"""
10161080
FormulaCurve = FormulaCurveItem(yAxisName=yAxisName, **kwargs)
10171081
self.plotItem.linkDataToAxis(FormulaCurve, yAxisName)
10181082
return FormulaCurve
1083+
1084+
@Slot(str)
1085+
def moveExtensionLine(self, name: str) -> None:
1086+
curve = self.sender()
1087+
self.plotItem.linkDataToAxis(curve._extension_line, name)

0 commit comments

Comments
 (0)