Skip to main content

ringkernel_procint/gui/panels/
conformance_panel.rs

1//! Conformance checking results panel.
2
3use crate::gui::widgets::labeled_progress;
4use crate::gui::{section_header, styled_panel, Theme};
5use crate::kernels::ConformanceCheckResult;
6use eframe::egui::{self, Ui};
7
8/// Conformance results panel.
9#[derive(Default)]
10pub struct ConformancePanel {
11    /// Last conformance results.
12    pub last_results: Option<ConformanceCheckResult>,
13}
14
15impl ConformancePanel {
16    /// Update with new results.
17    pub fn update(&mut self, results: ConformanceCheckResult) {
18        self.last_results = Some(results);
19    }
20
21    /// Render the panel.
22    pub fn render(&mut self, ui: &mut Ui, theme: &Theme) {
23        styled_panel(ui, theme, |ui| {
24            section_header(ui, theme, "CONFORMANCE");
25
26            if let Some(results) = &self.last_results {
27                let dist = results.distribution();
28                let total = dist.total();
29
30                // Fitness score
31                let avg_fitness = results.avg_fitness();
32                let fitness_color = theme.fitness_color(avg_fitness);
33
34                ui.horizontal(|ui| {
35                    ui.label("Fitness:");
36                    ui.label(
37                        egui::RichText::new(format!("{:.1}%", avg_fitness * 100.0))
38                            .size(16.0)
39                            .strong()
40                            .color(fitness_color),
41                    );
42                });
43
44                ui.add_space(8.0);
45
46                // Compliance distribution
47                if total > 0 {
48                    let percentages = dist.percentages();
49
50                    labeled_progress(
51                        ui,
52                        theme,
53                        "Fully",
54                        percentages[0] / 100.0,
55                        Some(theme.success),
56                    );
57                    labeled_progress(
58                        ui,
59                        theme,
60                        "Mostly",
61                        percentages[1] / 100.0,
62                        Some(egui::Color32::from_rgb(34, 211, 238)),
63                    );
64                    labeled_progress(
65                        ui,
66                        theme,
67                        "Partial",
68                        percentages[2] / 100.0,
69                        Some(theme.warning),
70                    );
71                    labeled_progress(ui, theme, "Non", percentages[3] / 100.0, Some(theme.error));
72                }
73
74                ui.add_space(8.0);
75
76                // Summary counts
77                ui.horizontal(|ui| {
78                    ui.label(
79                        egui::RichText::new(format!("✓ {}", results.conformant_count()))
80                            .color(theme.success),
81                    );
82                    ui.label(
83                        egui::RichText::new(format!("✗ {}", results.non_conformant_count()))
84                            .color(theme.error),
85                    );
86                });
87
88                ui.add_space(8.0);
89
90                // Deviations
91                ui.collapsing("Deviations", |ui| {
92                    let mut missing_total = 0u16;
93                    let mut extra_total = 0u16;
94
95                    for result in &results.results {
96                        missing_total += result.missing_count;
97                        extra_total += result.extra_count;
98                    }
99
100                    ui.label(format!("Missing activities: {}", missing_total));
101                    ui.label(format!("Extra activities: {}", extra_total));
102                    ui.label(format!("Traces checked: {}", results.results.len()));
103                });
104            } else {
105                ui.label(
106                    egui::RichText::new("No conformance data yet")
107                        .size(11.0)
108                        .color(theme.text_muted),
109                );
110            }
111        });
112    }
113}