-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlivesplit-graphs.pyw
168 lines (135 loc) · 6.08 KB
/
livesplit-graphs.pyw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
import sys
import gc
from PyQt6.QtWidgets import QApplication, QMainWindow, QFileDialog, QPushButton, QSizePolicy, QButtonGroup, QWidget
from PyQt6 import QtGui
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg, NavigationToolbar2QT as NavigationToolbar
from ui.main_window_ui import Ui_MainWindow
from livesplit_data import LiveSplitData
from plot import Plot
from theme import Theme, ThemeVariant
from graph import Graph
class Window(QMainWindow, Ui_MainWindow):
currentGraph: FigureCanvasQTAgg | None = None
currentToolbar: NavigationToolbar | None = None
lsd: LiveSplitData | None = None
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.setWindowTitle("Livesplit Graphs")
self.loadThemes()
self.listSplits.clear()
self.connectSignalsSlots()
# REMOVE testing
self.lsd = LiveSplitData("E:/Livesplit-new/layouts/Grand Theft Auto V - Trevor%.lss")
self.loadSplitsList()
def connectSignalsSlots(self):
self.actionOpen.triggered.connect(self.selectFile)
self.listSplits.itemClicked.connect(self.loadGraph)
self.check_showOutliers.clicked.connect(self.loadGraph)
self.color_options.currentIndexChanged.connect(self.loadGraph)
self.option_buttons.buttonClicked.connect(self.loadGraph)
def loadThemes(self):
for variant in ThemeVariant:
self.color_options.addItem(variant.value)
def selectFile(self):
fileDialog = QFileDialog.getOpenFileName(
self,
caption="Select a Livesplit file",
filter="*.lss"
)
livesplit_path = fileDialog[0]
if livesplit_path != "":
self.lsd = LiveSplitData(livesplit_path)
self.loadSplitsList()
def loadSplitsList(self):
self.listSplits.clear()
self.listSplits.addItems(self.lsd.split_names)
def loadGraph(self):
checkedButton = self.option_buttons.checkedButton()
if checkedButton is None or self.lsd is None:
return
if self.listSplits.currentItem() is None:
self.listSplits.setCurrentRow(0)
# remove old graph or placeholder
self.removeGraphAndToolbar()
# define new graph and toolbar
fig = self.getFigure(Graph(checkedButton.text()))
self.currentGraph = FigureCanvasQTAgg(fig)
self.currentGraph.setSizePolicy(QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Expanding))
self.currentToolbar = NavigationToolbar(canvas=self.currentGraph, parent=self)
self.currentToolbar.setStyleSheet("background-color: white;")
# TODO why is this here?
plt.grid()
plt.tight_layout()
# add new graph to layout
self.graph_layout.addWidget(self.currentToolbar)
self.graph_layout.addWidget(self.currentGraph)
def getFigure(self, graph: Graph) -> Figure:
plot = Plot(
livesplit_data=self.lsd,
split_name=self.listSplits.currentItem().text(),
split_index=self.listSplits.currentRow(),
theme=self.getTheme(self.color_options.currentText()),
show_outliers=self.check_showOutliers.isChecked()
)
# generate figure object
match graph:
case Graph.HISTOGRAM:
self.lsd.extract_segment_data(
segment_index=self.listSplits.currentRow(),
show_outliers=self.check_showOutliers.isChecked(),
)
fig = plot.hist(self.lsd.segment_times["seg_times"])
case Graph.MOVING_AVERAGE:
self.lsd.extract_segment_data(
segment_index=self.listSplits.currentRow(),
show_outliers=self.check_showOutliers.isChecked(),
)
fig = plot.moving_avg(self.lsd.segment_times, self.lsd.avg_segment_times)
# have to call this here, doesn't work in Plot class
fig.canvas.mpl_connect("motion_notify_event", lambda event=None : plot.hover_scatter(event))
case Graph.ATTEMPTS_OVER_TIME:
fig = plot.attempts_over_time()
fig.canvas.mpl_connect("motion_notify_event", lambda event=None : plot.hover_plot(event, graph=Graph.ATTEMPTS_OVER_TIME))
case Graph.IMP_OVER_ATTEMPTS:
fig = plot.imp_over_attempts()
case Graph.IMP_OVER_TIME:
fig = plot.imp_over_time()
case Graph.PB_OVER_TIME:
fig = plot.personal_best_over_time()
fig.canvas.mpl_connect("motion_notify_event", lambda event=None : plot.hover_plot(event, graph=Graph.PB_OVER_TIME))
case Graph.PB_OVER_ATTEMPTS:
fig = plot.personal_best_over_attempts()
fig.canvas.mpl_connect("motion_notify_event", lambda event=None : plot.hover_plot(event, graph=Graph.PB_OVER_ATTEMPTS))
case _:
NotImplementedError("Graph not implemented.")
return
return fig
def removeCurrentGraph(self):
if self.currentGraph is None:
return
plt.close("all")
self.currentGraph.setParent(None)
self.graph_layout.removeWidget(self.currentGraph)
self.currentGraph = None
def removeCurrentToolbar(self):
if self.currentToolbar is None:
return
self.currentToolbar.setParent(None)
self.graph_layout.removeWidget(self.currentToolbar)
self.currentToolbar = None
def removeGraphAndToolbar(self):
self.removeCurrentGraph()
self.removeCurrentToolbar()
self.graph_placeholder.setParent(None)
gc.collect()
def getTheme(self, theme_str: str):
theme_variant = ThemeVariant.from_str(theme_str)
return Theme.from_variant(theme_variant)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec())