Skip to content

Commit

Permalink
Render custom Legend
Browse files Browse the repository at this point in the history
  • Loading branch information
envex committed Jan 5, 2024
1 parent 8659ae6 commit 1fcf9bd
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
getColorVisionEventAttrs,
getColorVisionStylesForActiveIndex,
} from '@shopify/polaris-viz-core';
import type {ReactNode} from 'react';

import {
LEGEND_ITEM_LEFT_PADDING,
Expand All @@ -19,6 +20,7 @@ export interface LegendItemProps extends LegendData {
index: number;
activeIndex?: number;
colorVisionType?: string;
renderSeriesIcon?: () => ReactNode;
theme?: string;
}

Expand All @@ -29,6 +31,7 @@ export function LegendItem({
index,
isComparison,
name,
renderSeriesIcon,
shape,
theme,
value,
Expand Down Expand Up @@ -58,12 +61,16 @@ export function LegendItem({
}}
className={style.Legend}
>
<span
style={{height: PREVIEW_ICON_SIZE, width: PREVIEW_ICON_SIZE}}
className={style.IconContainer}
>
<SeriesIcon shape={shape} color={color} isComparison={isComparison} />
</span>
{renderSeriesIcon == null ? (
<span
style={{height: PREVIEW_ICON_SIZE, width: PREVIEW_ICON_SIZE}}
className={style.IconContainer}
>
<SeriesIcon shape={shape} color={color} isComparison={isComparison} />
</span>
) : (
renderSeriesIcon()
)}
<span className={style.TextContainer}>
<span style={{color: selectedTheme.legend.labelColor}}>{name}</span>
{value == null ? null : (
Expand Down
1 change: 1 addition & 0 deletions packages/polaris-viz/src/components/Legend/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export {Legend} from './Legend';
export {LegendItem} from './components';
export type {LegendProps} from './Legend';
export {estimateLegendItemWidth} from './utilities/estimateLegendItemWidth';
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import {
DEFAULT_CHART_PROPS,
DEFAULT_THEME_NAME,
useTheme,
useThemeSeriesColors,
} from '@shopify/polaris-viz-core';

import {LineChart} from '../LineChart';

import type {LineChartPredictiveProps} from './types';
import {PredictiveLineSeries} from './components';
import {CustomLegend, PredictiveLineSeries} from './components';

export function LineChartPredictive(props: LineChartPredictiveProps) {
const {
Expand All @@ -17,7 +18,6 @@ export function LineChartPredictive(props: LineChartPredictiveProps) {
emptyStateText,
id,
isAnimated,
renderLegendContent,
showLegend = true,
skipLinkText,
state,
Expand All @@ -41,6 +41,12 @@ export function LineChartPredictive(props: LineChartPredictiveProps) {
}
}

const predictiveSeriesNames = predictiveData
.map(({metadata}) => {
return data[metadata?.relatedIndex ?? -1].name;
})
.filter((value) => value != null) as string[];

const selectedTheme = useTheme(theme);
const seriesColors = useThemeSeriesColors(nonPredictiveData, selectedTheme);

Expand All @@ -52,7 +58,6 @@ export function LineChartPredictive(props: LineChartPredictiveProps) {
errorText={errorText}
id={id}
isAnimated={isAnimated}
renderLegendContent={renderLegendContent}
showLegend={showLegend}
skipLinkText={skipLinkText}
slots={{
Expand All @@ -75,6 +80,21 @@ export function LineChartPredictive(props: LineChartPredictiveProps) {
tooltipOptions={tooltipOptions}
xAxisOptions={xAxisOptions}
yAxisOptions={yAxisOptions}
renderLegendContent={({
getColorVisionStyles,
getColorVisionEventAttrs,
}) => {
return (
<CustomLegend
getColorVisionStyles={getColorVisionStyles}
getColorVisionEventAttrs={getColorVisionEventAttrs}
predictiveSeriesNames={predictiveSeriesNames}
data={nonPredictiveData}
seriesColors={seriesColors}
theme={theme ?? DEFAULT_THEME_NAME}
/>
);
}}
/>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.Container {
display: flex;
gap: 10px;
flex-wrap: wrap;
list-style: none;
}

.IconContainer {
display: flex;
align-items: center;
justify-items: center;
height: 12px;
width: 20px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import {
LinearGradientWithStops,
changeGradientOpacity,
isGradientType,
uniqueId,
} from '@shopify/polaris-viz-core';
import type {Color} from '@shopify/polaris-viz-core';
import {useMemo} from 'react';

import type {LineChartPredictiveDataSeries} from '../../../../components/LineChartPredictive/types';
import type {ColorVisionInteractionMethods} from '../../../../types';
import {getLineChartDataWithDefaults} from '../../../../utilities/getLineChartDataWithDefaults';
import {LegendItem} from '../../../../components/Legend';

import styles from './CustomLegend.scss';

interface Props extends ColorVisionInteractionMethods {
data: LineChartPredictiveDataSeries[];
predictiveSeriesNames: string[];
getColorVisionEventAttrs: any;
getColorVisionStyles: any;
seriesColors: Color[];
theme: string;
}

export function CustomLegend({
data,
predictiveSeriesNames,
getColorVisionEventAttrs,
getColorVisionStyles,
seriesColors,
theme,
}: Props) {
const id = useMemo(() => uniqueId('CustomLegen'), []);

const dataWithDefaults = getLineChartDataWithDefaults(data, seriesColors);

return (
<ul className={styles.Container}>
{dataWithDefaults.map(({color, name, isComparison}, index) => {
const gradientId = `${id}-${index}`;

function renderSeriesIcon() {
return <SeriesIcon color={color} gradientId={gradientId} />;
}

return (
<li
key={index}
style={{
...getColorVisionStyles(index),
}}
{...getColorVisionEventAttrs(index)}
>
<LegendItem
color={color!}
index={index}
renderSeriesIcon={
predictiveSeriesNames.includes(name ?? '')
? renderSeriesIcon
: undefined
}
isComparison={isComparison}
name={name!}
shape="Line"
theme={theme}
/>
</li>
);
})}
</ul>
);
}

function SeriesIcon({color, gradientId}: {color: Color; gradientId: string}) {
return (
<div className={styles.IconContainer}>
<svg
width="19"
height="4"
viewBox="0 0 19 4"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M8 2C8 0.89543 8.89543 0 10 0C11.1046 0 12 0.89543 12 2C12 3.10457 11.1046 4 10 4C8.89543 4 8 3.10457 8 2ZM7.17071 1C7.06015 1.31278 7 1.64936 7 2C7 2.35064 7.06015 2.68722 7.17071 3H1C0.447715 3 0 2.55228 0 2C0 1.44772 0.447715 1 1 1H7.17071ZM13 2C13 2.55228 13.4477 3 14 3H14.4C14.9523 3 15.4 2.55228 15.4 2C15.4 1.44772 14.9523 1 14.4 1H14C13.4477 1 13 1.44772 13 2ZM17.6 1C17.0477 1 16.6 1.44772 16.6 2C16.6 2.55228 17.0477 3 17.6 3H18C18.5523 3 19 2.55228 19 2C19 1.44772 18.5523 1 18 1H17.6Z"
fill={`url(#${gradientId})`}
/>
{isGradientType(color) ? (
<defs>
<LinearGradientWithStops
id={gradientId}
gradient={changeGradientOpacity(color)}
gradientUnits="userSpaceOnUse"
y1="100%"
y2="0%"
/>
</defs>
) : null}
</svg>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {CustomLegend} from './CustomLegend';
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export function PredictiveLineSeries({
color={pointColor}
cx={xScale(predictiveStartIndex)}
cy={yScale(series.data[predictiveStartIndex]?.value ?? -1)}
active
active={activeLineIndex === -1 || activeLineIndex === index}
index={index}
isAnimated={false}
ariaHidden
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export {PredictiveLineSeries} from './PredictiveLineSeries';
export {CustomLegend} from './CustomLegend';
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface LineChartPredictiveDataSeries extends DataSeries {
metadata?: MetaData;
}

export interface LineChartPredictiveProps extends Omit<LineChartProps, 'data'> {
export interface LineChartPredictiveProps
extends Omit<LineChartProps, 'data' | 'renderLegendContent'> {
data: LineChartPredictiveDataSeries[];
}

0 comments on commit 1fcf9bd

Please sign in to comment.