diff --git a/packages/polaris-viz-core/src/types.ts b/packages/polaris-viz-core/src/types.ts index 18ae7b8d3..8d931ad3b 100644 --- a/packages/polaris-viz-core/src/types.ts +++ b/packages/polaris-viz-core/src/types.ts @@ -27,6 +27,9 @@ interface StyleOverride { width?: number; strokeDasharray?: string; }; + tooltip?: { + shape?: Shape; + }; } export interface DataGroup { diff --git a/packages/polaris-viz/CHANGELOG.md b/packages/polaris-viz/CHANGELOG.md index 1f9f7748b..09a0f4d77 100644 --- a/packages/polaris-viz/CHANGELOG.md +++ b/packages/polaris-viz/CHANGELOG.md @@ -5,7 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). - +## Unreleased + +### Added + +- Added `tooltip.shape` override value to `DataSeries.styleOverride`. +- **Breaking change** Added custom legend to ``. + + +### Changed + +- **Breaking change** `` no longer renders all lines in the `DataSeries[]`. Any `DataSeries` with `metadata.relatedIndex` will only render the area in the chart. +- **Breaking change** `metadata.relatedIndex` should now refer to the single "median" index and not the next index to draw the area to. ## [11.1.0] - 2024-03-19 diff --git a/packages/polaris-viz/src/components/LineChart/Chart.tsx b/packages/polaris-viz/src/components/LineChart/Chart.tsx index 018fadb65..09dd01507 100644 --- a/packages/polaris-viz/src/components/LineChart/Chart.tsx +++ b/packages/polaris-viz/src/components/LineChart/Chart.tsx @@ -342,6 +342,10 @@ export function Chart({ })} {data.map((singleSeries, index) => { + if (singleSeries.metadata?.isVisuallyHidden === true) { + return null; + } + return ( {data.map((singleSeries, seriesIndex) => { + if (singleSeries?.metadata?.isVisuallyHidden === true) { + return null; + } + const index = singleSeries.metadata?.relatedIndex ?? seriesIndex; if (hiddenIndexes.includes(index)) { diff --git a/packages/polaris-viz/src/components/LineChartRelational/LineChartRelational.tsx b/packages/polaris-viz/src/components/LineChartRelational/LineChartRelational.tsx index de5026761..026764927 100644 --- a/packages/polaris-viz/src/components/LineChartRelational/LineChartRelational.tsx +++ b/packages/polaris-viz/src/components/LineChartRelational/LineChartRelational.tsx @@ -1,12 +1,17 @@ -import {DEFAULT_CHART_PROPS} from '@shopify/polaris-viz-core'; +import { + DEFAULT_CHART_PROPS, + DEFAULT_THEME_NAME, +} from '@shopify/polaris-viz-core'; import {Fragment} from 'react'; import type {LineChartProps} from '../LineChart'; import {LineChart} from '../LineChart'; -import {RelatedAreas, MissingDataArea} from './components'; +import {RelatedAreas, MissingDataArea, CustomLegend} from './components'; -export function LineChartRelational(props: LineChartProps) { +export function LineChartRelational( + props: Omit, +) { const { annotations = [], data, @@ -14,7 +19,6 @@ export function LineChartRelational(props: LineChartProps) { emptyStateText, id, isAnimated, - renderLegendContent, showLegend = true, skipLinkText, state, @@ -27,15 +31,37 @@ export function LineChartRelational(props: LineChartProps) { ...props, }; + const dataWithHiddenRelational = data.map((series) => { + return { + ...series, + metadata: { + ...series.metadata, + isVisuallyHidden: series.metadata?.relatedIndex != null, + }, + }; + }); + return ( { + return ( + + ); + }} showLegend={showLegend} skipLinkText={skipLinkText} slots={{ diff --git a/packages/polaris-viz/src/components/LineChartRelational/components/Area/Area.tsx b/packages/polaris-viz/src/components/LineChartRelational/components/Area/Area.tsx index 573c10d26..db47d76bb 100644 --- a/packages/polaris-viz/src/components/LineChartRelational/components/Area/Area.tsx +++ b/packages/polaris-viz/src/components/LineChartRelational/components/Area/Area.tsx @@ -57,7 +57,7 @@ export function Area({ style={{ ...getColorVisionStylesForActiveIndex({ activeIndex, - index: -1, + index, fadedOpacity: 0.2, }), }} diff --git a/packages/polaris-viz/src/components/LineChartRelational/components/CustomLegend/CustomLegend.scss b/packages/polaris-viz/src/components/LineChartRelational/components/CustomLegend/CustomLegend.scss new file mode 100644 index 000000000..7900c3649 --- /dev/null +++ b/packages/polaris-viz/src/components/LineChartRelational/components/CustomLegend/CustomLegend.scss @@ -0,0 +1,6 @@ +.Container { + display: flex; + gap: 10px; + flex-wrap: wrap; + list-style: none; +} diff --git a/packages/polaris-viz/src/components/LineChartRelational/components/CustomLegend/CustomLegend.tsx b/packages/polaris-viz/src/components/LineChartRelational/components/CustomLegend/CustomLegend.tsx new file mode 100644 index 000000000..c55b28c79 --- /dev/null +++ b/packages/polaris-viz/src/components/LineChartRelational/components/CustomLegend/CustomLegend.tsx @@ -0,0 +1,76 @@ +import type {DataSeries} from '@shopify/polaris-viz-core'; + +import type {ColorVisionInteractionMethods} from '../../../../types'; +import {LegendItem} from '../../../../components/Legend'; + +import styles from './CustomLegend.scss'; + +interface Props extends ColorVisionInteractionMethods { + data: DataSeries[]; + theme: string; +} + +export function CustomLegend({ + data, + getColorVisionEventAttrs, + getColorVisionStyles, + theme, +}: Props) { + const lineSeries = data.filter( + (series) => series?.metadata?.relatedIndex == null, + ); + + const percentileItems = data.filter( + (series) => series?.metadata?.relatedIndex != null, + ); + + const percentileIndex = lineSeries.length + 1; + + return ( +
    + {lineSeries.map(({color, name, isComparison, metadata}) => { + if (metadata?.isPredictive) { + return null; + } + + const index = data.findIndex((series) => series.name === name); + + return ( +
  • + +
  • + ); + })} +
  • + +
  • +
