From 8e3bf0be9415b214e503d8afcac7e892cf55ffb3 Mon Sep 17 00:00:00 2001 From: vishnukaushik Date: Tue, 24 Oct 2023 11:37:57 +0530 Subject: [PATCH 1/7] Add Rouge score lens --- src/lenses/RougeScoreLens.tsx | 31 +++++++++++++++++++++++++++++++ src/lenses/index.ts | 2 ++ 2 files changed, 33 insertions(+) create mode 100644 src/lenses/RougeScoreLens.tsx diff --git a/src/lenses/RougeScoreLens.tsx b/src/lenses/RougeScoreLens.tsx new file mode 100644 index 00000000..3ab166b4 --- /dev/null +++ b/src/lenses/RougeScoreLens.tsx @@ -0,0 +1,31 @@ + +import { log } from "console"; +import { Lens } from "../types"; + +const calculateRougeScore=(values: unknown[])=>{ + return values; +} + +const RougeScoreLens: Lens = ({values, columns})=>{ + const result = calculateRougeScore(values) + return ( + <> + RougeScoreView: {result} + + ) +} + +RougeScoreLens.key="RougeScoreView" +RougeScoreLens.dataTypes=["str"] +RougeScoreLens.defaultHeight = 100 +RougeScoreLens.minHeight=22 +RougeScoreLens.maxHeight=100 +RougeScoreLens.multi=true +RougeScoreLens.displayName="ROUGE Score" +RougeScoreLens.filterAllowedColumns=(allColumns, selectedColumns) => { + // if(selectedColumns.length===2) + // return selectedColumns + // else return [] + return [] +}; +export default RougeScoreLens \ No newline at end of file diff --git a/src/lenses/index.ts b/src/lenses/index.ts index 0a170cb5..35051f2d 100644 --- a/src/lenses/index.ts +++ b/src/lenses/index.ts @@ -10,6 +10,7 @@ import SequenceLens from './SequenceLens'; import SpectrogramLens from './SpectrogramLens'; import TextLens from './TextLens'; import VideoLens from './VideoLens'; +import RougeScoreLens from './RougeScoreLens'; export const ALL_LENSES = [ ArrayLens, @@ -24,4 +25,5 @@ export const ALL_LENSES = [ HtmlLens, MarkdownLens, ScalarLens, + RougeScoreLens, ]; From ff58f249944571b9e76d6cca57ec671e13d3b995 Mon Sep 17 00:00:00 2001 From: vishnukaushik Date: Tue, 24 Oct 2023 19:30:42 +0530 Subject: [PATCH 2/7] Added Rouge score --- package.json | 1 + pnpm-lock.yaml | 22 ++++++++++++++++++---- src/lenses/RougeScoreLens.tsx | 27 +++++++++++---------------- src/rouge.d.ts | 1 + 4 files changed, 31 insertions(+), 20 deletions(-) create mode 100644 src/rouge.d.ts diff --git a/package.json b/package.json index 88e8f3a9..4e1ef815 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,7 @@ "react-virtualized-auto-sizer": "^1.0.7", "react-window": "^1.8.8", "recharts": "^2.4.3", + "rouge": "^1.0.3", "seedrandom": "^3.0.5", "shallowequal": "^1.1.0", "short-uuid": "^4.2.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9847ebd2..c0407c55 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,5 +1,9 @@ lockfileVersion: '6.0' +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + dependencies: '@floating-ui/react': specifier: ^0.19.2 @@ -148,6 +152,9 @@ dependencies: recharts: specifier: ^2.4.3 version: 2.4.3(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0) + rouge: + specifier: ^1.0.3 + version: 1.0.3 seedrandom: specifier: ^3.0.5 version: 3.0.5 @@ -5376,6 +5383,11 @@ packages: p-locate: 5.0.0 dev: true + /lodash-node@2.4.1: + resolution: {integrity: sha512-egEt8eNQp2kZWRmngahiqMoDCDCENv3uM188S7Ed5t4k3v6RrLELXC+FqLNMUnhCo7gvQX3G1V8opK/Lcslahg==} + deprecated: This package is discontinued. Use lodash@^4.0.0. + dev: false + /lodash.castarray@4.4.0: resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==} dev: false @@ -6565,6 +6577,12 @@ packages: fsevents: 2.3.3 dev: true + /rouge@1.0.3: + resolution: {integrity: sha512-YCt74Dxsi99E8/uh943FTa80EmGboaOu1ij4q8WD4EAGyvyWYaH7MRHorrDbGgLY7iFUwDwyW/g9KJZx7D5fUQ==} + dependencies: + lodash-node: 2.4.1 + dev: false + /run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: @@ -7653,7 +7671,3 @@ packages: react: 18.2.0 use-sync-external-store: 1.2.0(react@18.2.0) dev: false - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false diff --git a/src/lenses/RougeScoreLens.tsx b/src/lenses/RougeScoreLens.tsx index 3ab166b4..223d9e0f 100644 --- a/src/lenses/RougeScoreLens.tsx +++ b/src/lenses/RougeScoreLens.tsx @@ -1,31 +1,26 @@ - -import { log } from "console"; import { Lens } from "../types"; +import rouge from 'rouge'; const calculateRougeScore=(values: unknown[])=>{ - return values; + return rouge.n(values[0], values[1]) + // return 0; } -const RougeScoreLens: Lens = ({values, columns})=>{ +const RougeScoreLens: Lens = ({values})=>{ const result = calculateRougeScore(values) - return ( - <> - RougeScoreView: {result} - - ) + return (<>Rouge score: {result}) } RougeScoreLens.key="RougeScoreView" RougeScoreLens.dataTypes=["str"] -RougeScoreLens.defaultHeight = 100 +RougeScoreLens.defaultHeight = 48 RougeScoreLens.minHeight=22 -RougeScoreLens.maxHeight=100 +RougeScoreLens.maxHeight=512 RougeScoreLens.multi=true RougeScoreLens.displayName="ROUGE Score" RougeScoreLens.filterAllowedColumns=(allColumns, selectedColumns) => { - // if(selectedColumns.length===2) - // return selectedColumns - // else return [] - return [] + if(selectedColumns.length===2) + return selectedColumns + else return allColumns.filter(({type}) => type.kind === 'str') }; -export default RougeScoreLens \ No newline at end of file +export default RougeScoreLens diff --git a/src/rouge.d.ts b/src/rouge.d.ts new file mode 100644 index 00000000..670ae045 --- /dev/null +++ b/src/rouge.d.ts @@ -0,0 +1 @@ +declare module "rouge" From 7afb9f7f888e987226d247e280f6b7d771bfc984 Mon Sep 17 00:00:00 2001 From: vishnukaushik Date: Wed, 25 Oct 2023 13:11:44 +0530 Subject: [PATCH 3/7] Added style and implemented isSatisfied property --- src/lenses/RougeScoreLens.tsx | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/lenses/RougeScoreLens.tsx b/src/lenses/RougeScoreLens.tsx index 223d9e0f..cdeafb38 100644 --- a/src/lenses/RougeScoreLens.tsx +++ b/src/lenses/RougeScoreLens.tsx @@ -1,26 +1,37 @@ import { Lens } from "../types"; +import 'twin.macro'; import rouge from 'rouge'; +import { formatNumber } from "../dataformat"; const calculateRougeScore=(values: unknown[])=>{ - return rouge.n(values[0], values[1]) - // return 0; + return rouge.n(values[0], values[1]) } const RougeScoreLens: Lens = ({values})=>{ const result = calculateRougeScore(values) - return (<>Rouge score: {result}) + return (
Rouge score: {formatNumber(result)}
) } RougeScoreLens.key="RougeScoreView" RougeScoreLens.dataTypes=["str"] -RougeScoreLens.defaultHeight = 48 +RougeScoreLens.defaultHeight = 22 RougeScoreLens.minHeight=22 -RougeScoreLens.maxHeight=512 +RougeScoreLens.maxHeight=64 RougeScoreLens.multi=true RougeScoreLens.displayName="ROUGE Score" RougeScoreLens.filterAllowedColumns=(allColumns, selectedColumns) => { if(selectedColumns.length===2) - return selectedColumns - else return allColumns.filter(({type}) => type.kind === 'str') + return [] + else return allColumns.filter(({type, key}) => { + const isNotSelected = (key)=>{ + return selectedColumns.filter((selectedCol)=>{selectedCol.key!==key}) + } + return type.kind === 'str' && isNotSelected(key); + }) }; +RougeScoreLens.isSatisfied = (columns)=>{ + if(columns.length===2) + return true; + return false; +} export default RougeScoreLens From 70b9448c0bf89749574cfed436230c8918d4c055 Mon Sep 17 00:00:00 2001 From: vishnukaushik Date: Wed, 25 Oct 2023 15:24:42 +0530 Subject: [PATCH 4/7] Formatted code --- src/lenses/RougeScoreLens.tsx | 65 +++++++++++++++++++---------------- src/rouge.d.ts | 1 - src/rougeScore.d.ts | 1 + 3 files changed, 36 insertions(+), 31 deletions(-) delete mode 100644 src/rouge.d.ts create mode 100644 src/rougeScore.d.ts diff --git a/src/lenses/RougeScoreLens.tsx b/src/lenses/RougeScoreLens.tsx index cdeafb38..5932bcf4 100644 --- a/src/lenses/RougeScoreLens.tsx +++ b/src/lenses/RougeScoreLens.tsx @@ -1,37 +1,42 @@ -import { Lens } from "../types"; +import { Lens } from '../types'; import 'twin.macro'; import rouge from 'rouge'; -import { formatNumber } from "../dataformat"; +import { formatNumber } from '../dataformat'; -const calculateRougeScore=(values: unknown[])=>{ - return rouge.n(values[0], values[1]) -} +const calculateRougeScore = (values: unknown[]) => { + return rouge.n(values[0], values[1]); +}; -const RougeScoreLens: Lens = ({values})=>{ - const result = calculateRougeScore(values) - return (
Rouge score: {formatNumber(result)}
) -} +const RougeScoreLens: Lens = ({ values }) => { + const result = calculateRougeScore(values); + return ( +
+ Rouge score: {formatNumber(result)} +
+ ); +}; -RougeScoreLens.key="RougeScoreView" -RougeScoreLens.dataTypes=["str"] -RougeScoreLens.defaultHeight = 22 -RougeScoreLens.minHeight=22 -RougeScoreLens.maxHeight=64 -RougeScoreLens.multi=true -RougeScoreLens.displayName="ROUGE Score" -RougeScoreLens.filterAllowedColumns=(allColumns, selectedColumns) => { - if(selectedColumns.length===2) - return [] - else return allColumns.filter(({type, key}) => { - const isNotSelected = (key)=>{ - return selectedColumns.filter((selectedCol)=>{selectedCol.key!==key}) - } - return type.kind === 'str' && isNotSelected(key); - }) +RougeScoreLens.key = 'RougeScoreView'; +RougeScoreLens.dataTypes = ['str']; +RougeScoreLens.defaultHeight = 22; +RougeScoreLens.minHeight = 22; +RougeScoreLens.maxHeight = 64; +RougeScoreLens.multi = true; +RougeScoreLens.displayName = 'ROUGE Score'; +RougeScoreLens.filterAllowedColumns = (allColumns, selectedColumns) => { + if (selectedColumns.length === 2) return []; + else + return allColumns.filter(({ type, key }) => { + const isNotSelected = (key: string) => { + return selectedColumns.filter((selectedCol) => { + selectedCol.key !== key; + }); + }; + return type.kind === 'str' && isNotSelected(key); + }); }; -RougeScoreLens.isSatisfied = (columns)=>{ - if(columns.length===2) - return true; +RougeScoreLens.isSatisfied = (columns) => { + if (columns.length === 2) return true; return false; -} -export default RougeScoreLens +}; +export default RougeScoreLens; diff --git a/src/rouge.d.ts b/src/rouge.d.ts deleted file mode 100644 index 670ae045..00000000 --- a/src/rouge.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module "rouge" diff --git a/src/rougeScore.d.ts b/src/rougeScore.d.ts new file mode 100644 index 00000000..a294f4d3 --- /dev/null +++ b/src/rougeScore.d.ts @@ -0,0 +1 @@ +declare module 'rouge'; From 584000ea18e7b76890fad81258590434ade36b68 Mon Sep 17 00:00:00 2001 From: vishnukaushik Date: Wed, 25 Oct 2023 20:37:10 +0530 Subject: [PATCH 5/7] Added rouge1 and rouge2 --- src/lenses/RougeScoreLens.tsx | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/src/lenses/RougeScoreLens.tsx b/src/lenses/RougeScoreLens.tsx index 5932bcf4..9ee86dbf 100644 --- a/src/lenses/RougeScoreLens.tsx +++ b/src/lenses/RougeScoreLens.tsx @@ -3,37 +3,34 @@ import 'twin.macro'; import rouge from 'rouge'; import { formatNumber } from '../dataformat'; -const calculateRougeScore = (values: unknown[]) => { - return rouge.n(values[0], values[1]); -}; - const RougeScoreLens: Lens = ({ values }) => { - const result = calculateRougeScore(values); + const rouge1 = rouge.n(values[0], values[1], 1); + const rouge2 = rouge.n(values[0], values[1], 2); return ( -
- Rouge score: {formatNumber(result)} +
+
+ Rouge 1: {formatNumber(rouge1)} +
+
+ Rouge 2: {formatNumber(rouge2)} +
); }; RougeScoreLens.key = 'RougeScoreView'; RougeScoreLens.dataTypes = ['str']; -RougeScoreLens.defaultHeight = 22; -RougeScoreLens.minHeight = 22; -RougeScoreLens.maxHeight = 64; +RougeScoreLens.defaultHeight = 50; +RougeScoreLens.minHeight = 50; +RougeScoreLens.maxHeight = 100; RougeScoreLens.multi = true; RougeScoreLens.displayName = 'ROUGE Score'; RougeScoreLens.filterAllowedColumns = (allColumns, selectedColumns) => { if (selectedColumns.length === 2) return []; - else - return allColumns.filter(({ type, key }) => { - const isNotSelected = (key: string) => { - return selectedColumns.filter((selectedCol) => { - selectedCol.key !== key; - }); - }; - return type.kind === 'str' && isNotSelected(key); - }); + const selectedKeys = selectedColumns.map((selectedCol) => selectedCol.key); + return allColumns.filter(({ type, key }) => { + return type.kind === 'str' && !selectedKeys.includes(key); + }); }; RougeScoreLens.isSatisfied = (columns) => { if (columns.length === 2) return true; From ded266b9a734f3cc360e274d8e225573751eca9b Mon Sep 17 00:00:00 2001 From: Dominik Haentsch Date: Fri, 27 Oct 2023 10:06:58 +0200 Subject: [PATCH 6/7] feat: globally switch between continuous and discrete coloring of ints --- src/components/AppBar.tsx | 28 +++--- src/components/ScalarValue.tsx | 2 +- src/hooks/useColorTransferFunction.ts | 46 ++++++--- src/stores/colors.ts | 45 ++++----- .../dataset/colorTransferFunctionFactory.tsx | 93 +++++-------------- src/stores/dataset/dataset.ts | 7 +- src/stores/dataset/statisticsFactory.tsx | 4 +- src/widgets/DataGrid/Cell/CategoricalCell.tsx | 2 +- src/widgets/Histogram/Histogram.tsx | 2 +- .../ScatterplotView/ScatterplotView.tsx | 4 +- src/widgets/SimilarityMap/SimilarityMap.tsx | 4 +- 11 files changed, 104 insertions(+), 133 deletions(-) diff --git a/src/components/AppBar.tsx b/src/components/AppBar.tsx index 05780480..c91a9422 100644 --- a/src/components/AppBar.tsx +++ b/src/components/AppBar.tsx @@ -137,16 +137,8 @@ const HelpMenu = (): JSX.Element => { ); }; -const useRobustColorScalesSelector = (c: ColorsState) => ({ - useRobustColorScales: c.useRobustColorScales, - setUseRobustColorScales: c.setUseRobustColorScales, -}); - const ColorMenu = () => { const colors = useColors(); - const { useRobustColorScales, setUseRobustColorScales } = useColors( - useRobustColorScalesSelector - ); const content = (
@@ -167,13 +159,27 @@ const ColorMenu = () => { onChangeColorPalette={colors.setCategoricalPalette} /> - Robust Coloring + + Continuous Ints Enable + + Continuous Categories + + Enable + + + Robust Coloring + + Enable +
); diff --git a/src/components/ScalarValue.tsx b/src/components/ScalarValue.tsx index 416d037e..ff5e7351 100644 --- a/src/components/ScalarValue.tsx +++ b/src/components/ScalarValue.tsx @@ -41,7 +41,7 @@ const ScalarValue: FunctionComponent = ({ // eslint-disable-next-line react-hooks/exhaustive-deps const colorTransferFunctionSelector = useCallback( (d: Dataset) => - d.colorTransferFunctions[column.key]?.[filtered ? 'filtered' : 'full'][0], + d.colorTransferFunctions[column.key]?.[filtered ? 'filtered' : 'full'], [column.key, filtered] ); diff --git a/src/hooks/useColorTransferFunction.ts b/src/hooks/useColorTransferFunction.ts index 2c992799..3b3f4d1e 100644 --- a/src/hooks/useColorTransferFunction.ts +++ b/src/hooks/useColorTransferFunction.ts @@ -109,36 +109,40 @@ export const createConstantTransferFunction = ( return tf as ConstantTransferFunction; }; -const createColorTransferFunction = ( +export const createColorTransferFunction = ( data: ColumnData | undefined, dType: DataType | undefined, + robust: boolean = false, + continuousInts = false, + continuousCategories = false, classBreaks?: number[] ): TransferFunction => { - const robustColoring = useColors.getState().useRobustColorScales; - if (dType === undefined) return createConstantTransferFunction(unknownDataType); if (data === undefined) return createConstantTransferFunction(dType); - if (['int', 'bool', 'Category', 'str'].includes(dType.kind)) { - const uniqValues = _.uniq(data); + if (['bool', 'str'].includes(dType.kind)) { + return createCategoricalTransferFunction(_.uniq(data), dType); + } + if (dType.kind === 'int' && !continuousInts) { + const uniqValues = _.uniq(data); const tooManyInts = dType.kind === 'int' && uniqValues.length > MAX_VALUES_FOR_INT_CATEGORY; if (!tooManyInts) { - const transferFunction = createCategoricalTransferFunction( - uniqValues, - dType - ); - return transferFunction; + return createCategoricalTransferFunction(uniqValues, dType); } } - if (['int', 'float'].includes(dType.kind)) { + if (dType.kind === 'Category' && !continuousCategories) { + return createCategoricalTransferFunction(_.uniq(data), dType); + } + + if (['int', 'float', 'Category'].includes(dType.kind)) { const stats = makeStats(dType, data); return createContinuousTransferFunction( - (robustColoring ? stats?.p5 : stats?.min) ?? 0, - (robustColoring ? stats?.p95 : stats?.max) ?? 1, + (robust ? stats?.p5 : stats?.min) ?? 0, + (robust ? stats?.p95 : stats?.max) ?? 1, dType, classBreaks ); @@ -148,7 +152,19 @@ const createColorTransferFunction = ( }; // eslint-disable-next-line @typescript-eslint/no-explicit-any -export const useColorTransferFunction = (data: any[], dtype: DataType) => - useMemo(() => createColorTransferFunction(data, dtype), [dtype, data]); +export const useColorTransferFunction = (data: any[], dtype: DataType) => { + const colors = useColors(); + return useMemo( + () => + createColorTransferFunction( + data, + dtype, + colors.robust, + colors.continuousInts, + colors.continuousCategories + ), + [dtype, data] + ); +}; export default useColorTransferFunction; diff --git a/src/stores/colors.ts b/src/stores/colors.ts index cf576ad5..d850f649 100644 --- a/src/stores/colors.ts +++ b/src/stores/colors.ts @@ -17,11 +17,15 @@ export interface ColorsState { constantPalette: ConstantPalette; categoricalPalette: CategoricalPalette; continuousPalette: ContinuousPalette; - useRobustColorScales: boolean; + robust: boolean; + continuousInts: boolean; + continuousCategories: boolean; setConstantPalette: (palette?: ConstantPalette) => void; setCategoricalPalette: (palette?: CategoricalPalette) => void; setContinuousPalette: (palette?: ContinuousPalette) => void; - setUseRobustColorScales: (useRobust: boolean) => void; + setRobust: (robust: boolean) => void; + setContinuousInts: (continuous: boolean) => void; + setContinuousCategories: (continuous: boolean) => void; } export const useColors = create()( @@ -30,35 +34,26 @@ export const useColors = create()( constantPalette: defaultConstantPalette, categoricalPalette: defaultCategoricalPalette, continuousPalette: defaultContinuousPalette, - useRobustColorScales: false, + robust: false, + continuousInts: false, + continuousCategories: false, setConstantPalette: (palette) => { - set((state) => { - return { - ...state, - constantPalette: palette ?? defaultConstantPalette, - }; - }); + set({ constantPalette: palette ?? defaultConstantPalette }); }, setCategoricalPalette: (palette) => { - set((state) => { - return { - ...state, - categoricalPalette: palette ?? defaultCategoricalPalette, - }; - }); + set({ categoricalPalette: palette ?? defaultCategoricalPalette }); }, setContinuousPalette: (palette) => { - set((state) => { - return { - ...state, - continuousPalette: palette ?? defaultContinuousPalette, - }; - }); + set({ continuousPalette: palette ?? defaultContinuousPalette }); + }, + setRobust: (robust: boolean) => { + set({ robust }); + }, + setContinuousInts: (continuousInts: boolean) => { + set({ continuousInts }); }, - setUseRobustColorScales: (useRobustColorScales: boolean) => { - set((state) => { - return { ...state, useRobustColorScales }; - }); + setContinuousCategories: (continuousCategories: boolean) => { + set({ continuousCategories }); }, }), { diff --git a/src/stores/dataset/colorTransferFunctionFactory.tsx b/src/stores/dataset/colorTransferFunctionFactory.tsx index f918ec43..318692ab 100644 --- a/src/stores/dataset/colorTransferFunctionFactory.tsx +++ b/src/stores/dataset/colorTransferFunctionFactory.tsx @@ -1,83 +1,40 @@ import { - DataType, - isCategorical, - isFloat, - isNumerical, - isScalar, -} from '../../datatypes'; -import { - createCategoricalTransferFunction, - createConstantTransferFunction, - createContinuousTransferFunction, + createColorTransferFunction, TransferFunction, } from '../../hooks/useColorTransferFunction'; import _ from 'lodash'; -import { useColors } from '../../stores/colors'; -import { - ColumnData, - DataColumn, - DataStatistics, - isCategoricalColumn, - isScalarColumn, - TableData, -} from '../../types'; -import { Dataset } from './dataset'; - -export const makeApplicableColorTransferFunctions = ( - type: DataType, - data: ColumnData, - stats?: DataStatistics -): TransferFunction[] => { - const transferFunctions: TransferFunction[] = []; - - if ((isCategorical(type) || isScalar(type)) && !isFloat(type)) { - const uniqueValues = _.uniq(data); - const transFn = createCategoricalTransferFunction(uniqueValues, type); - transferFunctions.push(transFn); - } - - if (isNumerical(type)) { - const useRobustColoring = useColors.getState().useRobustColorScales; - - const min = useRobustColoring ? stats?.p5 : stats?.min; - const max = useRobustColoring ? stats?.p95 : stats?.max; - - transferFunctions.push( - createContinuousTransferFunction(min || 0, max || 1, type) - ); - } - - transferFunctions.push(createConstantTransferFunction(type)); - - return transferFunctions; -}; +import { DataColumn, TableData } from '../../types'; +import { useColors } from '../colors'; type ColumnsTransferFunctions = Record< string, - { full: TransferFunction[]; filtered: TransferFunction[] } + { full: TransferFunction; filtered: TransferFunction } >; export const makeColumnsColorTransferFunctions = ( columns: DataColumn[], data: TableData, - stats: Dataset['columnStats'], filteredMask: boolean[] ): ColumnsTransferFunctions => { - return columns - .filter((column) => isScalarColumn(column) || isCategoricalColumn(column)) - .reduce((a, column) => { - a[column.key] = { - full: makeApplicableColorTransferFunctions( - column.type, - data[column.key], - stats.full[column.key] - ), - filtered: makeApplicableColorTransferFunctions( - column.type, - data[column.key].filter((_, i) => filteredMask[i]), - stats.filtered[column.key] - ), - }; - return a; - }, {} as ColumnsTransferFunctions); + const colors = useColors.getState(); + + return columns.reduce((a, column) => { + a[column.key] = { + full: createColorTransferFunction( + data[column.key], + column.type, + colors.robust, + colors.continuousInts, + colors.continuousCategories + ), + filtered: createColorTransferFunction( + data[column.key].filter((_, i) => filteredMask[i]), + column.type, + colors.robust, + colors.continuousInts, + colors.continuousCategories + ), + }; + return a; + }, {} as ColumnsTransferFunctions); }; diff --git a/src/stores/dataset/dataset.ts b/src/stores/dataset/dataset.ts index 4916c015..154f204d 100644 --- a/src/stores/dataset/dataset.ts +++ b/src/stores/dataset/dataset.ts @@ -44,8 +44,8 @@ export interface Dataset { colorTransferFunctions: Record< string, { - full: TransferFunction[]; - filtered: TransferFunction[]; + full: TransferFunction; + filtered: TransferFunction; } >; recomputeColorTransferFunctions: () => void; @@ -430,7 +430,6 @@ export const useDataset = create( const newTransferFunctions = makeColumnsColorTransferFunctions( get().columns.filter(({ key }) => columnsToCompute.includes(key)), get().columnData, - get().columnStats, get().isIndexFiltered ); @@ -535,6 +534,8 @@ useDataset.subscribe( } ); +useColors.subscribe(useDataset.getState().recomputeColorTransferFunctions); + useDataset.subscribe( (state) => state.selectedIndices, useDataset.getState().recomputeColumnRelevance diff --git a/src/stores/dataset/statisticsFactory.tsx b/src/stores/dataset/statisticsFactory.tsx index 20265276..d559821f 100644 --- a/src/stores/dataset/statisticsFactory.tsx +++ b/src/stores/dataset/statisticsFactory.tsx @@ -1,4 +1,4 @@ -import { DataType, isNumerical } from '../../datatypes'; +import { DataType, isCategorical, isNumerical } from '../../datatypes'; import { max, mean, min, quantile, standardDeviation } from 'simple-statistics'; import { ColumnData, @@ -13,7 +13,7 @@ export const makeStats = ( data: ColumnData, mask?: boolean[] ): DataStatistics | undefined => { - if (!isNumerical(type)) { + if (!isNumerical(type) && !isCategorical(type)) { return; } diff --git a/src/widgets/DataGrid/Cell/CategoricalCell.tsx b/src/widgets/DataGrid/Cell/CategoricalCell.tsx index f7cb40d2..187cfcb5 100644 --- a/src/widgets/DataGrid/Cell/CategoricalCell.tsx +++ b/src/widgets/DataGrid/Cell/CategoricalCell.tsx @@ -22,7 +22,7 @@ const CategoricalCell: FunctionComponent = ({ value, column }) => { (d: Dataset) => d.colorTransferFunctions[column.key]?.[ tableView !== 'full' ? 'filtered' : 'full' - ][0], + ], [column.key, tableView] ); diff --git a/src/widgets/Histogram/Histogram.tsx b/src/widgets/Histogram/Histogram.tsx index 99feb64e..1188520a 100644 --- a/src/widgets/Histogram/Histogram.tsx +++ b/src/widgets/Histogram/Histogram.tsx @@ -81,7 +81,7 @@ const Histogram: Widget = () => { stackByColumnKey ? d.colorTransferFunctions[stackByColumnKey]?.[ filter ? 'filtered' : 'full' - ][0] + ] : createConstantTransferFunction(), [filter, stackByColumnKey] ); diff --git a/src/widgets/ScatterplotView/ScatterplotView.tsx b/src/widgets/ScatterplotView/ScatterplotView.tsx index 3e9dd600..b4560728 100644 --- a/src/widgets/ScatterplotView/ScatterplotView.tsx +++ b/src/widgets/ScatterplotView/ScatterplotView.tsx @@ -139,9 +139,7 @@ const ScatterplotView: Widget = () => { const transferFunctionSelector = useCallback( (d: Dataset) => colorByKey !== undefined && colorByKey.length > 0 - ? d.colorTransferFunctions[colorByKey]?.[ - filter ? 'filtered' : 'full' - ][0] + ? d.colorTransferFunctions[colorByKey]?.[filter ? 'filtered' : 'full'] : createConstantTransferFunction(), [colorByKey, filter] ); diff --git a/src/widgets/SimilarityMap/SimilarityMap.tsx b/src/widgets/SimilarityMap/SimilarityMap.tsx index 023c4dd1..9bd9c55f 100644 --- a/src/widgets/SimilarityMap/SimilarityMap.tsx +++ b/src/widgets/SimilarityMap/SimilarityMap.tsx @@ -243,9 +243,7 @@ const SimilarityMap: Widget = () => { const transferFunctionSelector = useCallback( (d: Dataset) => colorByKey !== undefined && colorByKey.length > 0 - ? d.colorTransferFunctions[colorByKey]?.[ - filter ? 'filtered' : 'full' - ][0] + ? d.colorTransferFunctions[colorByKey]?.[filter ? 'filtered' : 'full'] : createConstantTransferFunction(colorBy?.type ?? unknownDataType), [colorByKey, filter, colorBy?.type] ); From f0e01678e973a3c3e403f0809a5f743158475c67 Mon Sep 17 00:00:00 2001 From: Dominik Haentsch Date: Fri, 27 Oct 2023 10:31:44 +0200 Subject: [PATCH 7/7] chore: fix linter errors --- src/components/AppBar.tsx | 1 - src/hooks/useColorTransferFunction.ts | 4 ++-- src/stores/dataset/colorTransferFunctionFactory.tsx | 5 ++--- src/stores/dataset/dataset.ts | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/components/AppBar.tsx b/src/components/AppBar.tsx index c91a9422..2b2799fe 100644 --- a/src/components/AppBar.tsx +++ b/src/components/AppBar.tsx @@ -19,7 +19,6 @@ import MainWalkthrough, { Handle as MainWalkthroughRef, } from './walkthrough/MainWalkthrough'; import { useColors } from '../stores/colors'; -import type { ColorsState } from '../stores/colors'; import ColorPaletteSelect from './ui/ColorPaletteSelect'; import { categoricalPalettes, continuousPalettes } from '../palettes'; diff --git a/src/hooks/useColorTransferFunction.ts b/src/hooks/useColorTransferFunction.ts index 3b3f4d1e..1939342c 100644 --- a/src/hooks/useColorTransferFunction.ts +++ b/src/hooks/useColorTransferFunction.ts @@ -112,7 +112,7 @@ export const createConstantTransferFunction = ( export const createColorTransferFunction = ( data: ColumnData | undefined, dType: DataType | undefined, - robust: boolean = false, + robust = false, continuousInts = false, continuousCategories = false, classBreaks?: number[] @@ -163,7 +163,7 @@ export const useColorTransferFunction = (data: any[], dtype: DataType) => { colors.continuousInts, colors.continuousCategories ), - [dtype, data] + [dtype, data, colors.robust, colors.continuousInts, colors.continuousCategories] ); }; diff --git a/src/stores/dataset/colorTransferFunctionFactory.tsx b/src/stores/dataset/colorTransferFunctionFactory.tsx index 318692ab..a868bfa2 100644 --- a/src/stores/dataset/colorTransferFunctionFactory.tsx +++ b/src/stores/dataset/colorTransferFunctionFactory.tsx @@ -2,7 +2,6 @@ import { createColorTransferFunction, TransferFunction, } from '../../hooks/useColorTransferFunction'; -import _ from 'lodash'; import { DataColumn, TableData } from '../../types'; import { useColors } from '../colors'; @@ -14,7 +13,7 @@ type ColumnsTransferFunctions = Record< export const makeColumnsColorTransferFunctions = ( columns: DataColumn[], data: TableData, - filteredMask: boolean[] + filteredIndices: Int32Array ): ColumnsTransferFunctions => { const colors = useColors.getState(); @@ -28,7 +27,7 @@ export const makeColumnsColorTransferFunctions = ( colors.continuousCategories ), filtered: createColorTransferFunction( - data[column.key].filter((_, i) => filteredMask[i]), + filteredIndices.map((i) => data[column.key][i]), column.type, colors.robust, colors.continuousInts, diff --git a/src/stores/dataset/dataset.ts b/src/stores/dataset/dataset.ts index 154f204d..123ec75d 100644 --- a/src/stores/dataset/dataset.ts +++ b/src/stores/dataset/dataset.ts @@ -430,7 +430,7 @@ export const useDataset = create( const newTransferFunctions = makeColumnsColorTransferFunctions( get().columns.filter(({ key }) => columnsToCompute.includes(key)), get().columnData, - get().isIndexFiltered + get().filteredIndices ); set({