Skip to content

Commit 888361f

Browse files
committed
2 parents 8c629a8 + a2ecd0d commit 888361f

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

GUI.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,7 @@ def __init__(self, parent, main_class):
10511051
self.button_open_events_table_preview.configure(command=self.events_table_preview)
10521052

10531053
# Graph types
1054-
(self.button_select_all, self.button_deselect_all, self.total_hours_per_year, self.total_hours_per_month, self.total_hours_by_summary, self.total_hours_by_summary2, self.total_hours_per_year_by_summary, self.total_hours_per_month_by_summary) = GUIWidgets.create_graph_types_scroll_frame(self, square_check_image, square_image)
1054+
(self.button_select_all, self.button_deselect_all, self.total_hours_per_year, self.total_hours_per_month, self.total_hours_by_summary, self.total_hours_by_summary2, self.total_hours_per_year_by_summary, self.total_hours_per_month_by_summary, self.total_hours_per_month_grouped_by_year) = GUIWidgets.create_graph_types_scroll_frame(self, square_check_image, square_image)
10551055
self.button_select_all.configure(command=self.select_all)
10561056
self.button_deselect_all.configure(command=self.deselect_all)
10571057

@@ -1100,6 +1100,7 @@ def select_all(self):
11001100
self.total_hours_by_summary2.select()
11011101
self.total_hours_per_year_by_summary.select()
11021102
self.total_hours_per_month_by_summary.select()
1103+
self.total_hours_per_month_grouped_by_year.select()
11031104
Logger.write_log(f"all chart types selected", Logger.LogType.INFO)
11041105
self._common.write_log(self.log_box, f"all chart types selected")
11051106

@@ -1110,6 +1111,7 @@ def deselect_all(self):
11101111
self.total_hours_by_summary2.deselect()
11111112
self.total_hours_per_year_by_summary.deselect()
11121113
self.total_hours_per_month_by_summary.deselect()
1114+
self.total_hours_per_month_grouped_by_year.deselect()
11131115
Logger.write_log(f"all chart types deselected", Logger.LogType.INFO)
11141116
self._common.write_log(self.log_box, f"all chart types deselected")
11151117

@@ -1166,6 +1168,8 @@ def generate_graph(self):
11661168
self.generate_chart_with_timeout(Plotter.Plotter.chart_TotalHoursPerYearBySummary, data)
11671169
if self.total_hours_per_month_by_summary.get() == "on":
11681170
self.generate_chart_with_timeout(Plotter.Plotter.chart_TotalHoursPerMonthBySummary, data)
1171+
if self.total_hours_per_month_grouped_by_year.get() == "on":
1172+
self.generate_chart_with_timeout(Plotter.Plotter.chart_TotalHoursPerMonthGroupedByYear, data)
11691173

11701174
except FileNotFoundError as error:
11711175
Logger.write_log(f"Error, the file '{self.file_path.get()}' doesn't exist", Logger.LogType.ERROR, error)

GUIWidgets.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,9 @@ def create_graph_types_scroll_frame(master, square_check_image: PhotoImage, squa
144144
total_hours_per_year_by_summary.grid(row=3, column=0, padx=10, pady=10, sticky="ew")
145145
total_hours_per_month_by_summary = ctk.CTkCheckBox(graph_types_frame, text="Hours per Month By Summary", onvalue="on", offvalue="off")
146146
total_hours_per_month_by_summary.grid(row=3, column=1, padx=10, pady=10, sticky="ew")
147-
return(button_select_all, button_deselect_all, total_hours_per_year, total_hours_per_month, total_hours_by_summary, total_hours_by_summary2, total_hours_per_year_by_summary, total_hours_per_month_by_summary)
147+
total_hours_per_month_grouped_by_year = ctk.CTkCheckBox(graph_types_frame, text="Hours per Month Grouped By Year", onvalue="on", offvalue="off")
148+
total_hours_per_month_grouped_by_year.grid(row=4, column=0, padx=10, pady=10, sticky="ew")
149+
return(button_select_all, button_deselect_all, total_hours_per_year, total_hours_per_month, total_hours_by_summary, total_hours_by_summary2, total_hours_per_year_by_summary, total_hours_per_month_by_summary, total_hours_per_month_grouped_by_year)
148150

149151
def create_date_selection_for_events_list_scroll_frame(master, timezone: list[str], calendar_image: PhotoImage):
150152
date_frame = ctk.CTkScrollableFrame(master, label_text="Date Interval")

Plotter.py

+50
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,56 @@ def chart_TotalHoursPerMonth(data):
220220
# Show the plot
221221
fig.show()
222222
####################
223+
224+
@staticmethod
225+
def chart_TotalHoursPerMonthGroupedByYear(data):
226+
#################### Total Hours per Month Grouped by Year
227+
# Extract time data
228+
data = Plotter.__extractTimeData(data)
229+
230+
# Group by month, year, and calculate the sum of hours
231+
monthly_hours_by_year = data.groupby(['Month', 'Year'])['Duration'].sum().reset_index()
232+
233+
# Create a bar chart with Plotly, color by 'Year'
234+
fig = px.bar(
235+
monthly_hours_by_year,
236+
x='Month',
237+
y='Duration',
238+
color='Year',
239+
labels={'Month': 'Month', 'Duration': 'Total Hours'},
240+
title='Total Hours per Month Grouped by Year',
241+
text_auto=True # Automatically align values
242+
)
243+
244+
# Ensure text annotations are centered inside each bar segment
245+
fig.for_each_trace(lambda trace: trace.update(
246+
textposition='inside', # Position text inside the bar
247+
textfont=dict(size=12), # Adjust font size for better readability
248+
))
249+
250+
# Customize layout
251+
fig.update_layout(
252+
xaxis=dict(
253+
tickmode='array',
254+
tickvals=monthly_hours_by_year['Month'].unique(),
255+
ticktext=[f"Month {i}" for i in monthly_hours_by_year['Month'].unique()]
256+
),
257+
yaxis=dict(
258+
title="Total Hours"
259+
),
260+
coloraxis_colorbar=dict(
261+
tickvals=sorted(monthly_hours_by_year['Year'].unique()), # Unique year ticks
262+
title="Year"
263+
),
264+
title=dict(
265+
text='Total Hours per Month Grouped by Year',
266+
x=0.5 # Center the title
267+
)
268+
)
269+
270+
# Show the plot
271+
fig.show()
272+
####################
223273

224274
@staticmethod
225275
def chart_TotalHoursBySummary(data):

0 commit comments

Comments
 (0)