+ ); +} diff --git a/packages/polaris-viz/src/components/LineChartRelational/components/CustomLegend/index.ts b/packages/polaris-viz/src/components/LineChartRelational/components/CustomLegend/index.ts new file mode 100644 index 000000000..da14739fe --- /dev/null +++ b/packages/polaris-viz/src/components/LineChartRelational/components/CustomLegend/index.ts @@ -0,0 +1 @@ +export {CustomLegend} from './CustomLegend'; diff --git a/packages/polaris-viz/src/components/LineChartRelational/components/RelatedAreas/RelatedAreas.tsx b/packages/polaris-viz/src/components/LineChartRelational/components/RelatedAreas/RelatedAreas.tsx index 212b6ceb5..43a06d48c 100644 --- a/packages/polaris-viz/src/components/LineChartRelational/components/RelatedAreas/RelatedAreas.tsx +++ b/packages/polaris-viz/src/components/LineChartRelational/components/RelatedAreas/RelatedAreas.tsx @@ -21,6 +21,12 @@ export interface RelatedAreaProps extends LineChartSlotProps { export function RelatedAreas({yScale, xScale, data}: RelatedAreaProps) { const [activeIndex, setActiveIndex] = useState(-1); + const lineSeries = data.filter( + (series) => series?.metadata?.relatedIndex == null, + ); + + const percentileIndex = lineSeries.length + 1; + const {hiddenIndexes} = useExternalHideEvents(); const {shouldAnimate, id} = useChartContext(); @@ -84,7 +90,7 @@ export function RelatedAreas({yScale, xScale, data}: RelatedAreaProps) { fill={series.metadata?.areaColor} getAreaGenerator={getAreaGenerator} hiddenIndexes={hiddenIndexes} - index={index} + index={percentileIndex} key={index} series={series} shouldAnimate={shouldAnimate} diff --git a/packages/polaris-viz/src/components/LineChartRelational/components/index.ts b/packages/polaris-viz/src/components/LineChartRelational/components/index.ts index bacbed578..a13f72640 100644 --- a/packages/polaris-viz/src/components/LineChartRelational/components/index.ts +++ b/packages/polaris-viz/src/components/LineChartRelational/components/index.ts @@ -1,3 +1,4 @@ export {Area} from './Area'; export {MissingDataArea} from './MissingDataArea'; export {RelatedAreas} from './RelatedAreas'; +export {CustomLegend} from './CustomLegend'; diff --git a/packages/polaris-viz/src/components/LineChartRelational/stories/Default.stories.tsx b/packages/polaris-viz/src/components/LineChartRelational/stories/Default.stories.tsx index 07d7640c2..6b143cdcd 100644 --- a/packages/polaris-viz/src/components/LineChartRelational/stories/Default.stories.tsx +++ b/packages/polaris-viz/src/components/LineChartRelational/stories/Default.stories.tsx @@ -11,4 +11,6 @@ Default.args = { ...DEFAULT_PROPS, data: DEFAULT_DATA, isAnimated: false, + showLegend: true, + theme: 'Uplift', }; diff --git a/packages/polaris-viz/src/components/LineChartRelational/stories/chromatic/data/missing-end-data.js b/packages/polaris-viz/src/components/LineChartRelational/stories/chromatic/data/missing-end-data.js index bd2ac3c33..942a0cff2 100644 --- a/packages/polaris-viz/src/components/LineChartRelational/stories/chromatic/data/missing-end-data.js +++ b/packages/polaris-viz/src/components/LineChartRelational/stories/chromatic/data/missing-end-data.js @@ -40,16 +40,10 @@ export const MISSING_END_DATA = [ {value: null, key: '2020-03-13T12:00:00'}, {value: null, key: '2020-03-14T12:00:00'}, ], - color: 'rgba(103, 197, 228, 1)', metadata: { relatedIndex: 2, areaColor: 'rgba(103, 197, 228, 0.1)', }, - styleOverride: { - line: { - hasArea: false, - }, - }, }, { name: 'Median', @@ -70,10 +64,6 @@ export const MISSING_END_DATA = [ {value: null, key: '2020-03-14T12:00:00'}, ], color: 'rgba(40, 106, 123, 1)', - metadata: { - relatedIndex: 3, - areaColor: 'rgba(47, 175, 218, 0.2)', - }, styleOverride: { line: { hasArea: false, @@ -99,11 +89,9 @@ export const MISSING_END_DATA = [ {value: null, key: '2020-03-13T12:00:00'}, {value: null, key: '2020-03-14T12:00:00'}, ], - color: 'rgba(103, 197, 228, 1)', - styleOverride: { - line: { - hasArea: false, - }, + metadata: { + relatedIndex: 2, + areaColor: 'rgba(103, 197, 228, 0.1)', }, }, ]; diff --git a/packages/polaris-viz/src/components/LineChartRelational/stories/chromatic/data/missing-middle-data.js b/packages/polaris-viz/src/components/LineChartRelational/stories/chromatic/data/missing-middle-data.js index 20c598be6..f59cd7440 100644 --- a/packages/polaris-viz/src/components/LineChartRelational/stories/chromatic/data/missing-middle-data.js +++ b/packages/polaris-viz/src/components/LineChartRelational/stories/chromatic/data/missing-middle-data.js @@ -40,16 +40,10 @@ export const MISSING_MIDDLE_DATA = [ {value: 773, key: '2020-03-13T12:00:00'}, {value: 171, key: '2020-03-14T12:00:00'}, ], - color: 'rgba(103, 197, 228, 1)', metadata: { relatedIndex: 2, areaColor: 'rgba(103, 197, 228, 0.1)', }, - styleOverride: { - line: { - hasArea: false, - }, - }, }, { name: 'Median', @@ -70,10 +64,6 @@ export const MISSING_MIDDLE_DATA = [ {value: 21, key: '2020-03-14T12:00:00'}, ], color: 'rgba(40, 106, 123, 1)', - metadata: { - relatedIndex: 3, - areaColor: 'rgba(47, 175, 218, 0.2)', - }, styleOverride: { line: { hasArea: false, @@ -99,11 +89,9 @@ export const MISSING_MIDDLE_DATA = [ {value: 473, key: '2020-03-13T12:00:00'}, {value: 0, key: '2020-03-14T12:00:00'}, ], - color: 'rgba(103, 197, 228, 1)', - styleOverride: { - line: { - hasArea: false, - }, + metadata: { + relatedIndex: 2, + areaColor: 'rgba(103, 197, 228, 0.1)', }, }, ]; diff --git a/packages/polaris-viz/src/components/LineChartRelational/stories/chromatic/data/missing-random-data.js b/packages/polaris-viz/src/components/LineChartRelational/stories/chromatic/data/missing-random-data.js index dea4ebcd6..5356e0786 100644 --- a/packages/polaris-viz/src/components/LineChartRelational/stories/chromatic/data/missing-random-data.js +++ b/packages/polaris-viz/src/components/LineChartRelational/stories/chromatic/data/missing-random-data.js @@ -40,16 +40,10 @@ export const MISSING_RANDOM_DATA = [ {value: 773, key: '2020-03-13T12:00:00'}, {value: 171, key: '2020-03-14T12:00:00'}, ], - color: 'rgba(103, 197, 228, 1)', metadata: { relatedIndex: 2, areaColor: 'rgba(103, 197, 228, 0.1)', }, - styleOverride: { - line: { - hasArea: false, - }, - }, }, { name: 'Median', @@ -70,10 +64,6 @@ export const MISSING_RANDOM_DATA = [ {value: 21, key: '2020-03-14T12:00:00'}, ], color: 'rgba(40, 106, 123, 1)', - metadata: { - relatedIndex: 3, - areaColor: 'rgba(47, 175, 218, 0.2)', - }, styleOverride: { line: { hasArea: false, @@ -99,11 +89,9 @@ export const MISSING_RANDOM_DATA = [ {value: 473, key: '2020-03-13T12:00:00'}, {value: 0, key: '2020-03-14T12:00:00'}, ], - color: 'rgba(103, 197, 228, 1)', - styleOverride: { - line: { - hasArea: false, - }, + metadata: { + relatedIndex: 2, + areaColor: 'rgba(103, 197, 228, 0.1)', }, }, ]; diff --git a/packages/polaris-viz/src/components/LineChartRelational/stories/chromatic/data/missing-start-data.js b/packages/polaris-viz/src/components/LineChartRelational/stories/chromatic/data/missing-start-data.js index 11d150b67..533edbc35 100644 --- a/packages/polaris-viz/src/components/LineChartRelational/stories/chromatic/data/missing-start-data.js +++ b/packages/polaris-viz/src/components/LineChartRelational/stories/chromatic/data/missing-start-data.js @@ -40,16 +40,10 @@ export const MISSING_START_DATA = [ {value: 773, key: '2020-03-13T12:00:00'}, {value: 171, key: '2020-03-14T12:00:00'}, ], - color: 'rgba(103, 197, 228, 1)', metadata: { relatedIndex: 2, areaColor: 'rgba(103, 197, 228, 0.1)', }, - styleOverride: { - line: { - hasArea: false, - }, - }, }, { name: 'Median', @@ -70,10 +64,6 @@ export const MISSING_START_DATA = [ {value: 21, key: '2020-03-14T12:00:00'}, ], color: 'rgba(40, 106, 123, 1)', - metadata: { - relatedIndex: 3, - areaColor: 'rgba(47, 175, 218, 0.2)', - }, styleOverride: { line: { hasArea: false, @@ -99,11 +89,9 @@ export const MISSING_START_DATA = [ {value: 473, key: '2020-03-13T12:00:00'}, {value: 0, key: '2020-03-14T12:00:00'}, ], - color: 'rgba(103, 197, 228, 1)', - styleOverride: { - line: { - hasArea: false, - }, + metadata: { + relatedIndex: 2, + areaColor: 'rgba(103, 197, 228, 0.1)', }, }, ]; diff --git a/packages/polaris-viz/src/components/LineChartRelational/stories/data.tsx b/packages/polaris-viz/src/components/LineChartRelational/stories/data.tsx index 67cfb3239..7cdc7150b 100644 --- a/packages/polaris-viz/src/components/LineChartRelational/stories/data.tsx +++ b/packages/polaris-viz/src/components/LineChartRelational/stories/data.tsx @@ -1,6 +1,7 @@ import type {Story} from '@storybook/react'; import type {RenderTooltipContentData} from 'types'; import type {DataSeries} from '@shopify/polaris-viz-core'; +import {UPLIFT_THEME} from '@shopify/polaris-viz-core'; import type {LineChartProps} from 'components/LineChart/LineChart'; import {LineChartRelational} from '../LineChartRelational'; @@ -80,10 +81,7 @@ export const DEFAULT_DATA: DataSeries[] = [ {value: 849, key: '2020-03-13T12:00:00'}, {value: 129, key: '2020-03-14T12:00:00'}, ], - color: [ - {offset: 0, color: 'rgba(149, 101, 255, 1)'}, - {offset: 100, color: 'rgba(75, 146, 229, 1)'}, - ], + color: UPLIFT_THEME.seriesColors.upToEight[0], }, { name: '75th Percentile', @@ -103,14 +101,15 @@ export const DEFAULT_DATA: DataSeries[] = [ {value: 773, key: '2020-03-13T12:00:00'}, {value: 171, key: '2020-03-14T12:00:00'}, ], - color: 'rgba(103, 197, 228, 1)', + color: 'rgba(218, 182, 242, 1)', metadata: { relatedIndex: 2, - areaColor: 'rgba(103, 197, 228, 0.1)', + areaColor: 'rgba(218, 182, 242, 0.2)', + legendLabel: '75th - 25th percentile', }, styleOverride: { - line: { - hasArea: false, + tooltip: { + shape: 'Bar', }, }, }, @@ -132,11 +131,7 @@ export const DEFAULT_DATA: DataSeries[] = [ {value: 623, key: '2020-03-13T12:00:00'}, {value: 21, key: '2020-03-14T12:00:00'}, ], - color: 'rgba(40, 106, 123, 1)', - metadata: { - relatedIndex: 3, - areaColor: 'rgba(47, 175, 218, 0.2)', - }, + color: UPLIFT_THEME.seriesColors.upToEight[5], styleOverride: { line: { hasArea: false, @@ -162,10 +157,15 @@ export const DEFAULT_DATA: DataSeries[] = [ {value: 473, key: '2020-03-13T12:00:00'}, {value: 0, key: '2020-03-14T12:00:00'}, ], - color: 'rgba(103, 197, 228, 1)', + color: 'rgba(218, 182, 242, 1)', + metadata: { + relatedIndex: 2, + areaColor: 'rgba(218, 182, 242, 0.2)', + legendLabel: '75th - 25th percentile', + }, styleOverride: { - line: { - hasArea: false, + tooltip: { + shape: 'Bar', }, }, }, diff --git a/packages/polaris-viz/src/utilities/renderLinearTooltipContent.tsx b/packages/polaris-viz/src/utilities/renderLinearTooltipContent.tsx index ae329329a..ab34cb37a 100644 --- a/packages/polaris-viz/src/utilities/renderLinearTooltipContent.tsx +++ b/packages/polaris-viz/src/utilities/renderLinearTooltipContent.tsx @@ -51,7 +51,7 @@ export function renderLinearTooltipContent( }; function renderSeriesIcon(color, styleOverride): ReactNode { - if (styleOverride == null) { + if (styleOverride?.line == null) { return null; } @@ -110,7 +110,7 @@ export function renderLinearTooltipContent( renderSeriesIcon={() => renderSeriesIcon(color, styleOverride) } - shape="Line" + shape={styleOverride?.tooltip?.shape ?? 'Line'} value={formatters.valueFormatter(item.value ?? 0)} /> );