Skip to content

Commit 68eab9e

Browse files
authored
Merge pull request #588 from adobe/moveExpressionFunctions
Move expression functions
2 parents fb2d99e + c633ed4 commit 68eab9e

File tree

9 files changed

+152
-32
lines changed

9 files changed

+152
-32
lines changed

packages/react-spectrum-charts/src/VegaChart.tsx

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,8 @@ import { Options as TooltipOptions } from 'vega-tooltip';
1717

1818
import { TABLE } from '@spectrum-charts/constants';
1919
import { getLocale } from '@spectrum-charts/locales';
20+
import { getVegaEmbedOptions } from '@spectrum-charts/vega-spec-builder';
2021

21-
import {
22-
expressionFunctions,
23-
formatLocaleCurrency,
24-
formatShortNumber,
25-
formatTimeDurationLabels,
26-
} from './expressionFunctions';
2722
import { useDebugSpec } from './hooks/useDebugSpec';
2823
import { extractValues, isVegaData } from './hooks/useSpec';
2924
import { ChartData, ChartProps } from './types';
@@ -62,12 +57,6 @@ export const VegaChart: FC<VegaChartProps> = ({
6257
const chartView = useRef<View>();
6358

6459
const { number: numberLocale, time: timeLocale } = useMemo(() => getLocale(locale), [locale]);
65-
const localeCode = useMemo(() => {
66-
if (typeof locale === 'string') {
67-
return locale;
68-
}
69-
return locale?.number;
70-
}, [locale]);
7160

7261
// Need to de a deep copy of the data because vega tries to transform the data
7362
const chartData = useMemo(() => {
@@ -100,22 +89,15 @@ export const VegaChart: FC<VegaChartProps> = ({
10089
});
10190
}
10291
embed(containerRef.current, specCopy, {
103-
actions: false,
104-
ast: true,
105-
config,
106-
expressionFunctions: {
107-
...expressionFunctions,
108-
formatTimeDurationLabels: formatTimeDurationLabels(numberLocale),
109-
formatLocaleCurrency: formatLocaleCurrency(numberLocale),
110-
formatShortNumber: formatShortNumber(localeCode),
111-
},
112-
formatLocale: numberLocale as unknown as Record<string, unknown>, // these are poorly typed by vega-embed
113-
height,
114-
padding,
115-
renderer,
116-
timeFormatLocale: timeLocale as unknown as Record<string, unknown>, // these are poorly typed by vega-embed
92+
...getVegaEmbedOptions({
93+
locale,
94+
height,
95+
width,
96+
padding,
97+
renderer,
98+
config,
99+
}),
117100
tooltip,
118-
width,
119101
}).then(({ view }) => {
120102
chartView.current = view;
121103
onNewView(view);
@@ -146,7 +128,7 @@ export const VegaChart: FC<VegaChartProps> = ({
146128
spec,
147129
tooltip,
148130
width,
149-
localeCode,
131+
locale,
150132
]);
151133

152134
return <div ref={containerRef} className="rsc"></div>;

packages/vega-spec-builder/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
},
2121
"dependencies": {
2222
"@spectrum-charts/constants": "1.17.3",
23+
"@spectrum-charts/locales": "1.17.3",
2324
"@spectrum-charts/themes": "1.17.3",
2425
"@spectrum-charts/utils": "1.17.3",
2526
"immer": "^10.1.1",

packages/react-spectrum-charts/src/expressionFunctions.ts renamed to packages/vega-spec-builder/src/expressionFunctions/expressionFunctions.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,39 @@
1010
* governing permissions and limitations under the License.
1111
*/
1212
import { FormatLocaleDefinition, formatLocale } from 'd3-format';
13-
import { FontWeight } from 'vega';
13+
import { FontWeight, Locale, NumberLocale, TimeLocale } from 'vega';
1414

15-
import { numberLocales } from '@spectrum-charts/locales';
15+
import { LocaleCode, NumberLocaleCode, TimeLocaleCode, getLocale, numberLocales } from '@spectrum-charts/locales';
1616
import { ADOBE_CLEAN_FONT } from '@spectrum-charts/themes';
17-
import { NumberFormat } from '@spectrum-charts/vega-spec-builder';
17+
18+
import { NumberFormat } from '../types';
1819

1920
export interface LabelDatum {
2021
index: number;
2122
label: string;
2223
value: string | number;
2324
}
2425

26+
export const getExpressionFunctions = (
27+
locale:
28+
| Locale
29+
| LocaleCode
30+
| { number?: NumberLocaleCode | NumberLocale; time?: TimeLocaleCode | TimeLocale } = 'en-US'
31+
) => {
32+
const { number: numberLocale } = getLocale(locale);
33+
const localeCode = typeof locale === 'string' ? locale : locale?.number;
34+
return {
35+
formatTimeDurationLabels: formatTimeDurationLabels(numberLocale),
36+
formatLocaleCurrency: formatLocaleCurrency(numberLocale),
37+
formatShortNumber: formatShortNumber(localeCode),
38+
consoleLog,
39+
formatHorizontalTimeAxisLabels: formatHorizontalTimeAxisLabels(),
40+
formatVerticalAxisTimeLabels: formatVerticalAxisTimeLabels(),
41+
getLabelWidth,
42+
truncateText,
43+
};
44+
};
45+
2546
/**
2647
* Formats a number using the compact notation.
2748
* @param numberLocale
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/*
2+
* Copyright 2025 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
export * from './expressionFunctions';

packages/vega-spec-builder/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@
1313
export * from './chartSpecBuilder';
1414
export * from './specUtils';
1515
export * from './types';
16+
export * from './expressionFunctions';
17+
export * from './vegaEmbedUtils';
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2025 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
import { numberLocales } from '@spectrum-charts/locales';
13+
14+
import { getVegaEmbedOptions } from './vegaEmbedUtils';
15+
16+
describe('getVegaEmbedOptions()', () => {
17+
it('should return the correct options', () => {
18+
const options = getVegaEmbedOptions({});
19+
expect(options).toHaveProperty('actions', false);
20+
expect(options).toHaveProperty('ast', true);
21+
expect(options).toHaveProperty('expressionFunctions');
22+
expect(options).toHaveProperty('formatLocale');
23+
expect(options).toHaveProperty('height', 400);
24+
expect(options).toHaveProperty('width', 600);
25+
expect(options).toHaveProperty('padding', 0);
26+
});
27+
it('should use the correct color scheme', () => {
28+
let options = getVegaEmbedOptions({ colorScheme: 'dark' });
29+
expect(options?.config?.text?.fill).toEqual('rgb(235, 235, 235)');
30+
options = getVegaEmbedOptions({ colorScheme: 'light' });
31+
expect(options?.config?.text?.fill).toEqual('rgb(34, 34, 34)');
32+
});
33+
it('should default to en-US', () => {
34+
const enLocale = numberLocales['en-US'];
35+
const options = getVegaEmbedOptions({});
36+
expect(options?.formatLocale).toEqual(enLocale);
37+
});
38+
it('should use the correct locale if provided', () => {
39+
const frLocale = numberLocales['fr-FR'];
40+
const options = getVegaEmbedOptions({ locale: 'fr-FR' });
41+
expect(options?.formatLocale).toEqual(frLocale);
42+
});
43+
});
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright 2025 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
import { Config, Locale, NumberLocale, Padding, Renderers, TimeLocale } from 'vega';
13+
14+
import { DEFAULT_COLOR_SCHEME } from '@spectrum-charts/constants';
15+
import { LocaleCode, NumberLocaleCode, TimeLocaleCode, getLocale } from '@spectrum-charts/locales';
16+
17+
import { getExpressionFunctions } from './expressionFunctions';
18+
import { getChartConfig } from './specUtils';
19+
20+
export const getVegaEmbedOptions = ({
21+
locale = 'en-US',
22+
height = 400,
23+
width = 600,
24+
padding = 0,
25+
renderer = 'svg',
26+
config,
27+
colorScheme = DEFAULT_COLOR_SCHEME,
28+
}: {
29+
locale?: Locale | LocaleCode | { number?: NumberLocaleCode | NumberLocale; time?: TimeLocaleCode | TimeLocale };
30+
height?: number;
31+
width?: number;
32+
padding?: Padding;
33+
renderer?: Renderers;
34+
config?: Config;
35+
colorScheme?: 'light' | 'dark';
36+
}) => {
37+
const expressionFunctions = getExpressionFunctions(locale);
38+
const { number: numberLocale, time: timeLocale } = getLocale(locale);
39+
const chartConfig = config ?? getChartConfig(undefined, colorScheme);
40+
41+
return {
42+
actions: false,
43+
ast: true,
44+
expressionFunctions,
45+
formatLocale: numberLocale as unknown as Record<string, unknown>, // these are poorly typed by vega-embed
46+
height,
47+
width,
48+
padding,
49+
renderer,
50+
timeFormatLocale: timeLocale as unknown as Record<string, unknown>, // these are poorly typed by vega-embed
51+
config: chartConfig,
52+
};
53+
};

packages/vega-spec-builder/tsconfig.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,10 @@
99
},
1010
"include": ["src/**/*", "index.ts"],
1111
"exclude": ["*.test.ts"],
12-
"references": [{ "path": "../constants" }, { "path": "../themes" }, { "path": "../utils" }]
12+
"references": [
13+
{ "path": "../constants" },
14+
{ "path": "../themes" },
15+
{ "path": "../utils" },
16+
{ "path": "../locales" }
17+
]
1318
}

0 commit comments

Comments
 (0)