/
zolnikov
/
database_analyzer
Обзор
Документация
Войти
/
zolnikov
/
database_analyzer
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
window/graph_window.py
220 строк
7 KB
Jaman
версия 01.06.26
01 июл 2026, 21:24
01 июл 2026, 21:24
93f1e01
Код
Авторство
О чём код?
import numpy as np import pyqtgraph as pg from PySide6 import QtWidgets, QtCore from pyqtgraph import DateAxisItem from common import TimeObject from qt import window_graph class ScatterGroup: def __init__(self, x, y, color, name, symbol, type_msg): self.x = np.array(x) self.y = np.array(y) self.name = name self.type_msg = type_msg self.default_brush = pg.mkBrush(color) self.selected_brush = pg.mkBrush(0, 120, 255) # СИНИЙ self.selected_mask = np.zeros(len(x), dtype=bool) self.curve = pg.PlotCurveItem( x=self.x, y=self.y, pen=pg.mkPen(color=color, width=2), name=name ) self.scatter = pg.ScatterPlotItem( x=self.x, y=self.y, size=7, brush=self.default_brush, symbol=symbol, pen=pg.mkPen(None), ) def add_to_viewbox(self, viewbox): viewbox.addItem(self.curve) viewbox.addItem(self.scatter) def update_colors(self): brushes = np.where( self.selected_mask, self.selected_brush, self.default_brush ) self.scatter.setBrush(list(brushes)) def clear_selection(self): self.selected_mask[:] = False self.update_colors() def select_in_rect(self, rect): x_min = rect.left() x_max = rect.right() y_min = rect.top() y_max = rect.bottom() self.selected_mask = ( (self.x >= x_min) & (self.x <= x_max) & (self.y >= y_min) & (self.y <= y_max) ) self.update_colors() def selected_timestamps(self): return self.x[self.selected_mask] class SelectViewBox(pg.ViewBox): selection_changed = QtCore.Signal() def __init__(self): super().__init__() self.setLimits(yMin=0) self.groups = [] self.start_pos = None self.selection_rect = QtWidgets.QGraphicsRectItem() self.selection_rect.setPen(pg.mkPen('w', width=2)) self.selection_rect.setBrush(pg.mkBrush(255, 255, 255, 40)) self.selection_rect.hide() self.addItem(self.selection_rect) def add_group(self, group): self.groups.append(group) group.add_to_viewbox(self) # Сброс выделения def clear_selection(self): for group in self.groups: group.clear_selection() self.selection_rect.hide() self.selection_changed.emit() # Обновление выделения def update_selection(self): rect = self.selection_rect.rect() for group in self.groups: group.select_in_rect(rect) self.selection_changed.emit() # Все выделенные timestamps def all_selected_timestamps(self): result = [] for group in self.groups: result.extend(group.selected_timestamps()) return np.asarray(result) def all_selected_items(self): result = [] for group in self.groups: idx = np.where(group.selected_mask)[0] if len(group.x[idx]) > 0: result.append({group.type_msg: group.x[idx], } ) return result def mouseClickEvent(self, ev): modifiers = QtWidgets.QApplication.keyboardModifiers() # ЛКМ без Ctrl -> сброс if (ev.button() == QtCore.Qt.MouseButton.LeftButton and modifiers == QtCore.Qt.KeyboardModifier.NoModifier): self.clear_selection() ev.accept() return super().mouseClickEvent(ev) def mouseDragEvent(self, ev, axis=None): modifiers = QtWidgets.QApplication.keyboardModifiers() if (modifiers == QtCore.Qt.KeyboardModifier.ControlModifier and ev.button() == QtCore.Qt.MouseButton.LeftButton): ev.accept() pos = self.mapSceneToView(ev.scenePos()) # START if ev.isStart(): self.start_pos = pos rect = QtCore.QRectF(pos, pos) self.selection_rect.setRect(rect) self.selection_rect.show() # FINISH elif ev.isFinish(): self.update_selection() # MOVE else: rect = QtCore.QRectF(self.start_pos, pos).normalized() self.selection_rect.setRect(rect) self.update_selection() else: super().mouseDragEvent(ev, axis) class WindowGraph(QtWidgets.QWidget, window_graph.Ui_Form): def __init__(self, logic_parent): self.logic_parent = logic_parent super(WindowGraph, self).__init__() self.setupUi(self) self.setWindowTitle('График событий') self.view_box = SelectViewBox() self.plot_widget = pg.PlotWidget(viewBox=self.view_box) plot = self.plot_widget.getPlotItem() date_axis = DateAxisItem(orientation='bottom', format='%Y-%m-%d %H:%M:%S') self.plot_widget.setAxisItems({'bottom': date_axis}) self.verticalLayout.addWidget(self.plot_widget) self.plot_widget.setLabel('left', 'Количество событий') self.plot_widget.setLabel('bottom', 'Время') self.plot_widget.setWindowTitle('Интенсивность событий') self.plot_widget.showGrid(x=True, y=True) self.legend = plot.addLegend(offset=(1, 1), colCount=3) # self.view_box.selection_changed.connect(self.on_selection_changed) def set_data(self, df, type_msg, color='b', name='events', symbol='o'): offset_sec = TimeObject.get_time_offset_seconds() x = [ts.timestamp() - offset_sec for ts in df.index] # convert_datetime = datetime.fromtimestamp(x[0], tz=UTC) # print(f'original_datetime {origin_data}') # print(f'convert_datetime {convert_datetime}') y = df.values # self.plot_widget.plot(x, # y, # pen=pg.mkPen(color, width=2), # symbol=symbol, # symbolSize=7, # name=name) group = ScatterGroup(x, y, color, name, symbol, type_msg) self.view_box.add_group(group) self.legend.addItem(group.curve, name) def keyPressEvent(self, event): if event.key() == QtCore.Qt.Key.Key_Escape: self.view_box.clear_selection() return elif event.key() == QtCore.Qt.Key.Key_Return or event.key() == QtCore.Qt.Key.Key_Enter: self.show_select_data_points() super().keyPressEvent(event) def on_selection_changed(self): timestamps = self.view_box.all_selected_timestamps() print("Выделено timestamps:", len(timestamps)) print(timestamps) pass def show_select_data_points(self): selected = self.view_box.all_selected_items() if hasattr(self.logic_parent, 'show_data_select_points'): self.logic_parent.show_data_select_points(selected) def clear_data(self): self.legend.clear() self.plot_widget.clear()