@@ -13,6 +13,7 @@ import {
1313 getLegendOfScale ,
1414 initCustomPaletteByCustomScale ,
1515 histogramFromValues ,
16+ histogramFromOrdinal ,
1617 histogramFromThreshold ,
1718 getHistogramDomain ,
1819 hasColorMap
@@ -176,8 +177,17 @@ function ColorScaleSelectorFactory(
176177 : idx => dataset . dataContainer . rowAsArray ( idx ) ;
177178 } , [ dataset , field ] ) ;
178179
180+ const ordinalDomain = useMemo ( ( ) => {
181+ return layer . config [ layer . visualChannels [ channelKey ] . domain ] || [ ] ;
182+ } , [ channelKey , layer . config , layer . visualChannels ] ) ;
183+
179184 // aggregatedBins should be the raw data
180185 const allBins = useMemo ( ( ) => {
186+ if ( field ?. type === ALL_FIELD_TYPES . string ) {
187+ // Use ordinal bins for string columns, as d3 could potentially generate invalid numeric bins, and crash
188+ return histogramFromOrdinal ( ordinalDomain , dataset . allIndexes , fieldValueAccessor ) ;
189+ }
190+
181191 if ( aggregatedBins ) {
182192 return histogramFromValues (
183193 Object . values ( aggregatedBins ) . map ( bin => bin . i ) ,
@@ -188,16 +198,12 @@ function ColorScaleSelectorFactory(
188198 return columnStats ?. bins
189199 ? columnStats ?. bins
190200 : histogramFromValues ( dataset . allIndexes , HISTOGRAM_BINS , fieldValueAccessor ) ;
191- } , [ aggregatedBins , columnStats , dataset , fieldValueAccessor ] ) ;
201+ } , [ aggregatedBins , columnStats , dataset , fieldValueAccessor , field ?. type , ordinalDomain ] ) ;
192202
193203 const histogramDomain = useMemo ( ( ) => {
194204 return getHistogramDomain ( { aggregatedBins, columnStats, dataset, fieldValueAccessor} ) ;
195205 } , [ dataset , fieldValueAccessor , aggregatedBins , columnStats ] ) ;
196206
197- const ordinalDomain = useMemo ( ( ) => {
198- return layer . config [ layer . visualChannels [ channelKey ] . domain ] || [ ] ;
199- } , [ channelKey , layer . config , layer . visualChannels ] ) ;
200-
201207 const isFiltered = aggregatedBins
202208 ? false
203209 : dataset . filteredIndexForDomain . length !== dataset . allIndexes . length ;
@@ -207,16 +213,23 @@ function ColorScaleSelectorFactory(
207213 if ( ! isFiltered ) {
208214 return allBins ;
209215 }
210- // get threholds
216+ if ( field ?. type === ALL_FIELD_TYPES . string ) {
217+ return histogramFromOrdinal (
218+ ordinalDomain as any ,
219+ dataset . filteredIndexForDomain ,
220+ fieldValueAccessor
221+ ) ;
222+ }
223+ // numeric thresholds
211224 const filterEmptyBins = false ;
212- const threholds = allBins . map ( b => b . x0 ) ;
225+ const thresholds = allBins . map ( b => b . x0 ) ;
213226 return histogramFromThreshold (
214- threholds ,
227+ thresholds ,
215228 dataset . filteredIndexForDomain ,
216229 fieldValueAccessor ,
217230 filterEmptyBins
218231 ) ;
219- } , [ dataset , fieldValueAccessor , allBins , isFiltered ] ) ;
232+ } , [ dataset , fieldValueAccessor , allBins , isFiltered , field ?. type , ordinalDomain ] ) ;
220233
221234 const onSelectScale = useCallback (
222235 val => {
0 commit comments