@@ -23,13 +23,14 @@ interface InfoState {
2323}
2424
2525export const ColumnChart = ( { width, height, data, scale, palette, settings } : BarChartProps ) => {
26- // bounds = area inside the graph axis = calculated by substracting the margins
26+ // bounds = area inside the graph axis = ccalculated by substracting the margins
2727 const svgRef = useRef ( null ) ;
2828 const tooltipRef = useRef ( null ) ;
2929 const [ info , setInfo ] = useState < null | InfoState > ( null ) ;
3030 const infoRef = useRef < HTMLDivElement | null > ( null ) ;
3131 const boundsWidth = width - MARGIN . right - MARGIN . left ;
3232 const boundsHeight = height - MARGIN . top - MARGIN . bottom ;
33+ const MAX_CHARS = 20 ; // Maximum characters for x-axis labels
3334
3435 //Create array with users that are visible on zoom, otherwise when opening the infobox it zooms out
3536 const [ visibleUsers , setVisibleUsers ] = useState < string [ ] > ( [ ] ) ;
@@ -59,6 +60,8 @@ export const ColumnChart = ({ width, height, data, scale, palette, settings }: B
5960 } , info ?. value ?? 0 ) ;
6061 } , [ sumUsers , info , data ] ) ;
6162
63+ const ellipsis = ( label : string ) => ( label . length > MAX_CHARS ? label . slice ( 0 , MAX_CHARS - 1 ) + '…' : label ) ;
64+
6265 //This is needed to make sure that the chart stays zoomed in when clicking on a user for the infobox
6366 useEffect ( ( ) => {
6467 if ( ! isZoomed ) setVisibleUsers ( allUsers ) ;
@@ -133,7 +136,7 @@ export const ColumnChart = ({ width, height, data, scale, palette, settings }: B
133136 // d3/typescript sometimes does weird things and throws an error where no error is.
134137 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
135138 // @ts -expect-error
136- svgElement . select ( '.xAxis' ) . transition ( ) . duration ( 1000 ) . call ( d3 . axisBottom ( xScale ) ) ;
139+ svgElement . select ( '.xAxis' ) . transition ( ) . duration ( 1000 ) . call ( d3 . axisBottom ( xScale ) . tickFormat ( ellipsis ) ) ;
137140
138141 if ( settings . showMean ) {
139142 svgElement . selectAll ( '.meanLine' ) . remove ( ) ;
@@ -158,7 +161,7 @@ export const ColumnChart = ({ width, height, data, scale, palette, settings }: B
158161 . append ( 'g' )
159162 . attr ( 'class' , 'xAxis' )
160163 . attr ( 'transform' , `translate(0,${ boundsHeight } )` )
161- . call ( d3 . axisBottom ( xScale ) )
164+ . call ( d3 . axisBottom ( xScale ) . tickFormat ( ellipsis ) )
162165 . selectAll ( 'text' )
163166 . style ( 'text-anchor' , 'middle' ) ;
164167
@@ -213,12 +216,7 @@ export const ColumnChart = ({ width, height, data, scale, palette, settings }: B
213216 { info && (
214217 < div ref = { infoRef } onClick = { ( ) => setInfo ( null ) } >
215218 < div onClick = { ( e ) => e . stopPropagation ( ) } className = { columnChartStyles . infoBox } >
216-
217- < button
218- aria-label = "Close"
219- onClick = { ( ) => setInfo ( null ) }
220- className = "btn btn-sm btn-ghost absolute right-0.5 top-0.5"
221- >
219+ < button aria-label = "Close" onClick = { ( ) => setInfo ( null ) } className = "btn btn-sm btn-ghost absolute right-0.5 top-0.5" >
222220 < strong > X</ strong >
223221 </ button >
224222
@@ -232,10 +230,10 @@ export const ColumnChart = ({ width, height, data, scale, palette, settings }: B
232230 < span className = { columnChartStyles . infoBoxValue } > { info . avgCommitsPerWeek } </ span >
233231 </ p >
234232
235- < label style = { { display : 'flex' , alignItems : 'center' , gap : '0.5rem' } } className = { columnChartStyles . infoBoxLabel } >
236- Diff to:
237- < select className = { columnChartStyles . infoBoxValue } value = { compareUser } onChange = { ( e ) => setCompareUser ( e . target . value ) } >
238- < option value = { '' } className = { columnChartStyles . infoBoxValue } disabled >
233+ < div className = { columnChartStyles . infoRow } >
234+ < span className = { columnChartStyles . infoBoxLabel } > Diff to:</ span >
235+ < select className = { columnChartStyles . selectBox } value = { compareUser } onChange = { ( e ) => setCompareUser ( e . target . value ) } >
236+ < option value = { '' } className = { columnChartStyles . infoBoxValue } >
239237 Pick user...
240238 </ option >
241239 { allUsers
@@ -246,63 +244,64 @@ export const ColumnChart = ({ width, height, data, scale, palette, settings }: B
246244 </ option >
247245 ) ) }
248246 </ select >
249- </ label >
247+ </ div >
250248
251249 { diffCommits !== null && (
252250 < span >
253251 < strong className = { columnChartStyles . infoBoxValue } > { diffCommits } Commits</ strong >
254252 </ span >
255253 ) }
256254
257- < div >
258- < span className = { columnChartStyles . infoBoxLabel } > Sum with user:</ span >
259- < select className = { columnChartStyles . infoBoxValue } value = { userToAdd } onChange = { ( e ) => setUserToAdd ( e . target . value ) } >
260- < option value = { '' } className = { columnChartStyles . infoBoxValue } disabled >
261- Pick user...
262- </ option >
263- { allUsers
264- . filter ( ( u ) => u !== info . label && ! sumUsers . includes ( u ) )
265- . map ( ( u ) => (
266- < option key = { u } value = { u } className = { columnChartStyles . infoBoxValue } >
267- { u }
268- </ option >
269- ) ) }
270- </ select >
271-
272- < button
273- className = { columnChartStyles . infoBoxButton }
274- onClick = { ( ) => {
275- if ( userToAdd && ! sumUsers . includes ( userToAdd ) ) {
276- setSumUsers ( ( prev ) => [ ...prev , userToAdd ] ) ;
277- setUserToAdd ( '' ) ;
278- }
279- } } >
280- < strong > +</ strong >
281- </ button >
282-
283- { sumUsers . length > 0 && (
284- < div >
285- < p >
286- < strong className = { columnChartStyles . infoBoxValue } > { sumCommits } Commits</ strong >
287- </ p >
288- < span className = { columnChartStyles . infoBoxLabel } > Remove user from sum:</ span >
289- < div >
290- { sumUsers . map ( ( u ) => (
291- < span key = { u } className = { columnChartStyles . infoBoxValue } >
255+ < div className = { columnChartStyles . infoRow } >
256+ < span className = { columnChartStyles . infoBoxLabel } > Sum with</ span >
257+ < div className = { columnChartStyles . combineUsersBlock } >
258+ < select className = { columnChartStyles . selectBox } value = { userToAdd } onChange = { ( e ) => setUserToAdd ( e . target . value ) } >
259+ < option value = { '' } disabled >
260+ Pick user...
261+ </ option >
262+ { allUsers
263+ . filter ( ( u ) => u !== info . label && ! sumUsers . includes ( u ) )
264+ . map ( ( u ) => (
265+ < option key = { u } value = { u } className = { columnChartStyles . userName } >
292266 { u }
293- < button
294- className = { columnChartStyles . infoBoxButton }
295- onClick = { ( ) => {
296- setSumUsers ( ( prev ) => prev . filter ( ( user ) => user !== u ) ) ;
297- } } >
298- < strong > x</ strong >
299- </ button >
300- </ span >
267+ </ option >
301268 ) ) }
302- </ div >
303- </ div >
304- ) }
269+ </ select >
270+ < button
271+ className = { columnChartStyles . addButton }
272+ onClick = { ( ) => {
273+ if ( userToAdd && ! sumUsers . includes ( userToAdd ) ) {
274+ setSumUsers ( ( prev ) => [ ...prev , userToAdd ] ) ;
275+ setUserToAdd ( '' ) ;
276+ }
277+ } } >
278+ +
279+ </ button >
280+ </ div >
305281 </ div >
282+
283+ { sumUsers . length > 0 && (
284+ < div >
285+ < p >
286+ < strong className = { columnChartStyles . infoBoxValue } > { sumCommits } Commits</ strong >
287+ </ p >
288+ < span className = { columnChartStyles . infoBoxLabel } > Remove user from sum:</ span >
289+ < div className = { columnChartStyles . userChips } >
290+ { sumUsers . map ( ( u ) => (
291+ < span key = { u } className = { columnChartStyles . userChip } >
292+ < span className = { columnChartStyles . userName } > { u } </ span >
293+ < button
294+ className = { columnChartStyles . chipClose }
295+ onClick = { ( ) => {
296+ setSumUsers ( ( prev ) => prev . filter ( ( user ) => user !== u ) ) ;
297+ } } >
298+ x
299+ </ button >
300+ </ span >
301+ ) ) }
302+ </ div >
303+ </ div >
304+ ) }
306305 </ div >
307306 </ div >
308307 ) }
0 commit comments