@@ -9,11 +9,12 @@ import {
99 scaleOrdinal ,
1010 scaleDiverging ,
1111 scaleLinear ,
12+ ascending ,
1213} from "d3" ;
1314import mapKeys from "lodash/mapKeys" ;
1415import mapValues from "lodash/mapValues" ;
1516import { ReactNode , useMemo } from "react" ;
16- import { Cell , Column } from "react-table" ;
17+ import { Cell , Column , Row } from "react-table" ;
1718
1819import {
1920 getLabelWithUnit ,
@@ -38,6 +39,7 @@ import { useFormatNumber, useDimensionFormatters } from "@/formatters";
3839import { getColorInterpolator } from "@/palettes" ;
3940import { useTheme } from "@/themes" ;
4041import { estimateTextWidth } from "@/utils/estimate-text-width" ;
42+ import { makeDimensionValueSorters } from "@/utils/sorting-values" ;
4143
4244export type MKColumnMeta < T > = {
4345 iri : string ;
@@ -145,7 +147,7 @@ const useTableState = ({
145147 // Data used by react-table
146148 const memoizedData = useMemo (
147149 function replaceKeys ( ) {
148- //Only read keys once
150+ // Only read keys once
149151 const keys = Object . keys ( data [ 0 ] ) ;
150152 const slugifiedKeys = keys . map ( getSlugifiedIri ) ;
151153
@@ -165,18 +167,25 @@ const useTableState = ({
165167 } ,
166168 [ data , types ]
167169 ) ;
170+
168171 // Columns used by react-table
169172 const tableColumns = useMemo ( ( ) => {
173+ const allComponents = [ ...dimensions , ...measures ] ;
174+
170175 return orderedTableColumns . map ( ( c ) => {
171- const headerDimension = [ ... dimensions , ... measures ] . find (
172- ( dim ) => dim . iri === c . componentIri
176+ const headerComponent = allComponents . find (
177+ ( d ) => d . iri === c . componentIri
173178 ) ;
174179
175- if ( ! headerDimension ) {
180+ if ( ! headerComponent ) {
176181 throw Error ( `No dimension <${ c . componentIri } > in cube!` ) ;
177182 }
178183
179- const headerLabel = getLabelWithUnit ( headerDimension ) ;
184+ const sorters = makeDimensionValueSorters ( headerComponent , {
185+ sorting : { sortingType : "byTableSortingType" , sortingOrder : "asc" } ,
186+ } ) ;
187+
188+ const headerLabel = getLabelWithUnit ( headerComponent ) ;
180189
181190 // The column width depends on the estimated width of the
182191 // longest value in the column, with a minimum of 150px.
@@ -203,9 +212,24 @@ const useTableState = ({
203212 accessor : getSlugifiedIri ( c . componentIri ) ,
204213
205214 width,
206- // If sort type is not "basic", react-table default to "alphanumeric"
207- // which doesn't sort negative values properly.
208- sortType : "basic" ,
215+ sortType : (
216+ rowA : Row < Observation > ,
217+ rowB : Row < Observation > ,
218+ colId : string
219+ ) => {
220+ for ( const d of sorters ) {
221+ const result = ascending (
222+ d ( rowA . values [ colId ] ) ,
223+ d ( rowB . values [ colId ] )
224+ ) ;
225+
226+ if ( result ) {
227+ return result ;
228+ }
229+ }
230+
231+ return 0 ;
232+ } ,
209233 } ;
210234 } ) ;
211235 } , [ orderedTableColumns , data , dimensions , measures , formatNumber ] ) ;
@@ -337,22 +361,16 @@ const useTableState = ({
337361 ) ,
338362 ] ;
339363 const columnItemSizes = columnItems . map ( ( item ) => {
340- // @ts -ignore
341364 const itemAsString = formatter ( item ) ;
342365 return estimateTextWidth ( `${ itemAsString } ` , 16 ) + 80 ;
343366 } ) ;
344367 const width =
345368 Math . max ( max ( columnItemSizes , ( d ) => d ) || 150 , 150 ) -
346369 BAR_CELL_PADDING * 2 ;
347- // const hasNegativeValue =
348- // (min(data, (d) => Math.abs(+d[iri])) || 0) < 0;
349370 const domain = extent ( columnItems , ( d ) => d ) as [ number , number ] ;
350371 const widthScale = scaleLinear ( ) . domain ( domain ) . range ( [ 0 , width ] ) ;
351372
352- return {
353- ...common ,
354- widthScale,
355- } as BarColumnMeta ;
373+ return { ...common , widthScale } as BarColumnMeta ;
356374 } else {
357375 return null as never ;
358376 }
0 commit comments