@@ -76,6 +76,95 @@ QString formatPressureScore(double score) {
7676 return QString::number (score, ' f' , 1 );
7777}
7878
79+ QString simplifyLocationLabel (QString text) {
80+ text = text.simplified ();
81+ if (text.isEmpty ()) {
82+ return text;
83+ }
84+
85+ QStringList words = text.split (' ' , Qt::SkipEmptyParts);
86+ static const QStringList genericSuffixes{
87+ " Room" ,
88+ " Area" ,
89+ " Zone" ,
90+ " Passage" ,
91+ " Corridor" ,
92+ " Hallway" ,
93+ " Hall" ,
94+ " Lobby" ,
95+ " Section" ,
96+ };
97+
98+ while (words.size () > 1 && genericSuffixes.contains (words.back (), Qt::CaseInsensitive)) {
99+ words.removeLast ();
100+ }
101+ return words.join (' ' );
102+ }
103+
104+ QString compactWords (QString text, int maxCharactersPerSide) {
105+ text = text.simplified ();
106+ if (text.size () <= maxCharactersPerSide) {
107+ return text;
108+ }
109+
110+ const auto words = text.split (' ' , Qt::SkipEmptyParts);
111+ if (words.size () >= 2 ) {
112+ QString compact = words.front ();
113+ for (int index = 1 ; index < words.size (); ++index) {
114+ const auto candidate = compact + ' ' + words[index];
115+ if (candidate.size () > maxCharactersPerSide) {
116+ break ;
117+ }
118+ compact = candidate;
119+ }
120+ if (compact.size () <= maxCharactersPerSide) {
121+ return compact;
122+ }
123+ }
124+
125+ if (maxCharactersPerSide <= 3 ) {
126+ return text.left (std::max (1 , maxCharactersPerSide));
127+ }
128+ return text.left (maxCharactersPerSide - 3 ).trimmed () + QStringLiteral (" ..." );
129+ }
130+
131+ QString compactBottleneckLabel (QString label) {
132+ label = label.simplified ();
133+ if (label.isEmpty ()) {
134+ return label;
135+ }
136+
137+ constexpr int kCompactLabelLimit = 18 ;
138+ if (label.size () <= kCompactLabelLimit ) {
139+ return label.replace (QStringLiteral (" ->" ), QStringLiteral (" >" ));
140+ }
141+
142+ const auto segments = label.split (QStringLiteral (" ->" ), Qt::SkipEmptyParts);
143+ if (segments.size () != 2 ) {
144+ const auto simplified = simplifyLocationLabel (label);
145+ return compactWords (simplified, kCompactLabelLimit );
146+ }
147+
148+ auto from = simplifyLocationLabel (segments[0 ]);
149+ auto to = simplifyLocationLabel (segments[1 ]);
150+ QString compact = QStringLiteral (" %1 > %2" ).arg (from, to);
151+ if (compact.size () <= kCompactLabelLimit ) {
152+ return compact;
153+ }
154+
155+ const int sideBudget = std::max (5 , (kCompactLabelLimit - 3 ) / 2 );
156+ from = compactWords (from, sideBudget);
157+ to = compactWords (to, sideBudget);
158+ compact = QStringLiteral (" %1 > %2" ).arg (from, to);
159+ if (compact.size () <= kCompactLabelLimit ) {
160+ return compact;
161+ }
162+
163+ return QStringLiteral (" %1 > %2" )
164+ .arg (compactWords (from, sideBudget - 1 ))
165+ .arg (compactWords (to, sideBudget - 1 ));
166+ }
167+
79168QString formatPercent (double ratio) {
80169 return QString (" %1%" ).arg (std::clamp (ratio, 0.0 , 1.0 ) * 100.0 , 0 , ' f' , 0 );
81170}
@@ -445,7 +534,20 @@ QFrame* createMetricCard(const QString& title, const QString& value, QWidget* pa
445534 auto * titleLabel = createLabel (title, card, ui::FontRole::Caption);
446535 titleLabel->setStyleSheet (ui::mutedTextStyleSheet ());
447536 auto * valueLabel = createLabel (value, card, ui::FontRole::SectionTitle);
448- valueLabel->setSizePolicy (QSizePolicy::Ignored, QSizePolicy::Preferred);
537+ const bool longValue = value.size () >= 12 || value.contains (' >' ) || value.contains (' ' );
538+ auto valueFont = longValue
539+ ? ui::font (ui::FontRole::Caption)
540+ : valueLabel->font ();
541+ if (longValue) {
542+ valueFont.setWeight (QFont::DemiBold);
543+ } else {
544+ valueFont.setPointSize (std::max (11 , valueFont.pointSize () - 1 ));
545+ }
546+ valueLabel->setFont (valueFont);
547+ valueLabel->setSizePolicy (QSizePolicy::Ignored, QSizePolicy::MinimumExpanding);
548+ valueLabel->setAlignment (Qt::AlignLeft | Qt::AlignTop);
549+ const auto minimumLines = longValue ? 2 : 1 ;
550+ valueLabel->setMinimumHeight ((QFontMetrics (valueFont).lineSpacing () * minimumLines) + 4 );
449551 if (!tooltip.isEmpty ()) {
450552 titleLabel->setToolTip (tooltip);
451553 valueLabel->setToolTip (tooltip);
@@ -961,9 +1063,10 @@ QWidget* createResultPanel(
9611063 metricsGrid->setColumnStretch (0 , 1 );
9621064 metricsGrid->setColumnStretch (1 , 1 );
9631065 const auto completionTime = resultCompletionTime (frame, artifacts);
964- const auto worstBottleneck = risk.bottlenecks .empty ()
1066+ const auto worstBottleneckFull = risk.bottlenecks .empty ()
9651067 ? QString (" None" )
9661068 : QString::fromStdString (risk.bottlenecks .front ().label );
1069+ const auto worstBottleneck = compactBottleneckLabel (worstBottleneckFull);
9671070 const auto slowestGroup = artifacts.placementCompletion .empty ()
9681071 ? QString (" Pending" )
9691072 : QString::fromStdString (artifacts.placementCompletion .front ().placementId );
@@ -994,7 +1097,8 @@ QWidget* createResultPanel(
9941097 " Bottleneck" ,
9951098 worstBottleneck,
9961099 panel,
997- QString (" Worst bottleneck observed during the run.\n\n %1" )
1100+ QString (" Worst bottleneck observed during the run.\n\n Full label: %1\n\n %2" )
1101+ .arg (worstBottleneckFull)
9981102 .arg (safecrowd::domain::scenarioBottleneckDefinition ())), 1 , 1 );
9991103 metricsGrid->addWidget (createMetricCard (
10001104 " Slowest" ,
0 commit comments