Skip to content

Commit

Permalink
Merge pull request adobe#46 from adobe/backgroundColor
Browse files Browse the repository at this point in the history
feat: set backgroundColor on chart
  • Loading branch information
marshallpete authored Nov 22, 2023
2 parents bdfedc0 + 6ad58fd commit 87008a6
Show file tree
Hide file tree
Showing 11 changed files with 74 additions and 28 deletions.
2 changes: 2 additions & 0 deletions src/Chart.css
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,6 @@ this removes transitions in the vega tooltip
}
.rsc-container {
position: relative;
width: auto;
height: auto;
}
11 changes: 8 additions & 3 deletions src/Chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { FC, MutableRefObject, forwardRef, useEffect, useMemo, useRef, useState

import { EmptyState } from '@components/EmptyState';
import { LoadingState } from '@components/LoadingState';
import { DEFAULT_COLOR_SCHEME, DEFAULT_LINE_TYPES, MARK_ID, SERIES_ID } from '@constants';
import { DEFAULT_BACKGROUND_COLOR, DEFAULT_COLOR_SCHEME, DEFAULT_LINE_TYPES, MARK_ID, SERIES_ID } from '@constants';
import useChartImperativeHandle from '@hooks/useChartImperativeHandle';
import useChartWidth from '@hooks/useChartWidth';
import useElementSize from '@hooks/useElementSize';
Expand Down Expand Up @@ -74,7 +74,7 @@ interface PlaceholderContentProps {
export const Chart = forwardRef<ChartHandle, ChartProps>(
(
{
backgroundColor = 'transparent',
backgroundColor = DEFAULT_BACKGROUND_COLOR,
data,
colors = 'categorical12',
colorScheme = DEFAULT_COLOR_SCHEME,
Expand Down Expand Up @@ -116,6 +116,7 @@ export const Chart = forwardRef<ChartHandle, ChartProps>(

// THE MAGIC, builds our spec
const spec = useSpec({
backgroundColor,
children: sanitizedChildren,
colors,
data,
Expand Down Expand Up @@ -244,7 +245,11 @@ export const Chart = forwardRef<ChartHandle, ChartProps>(
}, [colorScheme, hiddenSeriesState, legendIsToggleable, selectedIdSignalName, selectedSeriesSignalName]);

return (
<Provider colorScheme={colorScheme} theme={isValidTheme(theme) ? theme : defaultTheme}>
<Provider
colorScheme={colorScheme}
theme={isValidTheme(theme) ? theme : defaultTheme}
UNSAFE_style={{ backgroundColor: 'transparent' }}
>
<div
ref={containerRef}
id={chartId.current}
Expand Down
4 changes: 3 additions & 1 deletion src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const DEFAULT_SECONDARY_COLOR = 'subSeries';
export const DEFAULT_SYMBOL_SIZE = 100;
export const DEFAULT_SYMBOL_STROKE_WIDTH = 2;
export const DEFAULT_COLOR_SCHEME = 'light';
export const DEFAULT_BACKGROUND_COLOR = 'transparent';
export const DEFAULT_AXIS_ANNOTATION_COLOR = 'gray-600';
export const DEFAULT_AXIS_ANNOTATION_OFFSET = 80;
export const TITLE_FONT_WEIGHT = 'bold';
Expand Down Expand Up @@ -53,4 +54,5 @@ export const TRELLIS_PADDING = 0.2;
export const HIGHLIGHT_CONTRAST_RATIO = 5;

// signal names
export const BACKGROUND_COLOR = 'backgroundColor';
// 'backgroundColor' is an undocumented protected signal name used by vega
export const BACKGROUND_COLOR = 'chartBackgroundColor';
11 changes: 10 additions & 1 deletion src/hooks/useSpec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { buildSpec } from '../specBuilder';
import { initializeSpec } from '../specBuilder/specUtils';

export default function useSpec({
backgroundColor,
children,
colors,
colorScheme,
Expand All @@ -35,7 +36,13 @@ export default function useSpec({
return useMemo(() => {
// They already supplied a spec, fill it in with defaults
if (UNSAFE_vegaSpec) {
const vegaSpecWithDefaults = initializeSpec(UNSAFE_vegaSpec, { data, description, title });
const vegaSpecWithDefaults = initializeSpec(UNSAFE_vegaSpec, {
backgroundColor,
colorScheme,
data,
description,
title,
});

// copy the spec so we don't mutate the original
return JSON.parse(JSON.stringify(vegaSpecWithDefaults));
Expand All @@ -46,6 +53,7 @@ export default function useSpec({
return JSON.parse(
JSON.stringify(
buildSpec({
backgroundColor,
children,
colors,
colorScheme,
Expand All @@ -61,6 +69,7 @@ export default function useSpec({
)
);
}, [
backgroundColor,
children,
colors,
colorScheme,
Expand Down
15 changes: 7 additions & 8 deletions src/specBuilder/chartSpecBuilder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { Bar } from '@components/Bar';
import { Legend } from '@components/Legend';
import {
BACKGROUND_COLOR,
DEFAULT_BACKGROUND_COLOR,
DEFAULT_COLOR,
DEFAULT_SECONDARY_COLOR,
FILTERED_TABLE,
Expand Down Expand Up @@ -478,18 +479,16 @@ describe('Chart spec builder', () => {
];

test('hiddenSeries is empty when no hidden series', () => {
expect(getDefaultSignals('categorical12', 'light', ['dashed'], [1])).toStrictEqual([
...defaultSignals,
{ name: 'hiddenSeries', value: [] },
]);
expect(
getDefaultSignals(DEFAULT_BACKGROUND_COLOR, 'categorical12', 'light', ['dashed'], [1])
).toStrictEqual([...defaultSignals, { name: 'hiddenSeries', value: [] }]);
});

test('hiddenSeries contains provided hidden series', () => {
const hiddenSeries = ['test'];
expect(getDefaultSignals('categorical12', 'light', ['dashed'], [1], hiddenSeries)).toStrictEqual([
...defaultSignals,
{ name: 'hiddenSeries', value: hiddenSeries },
]);
expect(
getDefaultSignals(DEFAULT_BACKGROUND_COLOR, 'categorical12', 'light', ['dashed'], [1], hiddenSeries)
).toStrictEqual([...defaultSignals, { name: 'hiddenSeries', value: hiddenSeries }]);
});
});
});
26 changes: 17 additions & 9 deletions src/specBuilder/chartSpecBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
*/
import {
BACKGROUND_COLOR,
DEFAULT_BACKGROUND_COLOR,
DEFAULT_COLOR_SCHEME,
DEFAULT_LINE_TYPES,
FILTERED_TABLE,
Expand Down Expand Up @@ -60,6 +61,7 @@ import {
import { addTitle } from './title/titleSpecBuilder';

export function buildSpec({
backgroundColor = DEFAULT_BACKGROUND_COLOR,
children,
colors = 'categorical12',
description,
Expand All @@ -72,8 +74,8 @@ export function buildSpec({
colorScheme = DEFAULT_COLOR_SCHEME,
title,
}: SanitizedSpecProps) {
let spec = initializeSpec(null, { title, description });
spec.signals = getDefaultSignals(colors, colorScheme, lineTypes, opacities, hiddenSeries);
let spec = initializeSpec(null, { backgroundColor, colorScheme, description, title });
spec.signals = getDefaultSignals(backgroundColor, colors, colorScheme, lineTypes, opacities, hiddenSeries);
spec.scales = getDefaultScales(colors, colorScheme, lineTypes, lineWidths, opacities, symbolShapes);

// need to build the spec in a specific order
Expand Down Expand Up @@ -161,18 +163,24 @@ const initializeComponentCounts = () => {
};

export const getDefaultSignals = (
backgroundColor: string,
colors: ChartColors,
colorScheme: ColorScheme,
lineTypes: LineTypes,
opacities: Opacities | undefined,
hiddenSeries?: string[]
): Signal[] => [
getGenericSignal(BACKGROUND_COLOR, getColorValue('gray-50', colorScheme)),
getGenericSignal('colors', getTwoDimensionalColorScheme(colors, colorScheme)),
getGenericSignal('lineTypes', getTwoDimensionalLineTypes(lineTypes)),
getGenericSignal('opacities', getTwoDimensionalOpacities(opacities)),
getGenericSignal('hiddenSeries', hiddenSeries ?? []),
];
): Signal[] => {
// if the background color is transparent, then we want to set the signal background color to gray-50
// if the signal background color were transparent then backgroundMarks and annotation fill would also be transparent
const signalBackgroundColor = backgroundColor === 'transparent' ? 'gray-50' : backgroundColor;
return [
getGenericSignal(BACKGROUND_COLOR, getColorValue(signalBackgroundColor, colorScheme)),
getGenericSignal('colors', getTwoDimensionalColorScheme(colors, colorScheme)),
getGenericSignal('lineTypes', getTwoDimensionalLineTypes(lineTypes)),
getGenericSignal('opacities', getTwoDimensionalOpacities(opacities)),
getGenericSignal('hiddenSeries', hiddenSeries ?? []),
];
};

export const getTwoDimensionalColorScheme = (colors: ChartColors, colorScheme: ColorScheme): string[][] => {
if (isColors(colors)) {
Expand Down
3 changes: 2 additions & 1 deletion src/specBuilder/specUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,13 +181,14 @@ export const baseData: Data[] = [
* @returns Spec with default values
*/
export const initializeSpec = (spec: Spec | null = {}, chartProps: Partial<SanitizedSpecProps> = {}): Spec => {
const { title, description, data } = chartProps;
const { backgroundColor, colorScheme = 'light', data, description, title } = chartProps;

const baseSpec: Spec = {
title: title || undefined,
description,
autosize: { type: 'fit', contains: 'padding', resize: true },
data: isVegaData(data) ? data : baseData,
background: backgroundColor ? getColorValue(backgroundColor, colorScheme) : undefined,
};

return { ...baseSpec, ...(spec || {}) };
Expand Down
9 changes: 8 additions & 1 deletion src/stories/Chart.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ const Basic = bindWithProps(ChartLineStory);
// Story specific props are passed here
Basic.args = { data, renderer: 'svg', height: 300 };

const BackgroundColor = bindWithProps(ChartLineStory);
BackgroundColor.args = {
backgroundColor: 'gray-50',
padding: 32,
data,
};

const Config = bindWithProps(ChartBarStory);
Config.args = {
config: {
Expand All @@ -59,4 +66,4 @@ Width.args = {
data,
};

export { Basic, Config, Width };
export { Basic, BackgroundColor, Config, Width };
15 changes: 14 additions & 1 deletion src/stories/Chart.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { Axis, Bar, Chart, ChartHandle, ChartTooltip, Line } from '@rsc';
import { findChart, getAllMarksByGroupName, render, screen } from '@test-utils';
import { getElement } from '@utils';

import { Basic, Config, Width } from './Chart.story';
import { BackgroundColor, Basic, Config, Width } from './Chart.story';
import {
CssColors,
SpectrumColorNames,
Expand Down Expand Up @@ -139,6 +139,19 @@ describe('Chart', () => {
expect(bars[2].getAttribute('fill')).toEqual('#0d66d0');
expect(bars[3].getAttribute('fill')).toEqual('hsl(32deg, 86%, 46%)');
});

test('background color gets set', async () => {
render(<BackgroundColor {...BackgroundColor.args} />);

const chart = await findChart();
expect(chart).toBeInTheDocument();

const svg = chart.querySelector('svg');
expect(svg).toHaveStyle('background-color: rgb(255, 255, 255);');

const container = document.querySelector('.rsc-container');
expect(container).toHaveStyle('background-color: rgb(255, 255, 255);');
});
});

describe('State stories', () => {
Expand Down
4 changes: 2 additions & 2 deletions src/themes/spectrumTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
import { DEFAULT_SYMBOL_SIZE, DEFAULT_SYMBOL_STROKE_WIDTH } from '@constants';
import { DEFAULT_BACKGROUND_COLOR, DEFAULT_SYMBOL_SIZE, DEFAULT_SYMBOL_STROKE_WIDTH } from '@constants';
import { ROUNDED_SQUARE_PATH } from 'svgPaths';
import { ColorScheme } from 'types';
import { BaseLegendLayout, Config, mergeConfig } from 'vega';
Expand Down Expand Up @@ -93,7 +93,7 @@ function getSpectrumVegaConfig(colorScheme: ColorScheme): Config {
ordinal: categorical16,
ramp: sequentialViridis16,
},
background: 'transparent',
background: DEFAULT_BACKGROUND_COLOR,
legend: {
columnPadding: 20,
labelColor: gray700,
Expand Down
2 changes: 1 addition & 1 deletion src/types/Chart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export type SimpleData = { [key: string]: unknown };
export type ChartData = SimpleData | Data;

export interface SpecProps {
backgroundColor?: string;
// children is optional because it is a pain to make this required with how children get defined in stories
// we have a check at the beginning of Chart to make sure this isn't undefined
// if it is undefined, we log an error and render a fragment
Expand Down Expand Up @@ -67,7 +68,6 @@ export type SymbolShapes = ChartSymbolShape[] | ChartSymbolShape[][];
export type ChartSymbolShape = 'rounded-square' | SymbolShape;

export interface ChartProps extends SpecProps {
backgroundColor?: string;
config?: Config;
data: ChartData[];
debug?: boolean;
Expand Down

0 comments on commit 87008a6

Please sign in to comment.