From c3d9daa1b0e99a5cfef09b0b556e2769d677b24f Mon Sep 17 00:00:00 2001 From: WorldTeacher Date: Tue, 17 Jun 2025 16:13:20 +0200 Subject: [PATCH] replace datagraph with dataqtgraph implementation to fix a scrolling bug --- src/ui/widgets/graph.py | 110 +++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 57 deletions(-) diff --git a/src/ui/widgets/graph.py b/src/ui/widgets/graph.py index d480cdb..013916b 100644 --- a/src/ui/widgets/graph.py +++ b/src/ui/widgets/graph.py @@ -2,9 +2,12 @@ import random import sys from typing import Any, Union + import loguru -import pyqtgraph as pg -from PyQt6 import QtWidgets +from PySide6 import QtWidgets, QtCore, QtGui +from PySide6.QtCore import Qt +from PySide6.QtGui import QPainter, QPen, QColor +from PySide6.QtCharts import QChart, QChartView, QLineSeries, QValueAxis, QCategoryAxis from src import LOG_DIR @@ -30,21 +33,24 @@ def mergedicts(d1: dict[str, Any], d2: dict[str, Any]): res.update(d2_dict) # type: ignore return res - -class DataGraph(QtWidgets.QWidget): +class DataQtGraph(QtWidgets.QWidget): def __init__( self, title: str, - data=Union[dict[list, list], dict[list[dict[str, list[Any]]]]], - generateMissing: bool = False, - label: str = None, + data: dict, + generateMissing: bool, + y_label: str, + x_rotation: int = 90, ): super().__init__() - log.debug( - "Initialized with options: {}, {}, {}, {}".format( - title, data, generateMissing, label - ) - ) + self.series = QLineSeries() + self.chart = QChart() + # scale the chart to fit the data + self.chart.setTitle(title) + self.chart.legend().setVisible(True) + + layout = QtWidgets.QVBoxLayout() + lst = [] if generateMissing: x_data = data["x"] @@ -71,54 +77,44 @@ class DataGraph(QtWidgets.QWidget): lst.append(data) x_data = lst[0]["x"] # xdict = dict(enumerate(x_data)) - stringaxis_x = pg.AxisItem(orientation="bottom") - stringaxis_x.setTicks([xdict.items()]) - graph = pg.PlotWidget(axisItems={"bottom": stringaxis_x}) - graph.addLegend() - colors = ["b", "r", "c", "m", "y", "k", "w"] - symbols = [ - "o", - "s", - "t", - "d", - "+", - "t1", - "t2", - "t3", - "p", - "h", - "star", - "x", - "arrow_up", - "arrow_down", - "arrow_left", - "arrow_right", - ] - color_index = 0 - index = 0 + print("xdict:", xdict) - for data in lst: - symbol = symbols[random.randint(0, len(symbols) - 1)] - if color_index >= len(colors): - color_index = 0 - # iterate over the list, use y-data and y-label to plot the graph - y_data = data["y"] - label = data["y-label"] if "y-label" in data else label + self.chart.createDefaultAxes() + for entry in lst: + print("entry:", entry) + entryseries = QLineSeries() + for x_val, y_val in zip(entry["x"], entry["y"]): + # + entryseries.append(entry["x"].index(x_val), y_val) + entryseries.setName(entry["y-label"] if "y-label" in entry else y_label) - pen = pg.mkPen(color=colors[color_index], width=2) - if isinstance(y_data, list): - graph.plot( - list(xdict.keys()), y_data, pen=pen, symbol=symbol, name=label - ) - color_index += 1 - index += 1 - else: - pass - graph.setBackground("#d3d3d3") - graph.setTitle(title) - layout = QtWidgets.QVBoxLayout() - layout.addWidget(graph) + self.chart.addSeries(entryseries) + + x_axis = QCategoryAxis() + for index, semester in enumerate(lst[0]["x"]): + x_axis.append(semester, index) + x_axis.setLabelsPosition( + QCategoryAxis.AxisLabelsPosition.AxisLabelsPositionOnValue + ) + # rotare the label by 45 degrees + x_axis.setLabelsAngle(x_rotation) + x_axis.setLabelsFont(QtGui.QFont("Arial", 8, QtGui.QFont.Weight.Normal, False)) + self.chart.setAxisX(x_axis, entryseries) + + # entryseries.append( + # str() + # ) + self.chart.legend().setVisible(True) + self.chart.legend().setAlignment(QtCore.Qt.AlignmentFlag.AlignBottom) + # set legend labels + + self.chart.setAxisY(QValueAxis(self.chart), entryseries) + # the chart's x axis labels are not being displayed, as the chart only has limited space. scale down the x axis font + + chartview = QChartView(self.chart) + chartview.setRenderHint(QPainter.RenderHint.Antialiasing) + layout.addWidget(chartview) self.setLayout(layout) def generateMissingSemesters(self, data: dict[list]):