Skip to content

Commit

Permalink
Merge pull request #372 from Renumics/feature/configure-notation-for-…
Browse files Browse the repository at this point in the history
…numbers

Feature/configure notation for numbers
  • Loading branch information
neindochoh authored Nov 20, 2023
2 parents 3aa6d48 + 5a0d325 commit 11ccd3f
Show file tree
Hide file tree
Showing 21 changed files with 290 additions and 330 deletions.
32 changes: 32 additions & 0 deletions src/components/AppBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import GithubIcon from '../icons/Github';
import HelpIcon from '../icons/Help';
import OpenFolderIcon from '../icons/OpenFolder';
import ColorPaletteIcon from '../icons/ColorPalette';
import NumberIcon from '../icons/Number';
import Button from './ui/Button';
import Dialog from './ui/Dialog';
import Dropdown, { DropdownContext } from './ui/Dropdown';
Expand All @@ -21,6 +22,8 @@ import MainWalkthrough, {
import { useColors } from '../stores/colors';
import ColorPaletteSelect from './ui/ColorPaletteSelect';
import { categoricalPalettes, continuousPalettes } from '../palettes';
import Select from './ui/Select';
import { Notation, notations, useAppSettings } from '../stores/appSettings';

const NavBar = tw.nav`py-0.5 px-1 bg-gray-200 flex items-center w-full top-0 z-10 border-b border-gray-400`;

Expand Down Expand Up @@ -190,6 +193,34 @@ const ColorMenu = () => {
);
};

const NumberMenu = () => {
const notation = useAppSettings((s) => s.numberNotation);
const onChangeNotation = (value?: Notation) => {
if (value) useAppSettings.getState().setNumberNotation(value);
};

const content = (
<div tw="flex flex-col w-72 pb-1">
<Menu>
<Menu.Title>Notation</Menu.Title>
<Menu.Item>
<Select
options={notations}
value={notation}
onChange={onChangeNotation}
/>
</Menu.Item>
</Menu>
</div>
);

return (
<Dropdown content={content} tooltip="Numbers">
<NumberIcon />
</Dropdown>
);
};

const UpgradeButton = (): JSX.Element => {
return (
<a href="https://renumics.com/product/pricing" target="_blank" rel="noreferrer">
Expand Down Expand Up @@ -220,6 +251,7 @@ const AppBar = (): JSX.Element => {
<FileBar tw="flex-grow" />
<div tw="flex items-center">
<ColorMenu />
<NumberMenu />
<HelpMenu />
<GitHubButton />
{appBarItems.map((item, i) => (
Expand Down
6 changes: 3 additions & 3 deletions src/components/ColumnSelector/ColumnSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
useState,
} from 'react';
import tw from 'twin.macro';
import dataformat from '../../dataformat';
import { formatType } from '../../dataformat';
import X from '../../icons/X';
import { DataColumn } from '../../types';
import { DropdownContext } from '../ui/Dropdown';
Expand Down Expand Up @@ -43,8 +43,8 @@ const ColumnSelector = ({
(c) =>
regex.test(c.name) ||
regex.test(c.type.kind) ||
regex.test(dataformat.formatType(c.type)) ||
regex.test(dataformat.formatType(c.type, true)) ||
regex.test(formatType(c.type)) ||
regex.test(formatType(c.type, true)) ||
c.tags?.some((tag) => regex.test(tag))
);
}, [availableColumns, searchTerm]);
Expand Down
17 changes: 10 additions & 7 deletions src/components/FilterBar/FilterText.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FunctionComponent } from 'react';
import tw, { styled } from 'twin.macro';
import dataformat from '../../dataformat';
import { useDataformat } from '../../dataformat';
import { Filter, PredicateFilter, SetFilter } from '../../types';
import SelectionIcon from '../../icons/Selection';

Expand All @@ -18,12 +18,15 @@ const FilterIconSpan = styled.span`

const PredicateFilterText: FunctionComponent<{ filter: PredicateFilter }> = ({
filter,
}) => (
<>
{filter.column.name} {filter.predicate.shorthand}{' '}
{dataformat.format(filter.referenceValue, filter.type)}
</>
);
}) => {
const formatter = useDataformat();
return (
<>
{filter.column.name} {filter.predicate.shorthand}{' '}
{formatter.format(filter.referenceValue, filter.type)}
</>
);
};

const SetFilterText: FunctionComponent<{ filter: SetFilter }> = ({ filter }) => (
<>
Expand Down
7 changes: 4 additions & 3 deletions src/components/FilterBar/ValueInput.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Checkbox from '../ui/Checkbox';
import Select from '../ui/Select';
import dataformat from '../../dataformat';
import { parse, useDataformat } from '../../dataformat';
import { CategoricalDataType, DataType } from '../../datatypes';
import { ChangeEvent, KeyboardEvent, useCallback } from 'react';
import 'twin.macro';
Expand Down Expand Up @@ -53,7 +53,7 @@ const DefaultInput = ({
}: Props): JSX.Element => {
const onChangeInput = useCallback(
(e: ChangeEvent<HTMLInputElement>) => {
const value = dataformat.parse(e.target.value, type);
const value = parse(e.target.value, type);
onChange?.(value);
},
[onChange, type]
Expand All @@ -62,12 +62,13 @@ const DefaultInput = ({
const onKeyDown = useCallback(
(e: KeyboardEvent<HTMLInputElement>) => {
if (onEnter && e.key === 'Enter') {
onEnter(dataformat.parse(e.currentTarget.value, type));
onEnter(parse(e.currentTarget.value, type));
}
},
[onEnter, type]
);

const dataformat = useDataformat();
const defaultValue =
value === undefined ? undefined : dataformat.format(value, type);

Expand Down
36 changes: 20 additions & 16 deletions src/components/LineChart/LineChart.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { formatNumber } from '../../dataformat';
import { useDataformat } from '../../dataformat';
import _ from 'lodash';
import * as React from 'react';
import { forwardRef, useCallback, useImperativeHandle, useMemo, useState } from 'react';
Expand Down Expand Up @@ -89,21 +89,20 @@ const TooltipContent: React.FunctionComponent<{
: undefined;
}, [chartData]);

const dataformat = useDataformat();

return (
<Bubble>
<div>
{formatNumber(label ?? 0)} {xLabel}
{dataformat.formatFloat(label ?? 0)} {xLabel}
</div>
{payload.map((p, index) => {
if (!p.data?.[1]) return null;
return (
<div key={index} tw="flex" style={{ color: p.color }}>
<div tw="flex-grow mr-2">{p.name}</div>
<div>
{formatNumber(p.data[1], {
mantissa: 10,
})}{' '}
{p.yLabel}
{dataformat.formatFloat(p.data[1])} {p.yLabel}
</div>
</div>
);
Expand Down Expand Up @@ -246,14 +245,19 @@ const LineChart: React.ForwardRefRenderFunction<Handle, LineChartProps> = (
if (e.buttons === 1) setRefAreaRight(chartState.activeLabel);
}, []);

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const formatter = useCallback((value: any) => {
if (typeof value === 'number') {
return formatNumber(value);
} else {
return value.toString();
}
}, []);
const dataformat = useDataformat();

const formatter = useCallback(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(value: any) => {
if (typeof value === 'number') {
return dataformat.formatFloat(value);
} else {
return value.toString();
}
},
[dataformat]
);

const xDomain = useMemo(() => ['dataMin', 'dataMax'], []);
const allowEscapeViewBox = useMemo(() => ({ x: false, y: false }), []);
Expand All @@ -269,8 +273,8 @@ const LineChart: React.ForwardRefRenderFunction<Handle, LineChartProps> = (
return (
<Info>
<span>
No Data in Range ({formatNumber(xExtents[0])},{' '}
{formatNumber(xExtents[1])})
No Data in Range ({dataformat.formatFloat(xExtents[0])},{' '}
{dataformat.formatFloat(xExtents[1])})
</span>
</Info>
);
Expand Down
16 changes: 6 additions & 10 deletions src/components/ScalarValue.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import Dot from './ui/Dot';
import Tooltip from './ui/Tooltip';
import dataformat from '../dataformat';
import { useDataformat } from '../dataformat';
import { isNumerical } from '../datatypes';
import { FunctionComponent, memo, useCallback, useMemo } from 'react';
import { FunctionComponent, memo, useCallback } from 'react';
import { Dataset, useDataset } from '../stores/dataset';
import tw, { styled } from 'twin.macro';
import { DataColumn } from '../types';
Expand All @@ -28,16 +28,12 @@ const ScalarValue: FunctionComponent<Props> = ({
column,
filtered = false,
}) => {
const formattedValue = useMemo(
() => dataformat.format(value, column.type),
[value, column.type]
);
const fullValue = useMemo(
() => dataformat.format(value, column.type, true),
[value, column.type]
);
const isNumber = isNumerical(column.type);

const dataformat = useDataformat();
const formattedValue = dataformat.format(value, column.type);
const fullValue = dataformat.format(value, column.type, true);

// eslint-disable-next-line react-hooks/exhaustive-deps
const colorTransferFunctionSelector = useCallback(
(d: Dataset) =>
Expand Down
14 changes: 9 additions & 5 deletions src/components/shared/Plot/Legend/ContinuousLegend.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Color } from 'chroma-js';
import * as d3 from 'd3';
import dataformat from '../../../../dataformat';
import { useDataformat } from '../../../../dataformat';
import { ContinuousTransferFunction } from '../../../../hooks/useColorTransferFunction';
import _ from 'lodash';
import { useEffect, useMemo, useRef, useState } from 'react';
Expand Down Expand Up @@ -68,14 +68,16 @@ export const ContinuousLegend = ({
});
}, [domain, gradientID, steps]);

const dataformat = useDataformat();

return (
<ContinuousLegendWrapper arrange={arrange} align={align}>
<ContinuousLegendAnnotationWrapper arrange={arrange}>
<span style={{ textAlign: align }}>
{dataformat.formatNumber(domain[0])}
{dataformat.formatFloat(domain[0])}
</span>
<span style={{ textAlign: align }}>
{dataformat.formatNumber(domain[1])}
{dataformat.formatFloat(domain[1])}
</span>
</ContinuousLegendAnnotationWrapper>
<ContinuousLegendSVGWrapper arrange={arrange} ref={svgRef}>
Expand Down Expand Up @@ -126,20 +128,22 @@ export const ContinuousTransferFunctionLegend = ({
return valSteps.map((v) => transferFunction(v));
}, [domain, transferFunction]);

const dataformat = useDataformat();

const classBreaksColorMap = useMemo(() => {
if (transferFunction.classBreaks === undefined) return undefined;

return transferFunction.classBreaks.slice(1).map((v, i) => {
const start = transferFunction.classBreaks?.[i] || 0;
const end = v;
return {
label: `${dataformat.formatNumber(start)} - ${dataformat.formatNumber(
label: `${dataformat.formatFloat(start)} - ${dataformat.formatFloat(
end
)}`,
color: transferFunction((start + end) / 2),
};
});
}, [transferFunction]);
}, [transferFunction, dataformat]);

if (classBreaksColorMap !== undefined) {
return <CategoricalLegend colorMap={classBreaksColorMap} {...props} />;
Expand Down
8 changes: 5 additions & 3 deletions src/components/shared/Plot/XAxis.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as d3 from 'd3';
import { formatNumber } from '../../../dataformat';
import { useDataformat } from '../../../dataformat';
import { FunctionComponent, useContext, useEffect } from 'react';
import { theme } from 'twin.macro';
import PlotContext from './PlotContext';
Expand All @@ -23,6 +23,8 @@ function findOrCreateGroup<P extends SVGElement>(parentElement: P) {
const XAxis: FunctionComponent<Props> = ({ caption }) => {
const { transform, svgRef, width, height, xScale } = useContext(PlotContext);

const formatter = useDataformat();

useEffect(() => {
if (!transform || !svgRef.current) return;

Expand All @@ -40,7 +42,7 @@ const XAxis: FunctionComponent<Props> = ({ caption }) => {
)
.ticks(width / 64)
.tickSizeOuter(0)
.tickFormat((value) => formatNumber(value as number));
.tickFormat((value) => formatter.formatFloat(value as number));

group.attr('transform', `translate(0, ${height})`);
group.style('font-size', '0.75rem');
Expand Down Expand Up @@ -69,7 +71,7 @@ const XAxis: FunctionComponent<Props> = ({ caption }) => {
.attr('color', theme`colors.midnight.600`)
.attr('text-anchor', 'end')
.text(caption ?? '');
}, [transform, svgRef, width, height, xScale, caption]);
}, [transform, svgRef, width, height, xScale, caption, formatter]);

return <></>;
};
Expand Down
8 changes: 5 additions & 3 deletions src/components/shared/Plot/YAxis.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as d3 from 'd3';
import { formatNumber } from '../../../dataformat';
import { useDataformat } from '../../../dataformat';
import { FunctionComponent, useContext, useEffect } from 'react';
import { theme } from 'twin.macro';
import PlotContext from './PlotContext';
Expand All @@ -23,6 +23,8 @@ function findOrCreateGroup<P extends SVGElement>(parentElement: P) {
const YAxis: FunctionComponent<Props> = ({ caption }) => {
const { transform, svgRef, width, height, yScale } = useContext(PlotContext);

const formatter = useDataformat();

useEffect(() => {
if (!transform || !svgRef.current) return;

Expand All @@ -40,7 +42,7 @@ const YAxis: FunctionComponent<Props> = ({ caption }) => {
)
.ticks(height / 64)
.tickSizeOuter(0)
.tickFormat((value) => formatNumber(value as number));
.tickFormat((value) => formatter.formatFloat(value as number));

group.style('font-size', '0.75rem');
group.style('color', theme`colors.gray.900`);
Expand Down Expand Up @@ -68,7 +70,7 @@ const YAxis: FunctionComponent<Props> = ({ caption }) => {
.attr('color', theme`colors.midnight.600`)
.attr('text-anchor', 'start')
.text(caption ?? '');
}, [transform, svgRef, width, height, yScale, caption]);
}, [transform, svgRef, width, height, yScale, caption, formatter]);

return <></>;
};
Expand Down
Loading

0 comments on commit 11ccd3f

Please sign in to comment.