From 0c8ef9f896751f219c3e18654062ecf1fc88423f Mon Sep 17 00:00:00 2001 From: sunnavy Date: Wed, 27 Mar 2024 20:16:23 -0400 Subject: [PATCH] Support to sort/limit axis labels in search charts Previously charts were always sorted by labels in ascending order, this commit enhances it to support descending order too, as well as sorting by values(i.e. asset/ticket/transaction count). Limiting the number of results is also implemented in this commit, with which users can easily get a more friendly chart that contains significant data only. --- lib/RT/Interface/Web.pm | 2 +- lib/RT/Report.pm | 23 ++++++++++++++++---- share/html/Search/Chart | 2 +- share/html/Search/Chart.html | 36 +++++++++++++++++++++++++++++++- share/html/Search/Elements/Chart | 2 +- share/html/Search/JSChart | 2 +- 6 files changed, 58 insertions(+), 9 deletions(-) diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm index 6fe866f97f8..dc90a312944 100644 --- a/lib/RT/Interface/Web.pm +++ b/lib/RT/Interface/Web.pm @@ -84,7 +84,7 @@ use RT::Interface::Web::ReportsRegistry; our @SHORTENER_SEARCH_FIELDS = qw/Class ObjectType BaseQuery Query Format RowsPerPage Order OrderBy ExtraQueryParams ResultPage/; -our @SHORTENER_CHART_FIELDS = qw/Width Height ChartStyle GroupBy ChartFunction StackedGroupBy/; +our @SHORTENER_CHART_FIELDS = qw/Width Height ChartStyle GroupBy ChartFunction StackedGroupBy ChartOrderBy ChartOrder ChartLimit/; =head2 SquishedCSS $style diff --git a/lib/RT/Report.pm b/lib/RT/Report.pm index 5e76fa29edf..6cea047123b 100644 --- a/lib/RT/Report.pm +++ b/lib/RT/Report.pm @@ -759,6 +759,12 @@ sub _FieldToFunction { sub SortEntries { my $self = shift; + my %args = ( + ChartOrderBy => 'label', + ChartOrder => 'ASC', + ChartLimit => undef, + @_, + ); $self->_DoSearch if $self->{'must_redo_search'}; return unless $self->{'items'} && @{ $self->{'items'} }; @@ -772,16 +778,21 @@ sub SortEntries { my @SORT_OPS; my $by_multiple = sub ($$) { for my $f ( @SORT_OPS ) { - my $r = $f->($_[0], $_[1]); + my $r = uc $f->($args{ChartOrder} eq 'ASC' ? ( $_[0], $_[1] ) : ( $_[1], $_[0] ) ); return $r if $r; } }; + my @data = map [$_], @{ $self->{'items'} }; - for ( my $i = 0; $i < @groups; $i++ ) { - my $group_by = $groups[$i]; - my $idx = $i+1; + if ( $args{ChartOrderBy} eq 'value' && grep { $_ eq 'id' } $self->ColumnsList ) { + $_->[1] = $_->[0]->RawValue('id') for @data; + push @SORT_OPS, sub { $_[0][1] <=> $_[1][1] }; + } + # Even if charts are sorted by value, it's still good to sort by labels next, to sort items with the same value. + for my $group_by ( @groups ) { + my $idx = @SORT_OPS + 1; my $order = $group_by->{'META'}{Sort} || 'label'; my $method = $order =~ /label$/ ? 'LabelValue' : 'RawValue'; @@ -834,6 +845,10 @@ sub SortEntries { map $_->[0], sort $by_multiple @data ]; + + if ( $args{ChartLimit} ) { + $self->{'items'} = [ splice @{ $self->{'items'} }, 0, $args{ChartLimit} ]; + } } sub PostProcessRecords { diff --git a/share/html/Search/Chart b/share/html/Search/Chart index 5b3a19afcca..516eb2b232d 100644 --- a/share/html/Search/Chart +++ b/share/html/Search/Chart @@ -119,7 +119,7 @@ if ( $Cache and my $data = delete $session{'charts_cache'}{ $Cache } ) { Function => \@ChartFunction, ); - $report->SortEntries; + $report->SortEntries( map { $_ => $ARGS{$_} } grep { $ARGS{$_} } qw(ChartOrderBy ChartOrder ChartLimit) ); } my @data = ([],[]); diff --git a/share/html/Search/Chart.html b/share/html/Search/Chart.html index 14774cdb375..667d5d1344f 100644 --- a/share/html/Search/Chart.html +++ b/share/html/Search/Chart.html @@ -56,13 +56,16 @@ GroupBy => [ $report->DefaultGroupBy ], ChartStyle => 'bar+table+sql', ChartFunction => ['COUNT'], + ChartOrderBy => 'label', + ChartOrder => 'ASC', + ChartLimit => '', }; $m->callback( ARGSRef => \%ARGS, CallbackName => 'Initial' ); my $title = loc( "Grouped search results"); -my @search_fields = ( qw(Query GroupBy StackedGroupBy ChartStyle ChartFunction Width Height Class ExtraQueryParams), grep $_, @ExtraQueryParams ); +my @search_fields = ( qw(Query GroupBy StackedGroupBy ChartStyle ChartFunction Width Height Class ExtraQueryParams ChartOrderBy ChartOrder ChartLimit), grep $_, @ExtraQueryParams ); my $saved_search = $m->comp( '/Widgets/SavedSearch:new', SearchType => 'Chart', SearchFields => [@search_fields], @@ -273,6 +276,37 @@ > + +
+
+ + <&|/l&>Order by: +
+
+ +
+
+ +
+
<&|/l&>Limit:
+
+
+
+ <&|/l&>top +
+ +
+ <&|/l&>items +
+
+
+