@@ -26,13 +26,18 @@ import {
2626 CommonChartState ,
2727} from "@/charts/shared/chart-state" ;
2828import { useSize } from "@/charts/shared/use-size" ;
29- import { BAR_CELL_PADDING , TABLE_HEIGHT } from "@/charts/table/constants" ;
29+ import {
30+ BAR_CELL_PADDING ,
31+ LIMITED_COLUMN_WIDTH ,
32+ TABLE_HEIGHT ,
33+ } from "@/charts/table/constants" ;
3034import { getTableUIElementsOffset } from "@/charts/table/table" ;
3135import {
3236 TableStateVariables ,
3337 useTableStateData ,
3438 useTableStateVariables ,
3539} from "@/charts/table/table-state-props" ;
40+ import { columnCanBeWidthLimited } from "@/charts/table/width-limit" ;
3641import {
3742 ColumnStyleCategory ,
3843 ColumnStyleHeatmap ,
@@ -118,6 +123,7 @@ export type TableChartState = CommonChartState &
118123 groupingIds : string [ ] ;
119124 hiddenIds : string [ ] ;
120125 sortingIds : { id : string ; desc : boolean } [ ] ;
126+ shouldApplyWidthLimits : boolean ;
121127 links : TableLinks ;
122128 } ;
123129
@@ -210,11 +216,10 @@ const useTableState = (
210216 [ chartData , types ]
211217 ) ;
212218
213- // Columns used by react-table
214- const tableColumns = useMemo ( ( ) => {
219+ const tableColumnsData = useMemo ( ( ) => {
215220 const allComponents = [ ...dimensions , ...measures ] ;
216221
217- const columns = orderedTableColumns . map ( ( c ) => {
222+ const columnData = orderedTableColumns . map ( ( c ) => {
218223 const headerComponent = allComponents . find ( ( d ) => d . id === c . componentId ) ;
219224
220225 if ( ! headerComponent ) {
@@ -228,7 +233,7 @@ const useTableState = (
228233 const headerLabel = getLabelWithUnit ( headerComponent ) ;
229234
230235 // The column width depends on the estimated width of the
231- // longest value in the column, with a minimum of 150px .
236+ // longest value in the column, with a minimum of 50px .
232237 const columnItems = [ ...new Set ( chartData . map ( ( d ) => d [ c . componentId ] ) ) ] ;
233238 const columnItemSizes = [
234239 ...columnItems . map ( ( item ) => {
@@ -241,40 +246,81 @@ const useTableState = (
241246 } ) ,
242247 ] ;
243248
244- const width = Math . max (
249+ const naturalWidth = Math . max (
245250 50 ,
246251 getTextWidth ( headerLabel , { fontSize : 16 } ) + 44 ,
247252 ...columnItemSizes
248253 ) ;
249254
250255 return {
251- Header : headerLabel ,
252- // Slugify accessor to avoid id's "." to be parsed as JS object notation.
253- accessor : getSlugifiedId ( c . componentId ) ,
254- width,
255- sortType : (
256- rowA : Row < Observation > ,
257- rowB : Row < Observation > ,
258- colId : string
259- ) => {
260- for ( const d of sorters ) {
261- const result = ascending (
262- d ( rowA . values [ colId ] ) ,
263- d ( rowB . values [ colId ] )
264- ) ;
265-
266- if ( result ) {
267- return result ;
268- }
269- }
270-
271- return 0 ;
272- } ,
256+ c,
257+ headerComponent,
258+ headerLabel,
259+ sorters,
260+ naturalWidth,
261+ canBeWidthLimited : columnCanBeWidthLimited (
262+ fields [ c . componentId ] . columnStyle . type
263+ ) ,
273264 } ;
274265 } ) ;
275266
276- return columns ;
277- } , [ dimensions , measures , orderedTableColumns , chartData , formatNumber ] ) ;
267+ const totalNaturalWidth = columnData . reduce (
268+ ( sum , col ) => sum + col . naturalWidth ,
269+ 0
270+ ) ;
271+
272+ const shouldApplyLimits =
273+ settings . limitColumnWidths && totalNaturalWidth > chartWidth ;
274+
275+ const columns = columnData . map (
276+ ( { c, headerLabel, sorters, naturalWidth, canBeWidthLimited } ) => {
277+ const width =
278+ shouldApplyLimits && canBeWidthLimited
279+ ? Math . min ( naturalWidth , LIMITED_COLUMN_WIDTH )
280+ : naturalWidth ;
281+
282+ return {
283+ Header : headerLabel ,
284+ // Slugify accessor to avoid id's "." to be parsed as JS object notation.
285+ accessor : getSlugifiedId ( c . componentId ) ,
286+ width,
287+ sortType : (
288+ rowA : Row < Observation > ,
289+ rowB : Row < Observation > ,
290+ colId : string
291+ ) => {
292+ for ( const d of sorters ) {
293+ const result = ascending (
294+ d ( rowA . values [ colId ] ) ,
295+ d ( rowB . values [ colId ] )
296+ ) ;
297+
298+ if ( result ) {
299+ return result ;
300+ }
301+ }
302+
303+ return 0 ;
304+ } ,
305+ } ;
306+ }
307+ ) ;
308+
309+ return { columns, shouldApplyLimits } ;
310+ } , [
311+ dimensions ,
312+ measures ,
313+ orderedTableColumns ,
314+ chartData ,
315+ formatNumber ,
316+ fields ,
317+ chartWidth ,
318+ settings . limitColumnWidths ,
319+ ] ) ;
320+
321+ // Columns used by react-table
322+ const tableColumns = tableColumnsData . columns ;
323+ const shouldApplyWidthLimits = tableColumnsData . shouldApplyLimits ;
278324
279325 // Groupings used by react-table
280326 const groupingIds = useMemo (
@@ -436,6 +482,7 @@ const useTableState = (
436482 groupingIds,
437483 hiddenIds,
438484 sortingIds,
485+ shouldApplyWidthLimits,
439486 xScaleTimeRange,
440487 links,
441488 ...variables ,
0 commit comments