@@ -109,6 +109,9 @@ const TIMELINE_SERIES_COLORS = [
109109 Color . rgb ( 222 , 218 , 247 ) ,
110110] ;
111111
112+ const TOP_N_ROWS = 10 ;
113+ const OTHER_TAG_NAME = 'Other' ;
114+
112115// structured data to display/style table cells
113116interface TableValuesData {
114117 color ?: Color ;
@@ -260,6 +263,10 @@ function TagExplorerView() {
260263 const { groupsData, activeTagProfile } = getGroupsData ( ) ;
261264
262265 const handleGroupByTagValueChange = ( v : string ) => {
266+ if ( v === OTHER_TAG_NAME ) {
267+ return ;
268+ }
269+
263270 dispatch ( actions . setTagExplorerViewGroupByTagValue ( v ) ) ;
264271 } ;
265272
@@ -292,6 +299,32 @@ function TagExplorerView() {
292299 return acc ;
293300 } , [ ] as string [ ] ) ;
294301
302+ const sortedGroupsByTotal = [ ...filteredGroupsData ] . sort (
303+ ( a , b ) => calculateTotal ( b . data . samples ) - calculateTotal ( a . data . samples )
304+ ) ;
305+
306+ const topNGroups = sortedGroupsByTotal . slice ( 0 , TOP_N_ROWS ) ;
307+ const groupsRemainder = sortedGroupsByTotal . slice (
308+ TOP_N_ROWS ,
309+ sortedGroupsByTotal . length
310+ ) ;
311+
312+ const groups =
313+ filteredGroupsData . length > TOP_N_ROWS
314+ ? [
315+ ...topNGroups ,
316+ {
317+ tagName : OTHER_TAG_NAME ,
318+ color : Color ( '#888' ) ,
319+ data : {
320+ samples : groupsRemainder . reduce ( ( acc : number [ ] , current ) => {
321+ return acc . concat ( current . data . samples ) ;
322+ } , [ ] ) ,
323+ } ,
324+ } as TimelineGroupData ,
325+ ]
326+ : filteredGroupsData ;
327+
295328 return (
296329 < >
297330 < PageTitle title = { formatTitle ( 'Tag Explorer View' , query ) } />
@@ -321,12 +354,12 @@ function TagExplorerView() {
321354 timezone = { offset === 0 ? 'utc' : 'browser' }
322355 data-testid = "timeline-explore-page"
323356 id = "timeline-chart-explore-page"
324- timelineGroups = { filteredGroupsData }
357+ timelineGroups = { groups }
325358 // to not "dim" timelines when "All" option is selected
326359 activeGroup = {
327360 groupByTagValue !== ALL_TAGS ? groupByTagValue : ''
328361 }
329- showTagsLegend = { filteredGroupsData . length > 1 }
362+ showTagsLegend = { groups . length > 1 }
330363 handleGroupByTagValueChange = { handleGroupByTagValueChange }
331364 onSelect = { ( from , until ) =>
332365 dispatch ( setDateRange ( { from, until } ) )
@@ -351,8 +384,8 @@ function TagExplorerView() {
351384 >
352385 < div className = { styles . statisticsBox } >
353386 < div className = { styles . pieChartWrapper } >
354- { filteredGroupsData ?. length ? (
355- < TotalSamplesChart filteredGroupsData = { filteredGroupsData } />
387+ { groups ?. length ? (
388+ < TotalSamplesChart filteredGroupsData = { groups } />
356389 ) : (
357390 < LoadingSpinner />
358391 ) }
@@ -362,7 +395,7 @@ function TagExplorerView() {
362395 whereDropdownItems = { whereDropdownItems }
363396 groupByTag = { groupByTag }
364397 groupByTagValue = { groupByTagValue }
365- groupsData = { filteredGroupsData }
398+ groupsData = { groups }
366399 handleGroupByTagValueChange = { handleGroupByTagValueChange }
367400 isLoading = { type === 'loading' }
368401 activeTagProfile = { activeTagProfile }
@@ -431,6 +464,11 @@ function Table({
431464 ) ;
432465
433466 const handleTableRowClick = ( value : string ) => {
467+ // prevent clicking on single "application without tags" group row or Other row
468+ if ( value === appName || value === OTHER_TAG_NAME ) {
469+ return ;
470+ }
471+
434472 if ( value !== groupByTagValue ) {
435473 handleGroupByTagValueChange ( value ) ;
436474 } else {
@@ -544,9 +582,7 @@ function Table({
544582 const percentage = ( total / groupsTotal ) * 100 ;
545583 const row = {
546584 isRowSelected : isTagSelected ( tagName ) ,
547- // prevent clicking on single "application without tags" group row
548- onClick :
549- tagName !== appName ? ( ) => handleTableRowClick ( tagName ) : undefined ,
585+ onClick : ( ) => handleTableRowClick ( tagName ) ,
550586 cells : [
551587 {
552588 value : (
0 commit comments