@@ -171,35 +171,41 @@ ChartsWidget::ChartsWidget(QWidget* parent)
171171 stagui_(nullptr ),
172172 chart_tabs_(new QTabWidget(this )),
173173 mode_menu_(new QComboBox(this )),
174- filters_menu_(new QComboBox(this )),
174+ path_group_menu_(new QComboBox(this )),
175+ clock_menu_(new QComboBox(this )),
175176 display_(new HistogramView(this )),
176177 refresh_filters_button_(new QPushButton(" Update" , this )),
177- prev_filter_index_( 0 ), // start with no filter
178+ clock_filter_( nullptr ),
178179 resetting_menu_(false ),
179180 label_(new QLabel(this ))
180181{
181182 setObjectName (" charts_widget" ); // for settings
182183 chart_tabs_->setTabBarAutoHide (true );
183184
184- QHBoxLayout* controls_layout = new QHBoxLayout;
185- controls_layout->addWidget (label_);
186-
187- controls_layout->addWidget (mode_menu_);
185+ QHBoxLayout* controls_layout_top = new QHBoxLayout;
186+ controls_layout_top->addWidget (mode_menu_);
188187 setModeMenu ();
189- controls_layout->addWidget (filters_menu_);
190- filters_menu_->hide ();
191- controls_layout->addWidget (refresh_filters_button_);
188+ controls_layout_top->addWidget (path_group_menu_);
189+ path_group_menu_->hide ();
190+ controls_layout_top->addWidget (clock_menu_);
191+ clock_menu_->hide ();
192+ controls_layout_top->addWidget (refresh_filters_button_);
192193 refresh_filters_button_->hide ();
193- controls_layout ->insertStretch (2 );
194+ controls_layout_top ->insertStretch (1 );
194195
195196 QFrame* controls_frame = new QFrame;
196- controls_frame->setLayout (controls_layout );
197+ controls_frame->setLayout (controls_layout_top );
197198 controls_frame->setFrameShape (QFrame::StyledPanel);
198199 controls_frame->setFrameShadow (QFrame::Raised);
199200
201+ QHBoxLayout* controls_layout_botton = new QHBoxLayout;
202+ controls_layout_botton->addWidget (label_);
203+ controls_layout_botton->insertStretch (1 );
204+
200205 QVBoxLayout* slack_layout = new QVBoxLayout;
201206 slack_layout->addWidget (controls_frame);
202207 slack_layout->addWidget (display_);
208+ slack_layout->addLayout (controls_layout_botton);
203209
204210 QWidget* slack_container = new QWidget (this );
205211 slack_container->setLayout (slack_layout);
@@ -222,7 +228,12 @@ ChartsWidget::ChartsWidget(QWidget* parent)
222228 this ,
223229 &ChartsWidget::reportEndPoints);
224230
225- connect (filters_menu_,
231+ connect (path_group_menu_,
232+ qOverload<int >(&QComboBox::currentIndexChanged),
233+ this ,
234+ &ChartsWidget::changePathGroupFilter);
235+
236+ connect (clock_menu_,
226237 qOverload<int >(&QComboBox::currentIndexChanged),
227238 this ,
228239 &ChartsWidget::changePathGroupFilter);
@@ -242,36 +253,27 @@ Chart* ChartsWidget::addChart(const std::string& name,
242253
243254void ChartsWidget::changeMode ()
244255{
245- filters_menu_->clear ();
246256 display_->clear ();
247257
248- resetting_menu_ = true ;
249-
250258 const Mode mode = static_cast <Mode>(mode_menu_->currentIndex ());
251259
252260 switch (mode) {
253261 case kSetupSlack :
254262 stagui_->setUseMax (true );
263+ setSlackHistogramLayout ();
255264 break ;
256265 case kHoldSlack :
257266 stagui_->setUseMax (false );
267+ setSlackHistogramLayout ();
258268 break ;
259269 case kSelect :
270+ clearMenus ();
271+ path_group_menu_->hide ();
272+ clock_menu_->hide ();
273+ refresh_filters_button_->hide ();
274+ label_->hide ();
260275 break ;
261276 }
262-
263- setSlackHistogramLayout ();
264-
265- switch (mode) {
266- case kSelect :
267- break ;
268- case kSetupSlack :
269- case kHoldSlack :
270- setSlackHistogram ();
271- break ;
272- }
273-
274- resetting_menu_ = false ;
275277}
276278
277279ChartsWidget::Mode ChartsWidget::modeFromString (const std::string& mode) const
@@ -299,8 +301,23 @@ void ChartsWidget::setMode(Mode mode)
299301void ChartsWidget::setSlackHistogramLayout ()
300302{
301303 updatePathGroupMenuIndexes (); // so that the user doesn't have to refresh
302- filters_menu_->show ();
304+ path_group_menu_->show ();
305+ clock_menu_->show ();
303306 refresh_filters_button_->show ();
307+ label_->show ();
308+ }
309+
310+ void ChartsWidget::clearMenus ()
311+ {
312+ path_group_menu_->clear ();
313+ clock_menu_->clear ();
314+
315+ filter_index_to_path_group_name_.clear ();
316+ clock_index_to_clock_.clear ();
317+
318+ path_group_name_.clear ();
319+ clock_filter_ = nullptr ;
320+ all_clocks_.clear ();
304321}
305322
306323void ChartsWidget::setModeMenu ()
@@ -317,34 +334,31 @@ void ChartsWidget::setModeMenu()
317334
318335void ChartsWidget::updatePathGroupMenuIndexes ()
319336{
320- if (filters_menu_->count () != 0 ) {
321- filters_menu_->clear ();
322- path_group_name_.clear ();
323- }
337+ resetting_menu_ = true ;
338+ clearMenus ();
339+
340+ path_group_menu_->addItem (" No Path Group" ); // Index 0
341+ filter_index_to_path_group_name_[0 ] = " " ;
324342
325- filters_menu_->addItem (" No Path Group" ); // Index 0
343+ clock_menu_->addItem (" All Clocks" ); // Index 0
344+ clock_index_to_clock_[0 ] = nullptr ;
326345
327346 int filter_index = 1 ;
328347 for (const std::string& name : stagui_->getGroupPathsNames ()) {
329- filters_menu_ ->addItem (name.c_str ());
348+ path_group_menu_ ->addItem (name.c_str ());
330349 filter_index_to_path_group_name_[filter_index] = name;
331350 ++filter_index;
332351 }
333- }
334-
335- void ChartsWidget::setSlackHistogram ()
336- {
337- SlackHistogramData data = fetchSlackHistogramData ();
338352
339- if (data. constrained_pins . size () == 0 ) {
340- logger_-> warn (utl::GUI,
341- 97 ,
342- " All pins are unconstrained. Cannot plot histogram. Check if "
343- " timing data is loaded! " );
344- return ;
353+ filter_index = 1 ;
354+ for (sta::Clock* clock : *stagui_-> getClocks ()) {
355+ clock_menu_-> addItem (clock-> name ());
356+ clock_index_to_clock_[filter_index] = clock;
357+ all_clocks_. insert (clock );
358+ ++filter_index ;
345359 }
346-
347- display_-> setData (data );
360+ resetting_menu_ = false ;
361+ changePathGroupFilter ( );
348362}
349363
350364SlackHistogramData ChartsWidget::fetchSlackHistogramData () const
@@ -353,9 +367,7 @@ SlackHistogramData ChartsWidget::fetchSlackHistogramData() const
353367
354368 removeUnconstrainedPinsAndSetLimits (data);
355369
356- for (sta::Clock* clock : *stagui_->getClocks ()) {
357- data.clocks .insert (clock);
358- }
370+ data.clocks = all_clocks_;
359371
360372 return data;
361373}
@@ -433,28 +445,52 @@ void ChartsWidget::changePathGroupFilter()
433445 return ;
434446 }
435447
436- const int filter_index = filters_menu_->currentIndex ();
437-
438- if (filter_index > 0 ) {
439- path_group_name_ = filter_index_to_path_group_name_.at (filter_index);
440- } else {
441- path_group_name_.clear ();
448+ const int path_menu_index = path_group_menu_->currentIndex ();
449+ if (path_menu_index < 0 ) {
450+ return ;
451+ }
452+ const int clock_menu_index = clock_menu_->currentIndex ();
453+ if (clock_menu_index < 0 ) {
454+ return ;
442455 }
443456
444- setData (display_, path_group_name_);
457+ path_group_name_ = filter_index_to_path_group_name_.at (path_menu_index);
458+ clock_filter_ = clock_index_to_clock_.at (clock_menu_index);
445459
446- prev_filter_index_ = filter_index ;
460+ setData (display_, path_group_name_, clock_filter_) ;
447461}
448462
449463void ChartsWidget::setData (HistogramView* view,
450- const std::string& path_group) const
464+ const std::string& path_group,
465+ sta::Clock* clock)
451466{
452467 view->clear ();
453468
454- if (path_group.empty ()) {
455- view->setData (fetchSlackHistogramData ());
469+ if (clock != nullptr ) {
470+ sta::ClockSet clocks;
471+ clocks.insert (clock);
472+ if (!path_group.empty ()) {
473+ // filter by clock and path_group
474+ view->setData (stagui_->getEndPointToSlackMap (path_group, clock), &clocks);
475+ } else {
476+ // filter only by clock
477+ view->setData (stagui_->getEndPointToSlackMap (clock), &clocks);
478+ }
479+ } else if (!path_group.empty ()) {
480+ // filter only by path_group
481+ view->setData (stagui_->getEndPointToSlackMap (path_group), &all_clocks_);
456482 } else {
457- view->setData (stagui_->getEndPointToSlackMap (path_group));
483+ SlackHistogramData data = fetchSlackHistogramData ();
484+
485+ if (data.constrained_pins .empty ()) {
486+ logger_->warn (
487+ utl::GUI,
488+ 97 ,
489+ " All pins are unconstrained. Cannot plot histogram. Check if "
490+ " timing data is loaded!" );
491+ return ;
492+ }
493+ view->setData (data);
458494 }
459495}
460496
@@ -474,7 +510,7 @@ void ChartsWidget::saveImage(const std::string& path,
474510 HistogramView print_view (this );
475511 print_view.setLogger (logger_);
476512 print_view.setSTA (stagui_.get ());
477- setData (&print_view, path_group_name_);
513+ setData (&print_view, path_group_name_, clock_filter_ );
478514 QSize view_size (500 , 500 );
479515 if (width_px.has_value ()) {
480516 view_size.setWidth (width_px.value ());
@@ -538,10 +574,8 @@ void HistogramView::showToolTip(bool is_hovering, int bar_index)
538574
539575 if (bar_index >= num_of_neg_buckets) {
540576 num = buckets_.positive [bar_index - num_of_neg_buckets].size ();
541- ;
542577 } else {
543578 num = buckets_.negative [bar_index].size ();
544- ;
545579 }
546580 }
547581
@@ -624,10 +658,12 @@ void HistogramView::setData(const SlackHistogramData& data)
624658 setVisualConfig ();
625659}
626660
627- void HistogramView::setData (const EndPointSlackMap& data)
661+ void HistogramView::setData (const EndPointSlackMap& data, sta::ClockSet* clocks )
628662{
629663 clear ();
630664
665+ clocks_ = *clocks;
666+
631667 histogram_ = std::make_unique<utl::Histogram<float >>(logger_);
632668
633669 // extract data
@@ -1011,4 +1047,4 @@ void HistogramView::contextMenuEvent(QContextMenuEvent* event)
10111047 }
10121048}
10131049
1014- } // namespace gui
1050+ } // namespace gui
0 commit comments