diff --git a/packages/polaris-viz/src/components/Grid/Grid.tsx b/packages/polaris-viz/src/components/Grid/Grid.tsx
index ab718a1cc..c3da76cde 100644
--- a/packages/polaris-viz/src/components/Grid/Grid.tsx
+++ b/packages/polaris-viz/src/components/Grid/Grid.tsx
@@ -27,6 +27,8 @@ import {
SMALL_CONTAINER_WIDTH,
SMALL_CONTAINER_HEIGHT,
DEFAULT_BOUNDS,
+ DISABLED_GROUP_COLOR,
+ DISABLED_TEXT_COLOR,
} from './utilities/constants';
import type {
CellGroup,
@@ -143,7 +145,7 @@ export function Grid(props: GridProps) {
const handleGroupHover = useCallback(
(group: CellGroup | null) => {
- if (!isSmallContainer) {
+ if (!isSmallContainer && group?.value !== null) {
if (group) {
const activeGroups = getActiveGroups(group);
setHoveredGroups(activeGroups);
@@ -211,6 +213,12 @@ export function Grid(props: GridProps) {
]);
const getColors = (group: CellGroup | null) => {
+ if (group?.value === null) {
+ return {
+ bgColor: DISABLED_GROUP_COLOR,
+ textColor: DISABLED_TEXT_COLOR,
+ };
+ }
if (group) {
return {
bgColor: group.bgColor || DEFAULT_GROUP_COLOR,
diff --git a/packages/polaris-viz/src/components/Grid/components/Background.tsx b/packages/polaris-viz/src/components/Grid/components/Background.tsx
index c727f7ac2..9b8907d74 100644
--- a/packages/polaris-viz/src/components/Grid/components/Background.tsx
+++ b/packages/polaris-viz/src/components/Grid/components/Background.tsx
@@ -7,6 +7,7 @@ interface BackgroundProps {
height: number;
fill: string;
opacity: number;
+ isDisabled?: boolean;
}
export const Background = ({
@@ -16,18 +17,37 @@ export const Background = ({
height,
fill,
opacity,
+ isDisabled,
}: BackgroundProps) => {
+ const adjustedWidth = Math.max(0, width - BACKGROUND_GAP);
+ const adjustedHeight = Math.max(0, height - BACKGROUND_GAP);
+
return (
-
+
+
+ {isDisabled && (
+
+ )}
+
);
};
diff --git a/packages/polaris-viz/src/components/Grid/components/GroupCell.tsx b/packages/polaris-viz/src/components/Grid/components/GroupCell.tsx
index cc936efe7..167233fdd 100644
--- a/packages/polaris-viz/src/components/Grid/components/GroupCell.tsx
+++ b/packages/polaris-viz/src/components/Grid/components/GroupCell.tsx
@@ -139,6 +139,7 @@ export const GroupCell: React.FC = ({
height={groupHeight}
fill={getColors(group).bgColor}
opacity={opacity}
+ isDisabled={group.value === null}
/>
{textColor: string};
opacity: number;
mainFontSize: number;
- groupValue: string;
+ groupValue: string | null;
showNameAndSecondaryValue: boolean;
secondaryFontSize: number;
groupSecondaryValue: string;
@@ -58,6 +58,26 @@ export const GroupInfo: React.FC = ({
[characterWidths, dimensions],
);
+ const truncatedGroupName = showNameAndSecondaryValue
+ ? getTruncatedText(group.name, groupWidth * GROUP_NAME_WIDTH_MULTIPLIER)
+ : '';
+
+ if (groupValue === null) {
+ return (
+
+ {truncatedGroupName}
+
+ );
+ }
+
const valueAndSecondaryValue = showNameAndSecondaryValue
? `${groupValue}${VALUES_DIVIDER}${groupSecondaryValue}`
: groupValue;
@@ -70,10 +90,6 @@ export const GroupInfo: React.FC = ({
const truncatedSecondaryValue =
truncatedValueAndSecondaryValue.split(VALUES_DIVIDER)[1];
- const truncatedGroupName = showNameAndSecondaryValue
- ? getTruncatedText(group.name, groupWidth * GROUP_NAME_WIDTH_MULTIPLIER)
- : '';
-
const textYOffset = showNameAndSecondaryValue
? TEXT_Y_OFFSET_WITH_SECONDARY
: 0;
diff --git a/packages/polaris-viz/src/components/Grid/stories/data.tsx b/packages/polaris-viz/src/components/Grid/stories/data.tsx
index 319b4dc60..9c7eddf61 100644
--- a/packages/polaris-viz/src/components/Grid/stories/data.tsx
+++ b/packages/polaris-viz/src/components/Grid/stories/data.tsx
@@ -24,7 +24,7 @@ export const CELL_GROUPS: CellGroup[] = [
start: {row: 0, col: 0},
end: {row: 0, col: 1},
secondaryValue: getRandomPercentage(),
- value: getRandomValue(),
+ value: '0',
bgColor: '#B1C3F7',
color: '#000000',
name: 'Previously loyal',
@@ -169,6 +169,157 @@ export const CELL_GROUPS: CellGroup[] = [
},
];
+export const MISSING_CELL_GROUPS: CellGroup[] = [
+ {
+ id: 'previously_loyal',
+ start: {row: 0, col: 0},
+ end: {row: 0, col: 1},
+ secondaryValue: getRandomPercentage(),
+ value: null,
+ bgColor: '#B1C3F7',
+ color: '#000000',
+ name: 'Previously loyal',
+ connectedGroups: ['loyal'],
+ description:
+ 'Customers without recent purchases, but with a very strong history of orders and spend.',
+ goal: 'Goal: move customers to Loyal',
+ metricInformation: '1,424 (10.9% of customer base)',
+ },
+ {
+ id: 'at_risk',
+ start: {row: 1, col: 0},
+ end: {row: 2, col: 1},
+ secondaryValue: getRandomPercentage(),
+ value: getRandomValue(),
+ bgColor: '#CBD7F9',
+ color: '#000000',
+ name: 'At risk',
+ metricInformation: '1,424 (10.9% of customer base)',
+ connectedGroups: ['needs_attention', 'loyal'],
+ description:
+ 'Customers without recent purchases, but with a strong history of orders and spend.',
+ goal: 'Goal: move customers to Loyal or Needs Attention',
+ },
+ {
+ id: 'dormant',
+ start: {row: 3, col: 0},
+ end: {row: 4, col: 1},
+ secondaryValue: getRandomPercentage(),
+ value: getRandomValue(),
+ bgColor: '#E5EBFC',
+ color: '#000000',
+ name: 'Dormant',
+ connectedGroups: ['almost_lost'],
+ description:
+ 'Customers without recent orders, with infrequent orders, and with low spend.',
+ goal: 'Goal: move customers to Almost lost',
+ metricInformation: '1,424 (10.9% of customer base)',
+ },
+ {
+ id: 'loyal',
+ start: {row: 0, col: 2},
+ end: {row: 1, col: 3},
+ secondaryValue: getRandomPercentage(),
+ value: getRandomValue(),
+ bgColor: '#0B2062',
+ color: '#FFFFFF',
+ name: 'Loyal',
+ connectedGroups: ['champions'],
+ description:
+ 'Customers without recent purchases, but with a very strong history of orders and spend.',
+ goal: 'Goal: move customers to Loyal',
+ metricInformation: '1,424 (10.9% of customer base)',
+ },
+ {
+ id: 'needs_attention',
+ start: {row: 2, col: 2},
+ end: {row: 2, col: 2},
+ secondaryValue: getRandomPercentage(),
+ value: getRandomValue(),
+ bgColor: '#3E69EA',
+ color: '#FFFFFF',
+ name: 'Needs attention',
+ connectedGroups: ['loyal', 'active'],
+ description:
+ 'Customers who buy less recently, order sometimes and spend moderately with your store.',
+ goal: 'Goal: move customers to Loyal or Potential',
+ metricInformation: '1,424 (10.9% of customer base)',
+ },
+ {
+ id: 'almost_lost',
+ start: {row: 3, col: 2},
+ end: {row: 4, col: 2},
+ secondaryValue: getRandomPercentage(),
+ value: getRandomValue(),
+ bgColor: '#7594F0',
+ color: '#000000',
+ name: 'Almost lost',
+ connectedGroups: ['active', 'promising'],
+ description:
+ 'Customers without recent purchases, fewer orders, and with lower spend.',
+ goal: 'Goal: move customers to Active or Promising',
+ metricInformation: '1,424 (10.9% of customer base)',
+ },
+ {
+ id: 'promising',
+ start: {row: 4, col: 3},
+ end: {row: 4, col: 3},
+ secondaryValue: getRandomPercentage(),
+ value: getRandomValue(),
+ bgColor: '#194BE3',
+ color: '#FFFFFF',
+ name: 'Promising',
+ connectedGroups: ['active'],
+ description: 'Customers with recent purchases, few orders, and low spend.',
+ goal: 'Goal: move customers to Active.',
+ metricInformation: '1,424 (10.9% of customer base)',
+ },
+ {
+ id: 'active',
+ start: {row: 2, col: 3},
+ end: {row: 3, col: 4},
+ secondaryValue: getRandomPercentage(),
+ value: null,
+ bgColor: '#0D297C',
+ color: '#FFFFFF',
+ name: 'Active',
+ connectedGroups: ['loyal', 'champions'],
+ description:
+ 'Customers with recent purchases, some orders, and moderate spend.',
+ goal: 'Goal: move customers to Champions or Loyal',
+ metricInformation: '1,424 (10.9% of customer base)',
+ },
+ {
+ id: 'new',
+ start: {row: 4, col: 4},
+ end: {row: 4, col: 4},
+ secondaryValue: getRandomPercentage(),
+ value: getRandomValue(),
+ bgColor: '#133AAF',
+ color: '#FFFFFF',
+ name: 'New',
+ connectedGroups: ['active'],
+ description:
+ 'Clients ayant effectué des achats très récemment, ayant passé peu de commandes et ayant dépensé peu dargent.',
+ goal: 'Goal: move customers to Active',
+ metricInformation: '1,424 (10.9% of customer base)',
+ },
+ {
+ id: 'champions',
+ start: {row: 0, col: 4},
+ end: {row: 1, col: 4},
+ secondaryValue: getRandomPercentage(),
+ value: getRandomValue(),
+ bgColor: '#081848',
+ color: '#FFFFFF',
+ name: 'Champions',
+ description:
+ 'Customers with very recent purchases, many orders, and the most spend.',
+ goal: null,
+ metricInformation: '1,424 (10.9% of customer base)',
+ },
+];
+
export const RANDOM_CELL_GROUPS: CellGroup[] = [
{
id: 'revenue',
diff --git a/packages/polaris-viz/src/components/Grid/stories/playground/FilteredGroups.stories.tsx b/packages/polaris-viz/src/components/Grid/stories/playground/FilteredGroups.stories.tsx
new file mode 100644
index 000000000..f535627b9
--- /dev/null
+++ b/packages/polaris-viz/src/components/Grid/stories/playground/FilteredGroups.stories.tsx
@@ -0,0 +1,48 @@
+import type {Story} from '@storybook/react';
+
+import {Grid} from '../../Grid';
+import type {GridProps} from '../../Grid';
+import {MISSING_CELL_GROUPS} from '../data';
+import {META} from '../meta';
+
+export default {
+ ...META,
+ title: `${META.title}/Playground`,
+ decorators: [],
+};
+
+function GridCard(args: GridProps) {
+ return (
+
+
+
+ );
+}
+
+const Template: Story = (args: GridProps) => {
+ return (
+
+
+
+ );
+};
+
+export const FilteredGroups = Template.bind({});
+
+FilteredGroups.args = {
+ cellGroups: MISSING_CELL_GROUPS,
+ xAxisOptions: {
+ label: 'Recency',
+ },
+ yAxisOptions: {
+ label: 'Frequency',
+ },
+};
diff --git a/packages/polaris-viz/src/components/Grid/types.ts b/packages/polaris-viz/src/components/Grid/types.ts
index 3713f8d6f..66cbb602c 100644
--- a/packages/polaris-viz/src/components/Grid/types.ts
+++ b/packages/polaris-viz/src/components/Grid/types.ts
@@ -16,7 +16,7 @@ export interface CellGroup {
goal: string | null;
connectedGroups?: string[];
secondaryValue: string;
- value: string;
+ value: string | null;
metricInformation?: string;
}
diff --git a/packages/polaris-viz/src/components/Grid/utilities/constants.ts b/packages/polaris-viz/src/components/Grid/utilities/constants.ts
index c4ce984f9..9e19831d8 100644
--- a/packages/polaris-viz/src/components/Grid/utilities/constants.ts
+++ b/packages/polaris-viz/src/components/Grid/utilities/constants.ts
@@ -9,6 +9,8 @@ export const X_AXIS_LABEL_OFFSET = 20;
export const DEFAULT_GROUP_COLOR = '#B1C3F7';
export const DEFAULT_TEXT_COLOR = '#FFFFFF';
+export const DISABLED_GROUP_COLOR = 'rgba(0, 0, 0, 0.05)';
+export const DISABLED_TEXT_COLOR = '#B5B5B5';
export const SVG_OFFSET = 10;
export const SMALL_CONTAINER_WIDTH = 400;