@@ -144,41 +144,36 @@ export function GroupBreakdownChart({ stackField = 'model', metricOptions }: Gro
144144 } ,
145145 } ,
146146 tooltip : {
147- shared : true ,
147+ shared : false ,
148148 useHTML : true ,
149149 formatter : function ( ) {
150150 // eslint-disable-next-line @typescript-eslint/no-explicit-any
151- const points = ( this as any ) . points as Array < { y : number ; color : string ; series : { name : string ; userOptions ?: { custom ?: { rawStack ?: string } } } } > | undefined ;
152- if ( ! points ?. length ) return false ;
153- // Resolve the grouped entity (x-axis value)
154- const key = String ( ( this as Highcharts . TooltipFormatterContextObject ) . x ?? '' ) ;
151+ const pt = this as unknown as { point : { y : number ; total : number ; color : string } ; series : { name : string ; userOptions ?: { custom ?: { rawStack ?: string } } } ; x : string } ;
152+ const val = pt . point . y ?? 0 ;
153+ const total = pt . point . total ?? val ;
154+ // Header: groupBy entity with icon
155+ const key = String ( pt . x ?? '' ) ;
155156 const rawKey = sorted . find ( ( s ) => formatDisplayValue ( s . key , groupByColumn ) === key ) ?. key ?? key ;
156157 const headerIcon = columnHasIcons ( groupByColumn ) ? getGroupIconSvg ( rawKey , groupByColumn ) : '' ;
157158 const headerHtml = headerIcon
158159 ? `<span style="display:inline-flex;align-items:center;gap:4px;">${ headerIcon } ${ key } </span>`
159160 : key ;
160- let html = `<table style="min-width:120px;"><tr><th colspan="2" style="color:var(--fgColor-muted,#59636e);font-weight:600;padding-bottom:2px;font-size:12px;">${ headerHtml } </th></tr>` ;
161-
162- let total = 0 ;
161+ // Row: stack value with icon
163162 const hasStackIcons = columnHasIcons ( stackField ) ;
164- for ( const pt of points ) {
165- if ( ! pt . y ) continue ;
166- total += pt . y ;
167- const rawStack = pt . series . userOptions ?. custom ?. rawStack ?? '' ;
168- const indicator = hasStackIcons && rawStack
169- ? getGroupIconSvg ( rawStack , stackField , String ( pt . color ) )
170- : `<span style="color:${ pt . color } ">●</span>` ;
171- const displayName = formatDisplayValue ( rawStack , stackField ) || pt . series . name ;
172- const formatted = activeMetric . isCurrency
173- ? `$${ pt . y . toLocaleString ( undefined , { minimumFractionDigits : 2 , maximumFractionDigits : 2 } ) } `
174- : formatCompact ( pt . y ) ;
175- html += `<tr><td>${ indicator } ${ displayName } : </td><td style="text-align:right;"><b>${ formatted } </b></td></tr>` ;
176- }
163+ const rawStack = pt . series . userOptions ?. custom ?. rawStack ?? '' ;
164+ const indicator = hasStackIcons && rawStack
165+ ? getGroupIconSvg ( rawStack , stackField , String ( pt . point . color ) )
166+ : `<span style="color:${ pt . point . color } ">●</span>` ;
167+ const displayName = formatDisplayValue ( rawStack , stackField ) || pt . series . name ;
168+ const formatted = activeMetric . isCurrency
169+ ? `$${ val . toLocaleString ( undefined , { minimumFractionDigits : 2 , maximumFractionDigits : 2 } ) } `
170+ : formatCompact ( val ) ;
177171 const totalStr = activeMetric . isCurrency
178172 ? `$${ total . toLocaleString ( undefined , { minimumFractionDigits : 2 , maximumFractionDigits : 2 } ) } `
179173 : formatCompact ( total ) ;
180- html += `<tr style="border-top:1px solid var(--borderColor-muted,#d1d9e0b3);"><td><b>Total: </b></td><td style="text-align:right;"><b>${ totalStr } </b></td></tr></table>` ;
181- return html ;
174+ return `<table style="min-width:120px;"><tr><th colspan="2" style="color:var(--fgColor-muted,#59636e);font-weight:600;padding-bottom:2px;font-size:12px;">${ headerHtml } </th></tr>` +
175+ `<tr><td>${ indicator } ${ displayName } : </td><td style="text-align:right;"><b>${ formatted } </b></td></tr>` +
176+ `<tr style="border-top:1px solid var(--borderColor-muted,#d1d9e0b3);"><td><b>Total: </b></td><td style="text-align:right;"><b>${ totalStr } </b></td></tr></table>` ;
182177 } ,
183178 } ,
184179 plotOptions : { bar : { stacking : 'normal' } } ,
0 commit comments