diff --git a/diagrams/dasharo_forks.py b/diagrams/dasharo_forks.py index 2c716df..0012d90 100755 --- a/diagrams/dasharo_forks.py +++ b/diagrams/dasharo_forks.py @@ -57,77 +57,135 @@ def count_closed_prs(repo, state, date): return 0 -def add_labels_merged(bars): - for bar in bars: - height = bar.get_height() - if height <= 0: - continue - font_s = 14 - plt.annotate( - f"{height}", - xy=(bar.get_x() + bar.get_width() / 2, bar.get_y() + height / 2), - xytext=(0, 3), # 3 points vertical offset - textcoords="offset points", - ha="center", - va="bottom", - color="white", - fontsize=font_s, - fontweight="bold", - ) - - -def add_labels_closed(bars, offset=0): - for bar in bars: - height = bar.get_height() - logging.info("height:{}, x:{}, y:{}".format(height, bar.get_x(), bar.get_y())) - if height <= 0: - continue - font_s = 14 - plt.annotate( - f"{height}", - xy=(bar.get_x() + bar.get_width() / 2, bar.get_y() + height / 2 - offset), - xytext=(0, 3), # 3 points vertical offset - textcoords="offset points", - ha="center", - va="bottom", - color="white", - fontsize=font_s, - fontweight="bold", - ) - - -def add_labels_open(bars, offset=0): - for bar in bars: - height = bar.get_height() - if height <= 0: - continue - font_s = 14 - logging.info("height:{}, x:{}, y:{}".format(height, bar.get_x(), bar.get_y())) - plt.annotate( - f"{height}", - xy=(bar.get_x() + bar.get_width() / 2, bar.get_y() + height / 2 - offset), - xytext=(0, 3), # 3 points vertical offset - textcoords="offset points", - ha="center", - va="bottom", - color="black", - fontsize=font_s, - fontweight="bold", - ) - - -dates = [ - "2023-03", - "2023-07", - "2023-09", - "2023-12", - "2024-03", - "2024-06", - "2024-09", - "2024-12", - "2025-03", - "2025-06", -] +def add_labels(bars_merged, bars_closed, bars_open, min_height_internal=8): + """ + Smart labeling that avoids overlaps between adjacent segments. + Processes all bars together to coordinate positioning. + """ + # Store label information for collision detection + label_positions = [] + + # Process each date column (assuming all bar lists have same length) + for i in range(len(bars_merged)): + bars_in_stack = [ + (bars_merged[i], "merged", "white", "#1a5a0f"), + (bars_closed[i], "closed", "white", "#000000"), + (bars_open[i], "open", "white", "#0066cc"), + ] + + # Calculate positions for this stack + stack_labels = [] + + for bar, bar_type, internal_color, external_color in bars_in_stack: + height = bar.get_height() + if height <= 0: # Skip zero height bars completely + continue + + x_center = bar.get_x() + bar.get_width() / 2 + + # Determine initial positioning + if height >= min_height_internal: + # Internal label + y_pos = bar.get_y() + height / 2 + is_external = False + color = internal_color + font_size = 13 + else: + y_pos = bar.get_y() + height + 2 + is_external = True + color = external_color + font_size = 11 + + stack_labels.append( + { + "bar": bar, + "height": height, + "x": x_center, + "y": y_pos, + "is_external": is_external, + "color": color, + "font_size": font_size, + "bar_type": bar_type, + "text": str(int(height)), + } + ) + + # Resolve collisions in this stack + stack_labels = resolve_stack_collisions(stack_labels) + + # Add the resolved labels to the plot + for label_info in stack_labels: + plt.annotate( + label_info["text"], + xy=(label_info["x"], label_info["y"]), + ha="center", + va="center" if not label_info["is_external"] else "bottom", + color=label_info["color"], + fontsize=label_info["font_size"], + fontweight="bold", + ) + + +def resolve_stack_collisions(stack_labels): + """ + Resolve label collisions within a single stack by considering both internal and external labels. + """ + if len(stack_labels) <= 1: + return stack_labels + + # Sort labels by their original y position (bottom to top) + stack_labels.sort(key=lambda x: x["y"]) + + # Minimum spacing between any two labels + min_spacing = 6 + + # Check for collisions between ALL adjacent labels (internal and external) + for i in range(1, len(stack_labels)): + prev_label = stack_labels[i - 1] + curr_label = stack_labels[i] + + # Calculate the visual bounds of each label + prev_top = prev_label["y"] + ( + 6 if prev_label["is_external"] else 7 + ) # Approximate label height + curr_bottom = curr_label["y"] - ( + 3 if curr_label["is_external"] else 7 + ) # Approximate label height + + # Check for overlap + if prev_top > curr_bottom: + # There's an overlap! We need to resolve it + + # Strategy: if current label is internal and would overlap with external above, + # move current label to external position + if not curr_label["is_external"] and prev_label["is_external"]: + # Move current label outside + curr_label["y"] = curr_label["bar"].get_y() + curr_label["height"] + 4 + curr_label["is_external"] = True + # Update color for external positioning + if curr_label["bar_type"] == "merged": + curr_label["color"] = "#1a5a0f" + elif curr_label["bar_type"] == "closed": + curr_label["color"] = "#000000" + else: # open + curr_label["color"] = "#0066cc" + + # Ensure minimum spacing between external labels + if curr_label["is_external"] and prev_label["is_external"]: + if curr_label["y"] - prev_label["y"] < min_spacing: + curr_label["y"] = prev_label["y"] + min_spacing + + # If previous is internal and current is external, adjust current position + elif not prev_label["is_external"] and curr_label["is_external"]: + # Calculate minimum safe position for external label + safe_y = prev_label["y"] + 6 + 3 + bar_top = curr_label["bar"].get_y() + curr_label["height"] + base_external_y = bar_top + 4 + + # Use the higher of the two positions + curr_label["y"] = max(safe_y, base_external_y) + + return stack_labels def gather_data(repo, dates, differences=False): @@ -153,9 +211,7 @@ def gather_data(repo, dates, differences=False): return data -def plot_pr_statistics( - repo, dates, data, title, filename, label_offsets, cap_to_zero=False -): +def plot_pr_statistics(repo, dates, data, title, filename, cap_to_zero=False): """ Plots PR statistics for a given repository. @@ -165,7 +221,6 @@ def plot_pr_statistics( data (dict): Dictionary containing PR data. title (str): Title of the plot. filename (str): Filename to save the plot. - label_offsets (tuple): Offsets for merged, closed, and open PR labels. """ plt.figure(figsize=(10, 6)) @@ -200,9 +255,7 @@ def plot_pr_statistics( plt.ylabel("Number of PRs", fontsize=16, fontweight="bold", color="#272727") # Add labels to the bars - add_labels_merged(bars_merged) - add_labels_closed(bars_closed, offset=label_offsets[0]) - add_labels_open(bars_open, offset=label_offsets[1]) + add_labels(bars_merged, bars_closed, bars_open) # Add legend plt.legend(fontsize=12) @@ -217,6 +270,20 @@ def plot_pr_statistics( plt.close() +dates = [ + "2023-03", + "2023-07", + "2023-09", + "2023-12", + "2024-03", + "2024-06", + "2024-09", + "2024-12", + "2025-03", + "2025-06", + "2025-08", +] + # Plot for Dasharo/coreboot repo_coreboot = "Dasharo/coreboot" data_coreboot = gather_data(repo_coreboot, dates) @@ -226,7 +293,6 @@ def plot_pr_statistics( data_coreboot, "PR Statistics for Dasharo/coreboot downstream", "img/dug_10/dasharo_coreboot.png", - label_offsets=(30, 5), ) # Plot for Dasharo/edk2 @@ -238,7 +304,6 @@ def plot_pr_statistics( data_edk2, "PR Statistics for Dasharo/edk2 fork", "img/dug_10/dasharo_edk2.png", - label_offsets=(7, 1), ) # Plot for Dasharo/open-source-firmware-validation @@ -250,7 +315,6 @@ def plot_pr_statistics( data_osfv, "PR Statistics for OSFV repository", "img/dug_10/dasharo_prs_osfv_total.png", - label_offsets=(7, 1), ) data_osfv = gather_data(repo_osfv, dates, differences=True) plot_pr_statistics( @@ -259,7 +323,6 @@ def plot_pr_statistics( data_osfv, "PR Statistics for OSFV repository - increments", "img/dug_10/dasharo_prs_osfv_diff.png", - label_offsets=(7, 1), ) # Plot for Dasharo/osfv-scripts @@ -271,7 +334,6 @@ def plot_pr_statistics( data_osfv_cli, "PR Statistics for osfv_cli repository", "img/dug_10/dasharo_prs_osfv_cli_total.png", - label_offsets=(5, 1), cap_to_zero=True, ) data_osfv_cli = gather_data(repo_osfv_cli, dates, differences=True) @@ -281,7 +343,6 @@ def plot_pr_statistics( data_osfv_cli, "PR Statistics for osfv_cli repository - increments", "img/dug_10/dasharo_prs_osfv_cli_diff.png", - label_offsets=(0.7, 0.5), cap_to_zero=True, ) @@ -294,7 +355,6 @@ def plot_pr_statistics( data_meta_dts, "PR Statistics for meta-dts repository", "img/dug_10/dasharo_prs_meta_dts.png", - label_offsets=(7, 1), ) # Plot for Dasharo/meta-dts @@ -306,5 +366,4 @@ def plot_pr_statistics( data_dts_scripts, "PR Statistics for dts-scripts repository", "img/dug_10/dasharo_prs_dts_scripts.png", - label_offsets=(7, 1), ) diff --git a/diagrams/dts_issues.py b/diagrams/dts_issues.py index f034a58..b20856e 100755 --- a/diagrams/dts_issues.py +++ b/diagrams/dts_issues.py @@ -53,7 +53,19 @@ def count_issues(repo, state, date): repo = "Dasharo/dasharo-issues" -dates = ["2023-03-16", "2023-07-06", "2023-09-28", "2023-12-03"] +dates = [ + "2023-03", + "2023-07", + "2023-09", + "2023-12", + "2024-03", + "2024-06", + "2024-09", + "2024-12", + "2025-03", + "2025-06", + "2025-08", +] # Data storage data = {"Total": [], "Closed": [], "Open": []} @@ -77,26 +89,42 @@ def count_issues(repo, state, date): ) # Add titles and labels -plt.title("Dasharo Issues Statistics", fontsize=18, fontweight="bold", color="#272727") +plt.title( + "Dasharo Tools Suite Issues Statistics", + fontsize=18, + fontweight="bold", + color="#272727", +) plt.xlabel("Date", fontsize=16, fontweight="bold", color="#272727") plt.ylabel("Number of Issues", fontsize=16, fontweight="bold", color="#272727") # Function to add labels inside the bars -def add_labels(bars, color="white"): +def add_labels(bars, default_color="white"): for bar in bars: height = bar.get_height() - plt.annotate( - f"{height}", - xy=(bar.get_x() + bar.get_width() / 2, bar.get_y() + height / 2), - xytext=(0, 3), # 3 points vertical offset - textcoords="offset points", - ha="center", - va="bottom", - color=color, - fontsize=14, - fontweight="bold", - ) + if height > 0: + # Adjust position and color based on bar height + if height < 5: # For very small bars, place label above with dark color + y_offset = 3 + va_setting = "bottom" + text_color = "#272727" # Dark color for visibility on light background + else: # For normal bars, center the label with default color + y_offset = 0 + va_setting = "center" + text_color = default_color + + plt.annotate( + f"{height}", + xy=(bar.get_x() + bar.get_width() / 2, bar.get_y() + height / 2), + xytext=(0, y_offset), + textcoords="offset points", + ha="center", + va=va_setting, + color=text_color, + fontsize=14, + fontweight="bold", + ) # Add labels to the bars @@ -110,7 +138,7 @@ def add_labels(bars, color="white"): plt.gca().set_facecolor("#f5f5f5") # Save the plot as an image file -plt.savefig("dts_issues_2023q4.png") +plt.savefig("dts_issues_2025q3.png") # Optionally, close the plot to free up memory plt.close() diff --git a/diagrams/dts_roadmap.py b/diagrams/dts_roadmap.py index 251ecdd..0935a60 100755 --- a/diagrams/dts_roadmap.py +++ b/diagrams/dts_roadmap.py @@ -10,45 +10,65 @@ """" Dasharo Tools Suite Roadmap """ -roadmap = Roadmap(1600, 1000, colour_theme="dasharo.json", show_marker=False) +roadmap = Roadmap(1600, 1000, colour_theme="diagrams/dasharo.json", show_marker=False) roadmap.set_title("Dasharo Tools Suite Roadmap") roadmap.set_subtitle("subject to change") -roadmap.set_timeline(TimelineMode.QUARTERLY, start="2024-01-01", number_of_items=2) -roadmap.add_logo("../../img/dasharo_logo_white.png", "top-right", 140, 140) +roadmap.set_timeline(TimelineMode.QUARTERLY, start="2025-07-01", number_of_items=2) +roadmap.add_logo("img/dasharo_logo_white.png", "top-right", 140, 140) -dts_1213 = roadmap.add_group("DTS v1.2.13") +dts_260 = roadmap.add_group("DTS v2.6.0") -dts_1213.add_task( - "Porting", "2024-01-01", "2024-02-14", style="rounded", fill_colour="#EA4335" +dts_260.add_task( + "E2E testing improvements", + "2025-07-01", + "2025-08-04", + style="rounded", + fill_colour="#EA4335", ) -dts_1213.add_task( - "Validation", "2024-02-15", "2024-03-06", style="rounded", fill_colour="#34A853" + +dts_261 = roadmap.add_group("DTS v2.6.1") + +dts_261.add_task( + "NovaCustom MTL v1.0.0", + "2025-08-01", + "2025-08-28", + style="rounded", + fill_colour="#EA4335", ) -dts_1213.add_task( - "Community Release", - "2024-03-07", - "2024-03-31", + +dts_261.add_task( + "Odroid-H4 v0.9.1", + "2025-08-01", + "2025-08-28", style="rounded", - fill_colour="#ADD8E6", + fill_colour="#EA4335", ) -dts_200 = roadmap.add_group("DTS v2.0.0") -dts_200.add_task( - "Porting", "2024-01-01", "2024-03-31", style="rounded", fill_colour="#EA4335" +dts_270 = roadmap.add_group("DTS v2.7.0") + +dts_270.add_task( + "ASRock server v0.9.0", + "2025-08-07", + "2025-09-11", + style="rounded", + fill_colour="#EA4335", ) -dts_200.add_task( - "Validation", "2024-04-01", "2024-05-15", style="rounded", fill_colour="#34A853" + +future = roadmap.add_group("Future") + +future.add_task( + "MSI Z690/Z790", "2025-09-11", "2025-10-31", style="rounded", fill_colour="#EA4335" ) -dts_200.add_task( - "Community Release", - "2024-05-16", - "2024-06-30", + +future.add_task( + "PC Engines APU (UEFI, SeaBIOS)", + "2025-09-11", + "2025-10-31", style="rounded", - fill_colour="#ADD8E6", + fill_colour="#EA4335", ) -roadmap.set_footer( - "Dasharo Community Support Roadmap | December 2023 (v0.4) | CC-BY-SA-4.0" -) +roadmap.set_footer("Dasharo Tools Suite Roadmap | August 2025 (v0.1) | CC-BY-SA-4.0") + roadmap.draw() -roadmap.save("dts_roadmap_v0.4.png") +roadmap.save("dts_roadmap_v0.1.png") diff --git a/dts_issues_2025q3.png b/dts_issues_2025q3.png new file mode 100644 index 0000000..3ded29a Binary files /dev/null and b/dts_issues_2025q3.png differ diff --git a/dts_roadmap_v0.1.png b/dts_roadmap_v0.1.png new file mode 100644 index 0000000..c99e832 Binary files /dev/null and b/dts_roadmap_v0.1.png differ diff --git a/img/dug_10/dasharo_coreboot.png b/img/dug_10/dasharo_coreboot.png index 404e9fa..2da65b8 100644 Binary files a/img/dug_10/dasharo_coreboot.png and b/img/dug_10/dasharo_coreboot.png differ diff --git a/img/dug_10/dasharo_edk2.png b/img/dug_10/dasharo_edk2.png index 26f7df7..5cbfed6 100644 Binary files a/img/dug_10/dasharo_edk2.png and b/img/dug_10/dasharo_edk2.png differ diff --git a/img/dug_10/dasharo_prs_dts_scripts.png b/img/dug_10/dasharo_prs_dts_scripts.png index 829614d..d3f64fe 100644 Binary files a/img/dug_10/dasharo_prs_dts_scripts.png and b/img/dug_10/dasharo_prs_dts_scripts.png differ diff --git a/img/dug_10/dasharo_prs_meta_dts.png b/img/dug_10/dasharo_prs_meta_dts.png index 8ff17a6..5fed326 100644 Binary files a/img/dug_10/dasharo_prs_meta_dts.png and b/img/dug_10/dasharo_prs_meta_dts.png differ diff --git a/img/dug_10/dasharo_prs_osfv_cli_diff.png b/img/dug_10/dasharo_prs_osfv_cli_diff.png new file mode 100644 index 0000000..2a59511 Binary files /dev/null and b/img/dug_10/dasharo_prs_osfv_cli_diff.png differ diff --git a/img/dug_10/dasharo_prs_osfv_cli_total.png b/img/dug_10/dasharo_prs_osfv_cli_total.png new file mode 100644 index 0000000..24511d4 Binary files /dev/null and b/img/dug_10/dasharo_prs_osfv_cli_total.png differ diff --git a/img/dug_10/dasharo_prs_osfv_diff.png b/img/dug_10/dasharo_prs_osfv_diff.png new file mode 100644 index 0000000..5a54c5f Binary files /dev/null and b/img/dug_10/dasharo_prs_osfv_diff.png differ diff --git a/img/dug_10/dasharo_prs_osfv_total.png b/img/dug_10/dasharo_prs_osfv_total.png new file mode 100644 index 0000000..ffcc227 Binary files /dev/null and b/img/dug_10/dasharo_prs_osfv_total.png differ diff --git a/img/dug_10/dasharo_team_roadmap.png b/img/dug_10/dasharo_team_roadmap.png index c8a4fcc..23416dd 100644 Binary files a/img/dug_10/dasharo_team_roadmap.png and b/img/dug_10/dasharo_team_roadmap.png differ diff --git a/img/dug_10/dasharo_team_roadmap2.png b/img/dug_10/dasharo_team_roadmap2.png index 707bcc4..ebae7ad 100644 Binary files a/img/dug_10/dasharo_team_roadmap2.png and b/img/dug_10/dasharo_team_roadmap2.png differ diff --git a/slidev-template b/slidev-template index d76a53a..fecc347 160000 --- a/slidev-template +++ b/slidev-template @@ -1 +1 @@ -Subproject commit d76a53ab0b726f40eae674472461ad1d9b8bbcac +Subproject commit fecc3479330d3443aabc64a62cb902dbafd9100b