Center metric layer on pie chart + cleanup (#16105)
https://github.com/user-attachments/assets/bb48bebe-d0be-4006-8f63-e686c70c0011 --------- Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
This commit is contained in:
-9
@@ -53,7 +53,6 @@ export const WithCustomColors: Story = {
|
||||
min: 0,
|
||||
max: 100,
|
||||
color: 'purple',
|
||||
to: '/metrics/progress',
|
||||
label: 'Progress',
|
||||
},
|
||||
displayType: 'number',
|
||||
@@ -83,7 +82,6 @@ export const Default: Story = {
|
||||
value: 0.5,
|
||||
min: 0,
|
||||
max: 1,
|
||||
to: '/metrics/conversion',
|
||||
label: 'Conversion rate',
|
||||
},
|
||||
displayType: 'percentage',
|
||||
@@ -120,7 +118,6 @@ export const Catalog: Story = {
|
||||
min: 0,
|
||||
max: 1,
|
||||
label: 'Percentage',
|
||||
to: '/metrics/catalog',
|
||||
},
|
||||
displayType: 'percentage' as const,
|
||||
id: `gauge-chart-catalog-${value}`,
|
||||
@@ -157,7 +154,6 @@ export const WithoutValue: Story = {
|
||||
value: 65,
|
||||
min: 0,
|
||||
max: 100,
|
||||
to: '/metrics/conversion-without-value',
|
||||
label: 'Conversion rate',
|
||||
},
|
||||
displayType: 'percentage',
|
||||
@@ -186,7 +182,6 @@ export const Revenue: Story = {
|
||||
value: 750,
|
||||
min: 0,
|
||||
max: 1000,
|
||||
to: '/financials/revenue',
|
||||
label: 'Revenue',
|
||||
},
|
||||
displayType: 'shortNumber',
|
||||
@@ -215,7 +210,6 @@ export const Temperature: Story = {
|
||||
value: 22,
|
||||
min: -10,
|
||||
max: 40,
|
||||
to: '/sensors/temperature',
|
||||
label: 'Temperature',
|
||||
},
|
||||
suffix: '°C',
|
||||
@@ -244,7 +238,6 @@ export const Storage: Story = {
|
||||
value: 384,
|
||||
min: 0,
|
||||
max: 512,
|
||||
to: '/system/storage',
|
||||
label: 'Storage Used',
|
||||
},
|
||||
suffix: ' GB',
|
||||
@@ -273,7 +266,6 @@ export const Rating: Story = {
|
||||
value: 4.2,
|
||||
min: 0,
|
||||
max: 5,
|
||||
to: '/reviews/rating',
|
||||
label: 'Average Rating',
|
||||
},
|
||||
suffix: ' ⭐',
|
||||
@@ -303,7 +295,6 @@ export const WithoutLegend: Story = {
|
||||
value: 65,
|
||||
min: 0,
|
||||
max: 100,
|
||||
to: '/metrics/conversion-no-legend',
|
||||
label: 'Conversion rate',
|
||||
},
|
||||
displayType: 'percentage',
|
||||
|
||||
+95
-164
@@ -1,12 +1,13 @@
|
||||
import { type Meta, type StoryObj } from '@storybook/react';
|
||||
|
||||
import { CatalogDecorator, ComponentDecorator } from 'twenty-ui/testing';
|
||||
import { GraphWidgetPieChart } from '@/page-layout/widgets/graph/graphWidgetPieChart/components/GraphWidgetPieChart';
|
||||
import { CatalogDecorator, ComponentDecorator } from 'twenty-ui/testing';
|
||||
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
|
||||
|
||||
const meta: Meta<typeof GraphWidgetPieChart> = {
|
||||
title: 'Modules/PageLayout/Widgets/GraphWidgetPieChart',
|
||||
component: GraphWidgetPieChart,
|
||||
decorators: [ComponentDecorator],
|
||||
decorators: [ComponentDecorator, I18nFrontDecorator],
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
@@ -33,6 +34,12 @@ const meta: Meta<typeof GraphWidgetPieChart> = {
|
||||
id: {
|
||||
control: 'text',
|
||||
},
|
||||
showCenterMetric: {
|
||||
control: 'boolean',
|
||||
},
|
||||
showDataLabels: {
|
||||
control: 'boolean',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -43,91 +50,14 @@ const Container = ({ children }: { children: React.ReactNode }) => (
|
||||
<div style={{ width: '300px', height: '300px' }}>{children}</div>
|
||||
);
|
||||
|
||||
export const WithCustomColors: Story = {
|
||||
args: {
|
||||
data: [
|
||||
{
|
||||
id: 'segment1',
|
||||
value: 30,
|
||||
label: 'Segment A',
|
||||
color: 'blue',
|
||||
to: '/segments/a',
|
||||
},
|
||||
{
|
||||
id: 'segment2',
|
||||
value: 25,
|
||||
label: 'Segment B',
|
||||
color: 'purple',
|
||||
to: '/segments/b',
|
||||
},
|
||||
{
|
||||
id: 'segment3',
|
||||
value: 20,
|
||||
label: 'Segment C',
|
||||
color: 'turquoise',
|
||||
to: '/segments/c',
|
||||
},
|
||||
{
|
||||
id: 'segment4',
|
||||
value: 15,
|
||||
label: 'Segment D',
|
||||
color: 'orange',
|
||||
to: '/segments/d',
|
||||
},
|
||||
{
|
||||
id: 'segment5',
|
||||
value: 10,
|
||||
label: 'Segment E',
|
||||
color: 'pink',
|
||||
to: '/segments/e',
|
||||
},
|
||||
],
|
||||
showLegend: true,
|
||||
id: 'pie-chart-custom-colors',
|
||||
},
|
||||
render: (args) => (
|
||||
<Container>
|
||||
<GraphWidgetPieChart
|
||||
data={args.data}
|
||||
displayType={args.displayType}
|
||||
prefix={args.prefix}
|
||||
suffix={args.suffix}
|
||||
decimals={args.decimals}
|
||||
showLegend={args.showLegend}
|
||||
id={args.id}
|
||||
/>
|
||||
</Container>
|
||||
),
|
||||
};
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
data: [
|
||||
{
|
||||
id: 'qualified',
|
||||
value: 35,
|
||||
label: 'Qualified',
|
||||
to: '/leads/qualified',
|
||||
},
|
||||
{
|
||||
id: 'contacted',
|
||||
value: 25,
|
||||
label: 'Contacted',
|
||||
to: '/leads/contacted',
|
||||
},
|
||||
{
|
||||
id: 'unqualified',
|
||||
value: 20,
|
||||
label: 'Unqualified',
|
||||
to: '/leads/unqualified',
|
||||
},
|
||||
{ id: 'proposal', value: 15, label: 'Proposal', to: '/leads/proposal' },
|
||||
{
|
||||
id: 'negotiation',
|
||||
value: 5,
|
||||
label: 'Negotiation',
|
||||
to: '/leads/negotiation',
|
||||
},
|
||||
{ id: 'Qualified', value: 35 },
|
||||
{ id: 'Contacted', value: 25 },
|
||||
{ id: 'Unqualified', value: 20 },
|
||||
{ id: 'Proposal', value: 15 },
|
||||
{ id: 'Negotiation', value: 5 },
|
||||
],
|
||||
showLegend: true,
|
||||
id: 'pie-chart-default',
|
||||
@@ -147,33 +77,54 @@ export const Default: Story = {
|
||||
),
|
||||
};
|
||||
|
||||
export const WithCenterMetric: Story = {
|
||||
args: {
|
||||
data: [
|
||||
{ id: 'Qualified', value: 35 },
|
||||
{ id: 'Contacted', value: 25 },
|
||||
{ id: 'Unqualified', value: 20 },
|
||||
],
|
||||
showCenterMetric: true,
|
||||
id: 'pie-chart-with-center-metric',
|
||||
},
|
||||
render: (args) => (
|
||||
<Container>
|
||||
<GraphWidgetPieChart
|
||||
data={args.data}
|
||||
showCenterMetric={args.showCenterMetric}
|
||||
id={args.id}
|
||||
/>
|
||||
</Container>
|
||||
),
|
||||
};
|
||||
|
||||
export const WithDataLabels: Story = {
|
||||
args: {
|
||||
data: [
|
||||
{ id: 'Qualified', value: 35 },
|
||||
{ id: 'Contacted', value: 25 },
|
||||
{ id: 'Unqualified', value: 20 },
|
||||
],
|
||||
showDataLabels: true,
|
||||
id: 'pie-chart-with-data-labels',
|
||||
},
|
||||
render: (args) => (
|
||||
<Container>
|
||||
<GraphWidgetPieChart
|
||||
data={args.data}
|
||||
showDataLabels={args.showDataLabels}
|
||||
id={args.id}
|
||||
/>
|
||||
</Container>
|
||||
),
|
||||
};
|
||||
export const Revenue: Story = {
|
||||
args: {
|
||||
data: [
|
||||
{
|
||||
id: 'product-a',
|
||||
value: 420000,
|
||||
label: 'Product A',
|
||||
to: '/products/a/revenue',
|
||||
},
|
||||
{
|
||||
id: 'product-b',
|
||||
value: 380000,
|
||||
label: 'Product B',
|
||||
to: '/products/b/revenue',
|
||||
},
|
||||
{
|
||||
id: 'product-c',
|
||||
value: 250000,
|
||||
label: 'Product C',
|
||||
to: '/products/c/revenue',
|
||||
},
|
||||
{
|
||||
id: 'product-d',
|
||||
value: 180000,
|
||||
label: 'Product D',
|
||||
to: '/products/d/revenue',
|
||||
},
|
||||
{ id: 'Product A', value: 420000 },
|
||||
{ id: 'Product B', value: 380000 },
|
||||
{ id: 'Product C', value: 250000 },
|
||||
{ id: 'Product D', value: 180000 },
|
||||
],
|
||||
prefix: '$',
|
||||
displayType: 'shortNumber',
|
||||
@@ -198,19 +149,9 @@ export const Revenue: Story = {
|
||||
export const TaskStatus: Story = {
|
||||
args: {
|
||||
data: [
|
||||
{
|
||||
id: 'completed',
|
||||
value: 45,
|
||||
label: 'Completed',
|
||||
to: '/tasks/completed',
|
||||
},
|
||||
{
|
||||
id: 'in-progress',
|
||||
value: 30,
|
||||
label: 'In Progress',
|
||||
to: '/tasks/in-progress',
|
||||
},
|
||||
{ id: 'todo', value: 25, label: 'To Do', to: '/tasks/todo' },
|
||||
{ id: 'Completed', value: 45 },
|
||||
{ id: 'In Progress', value: 30 },
|
||||
{ id: 'To Do', value: 25 },
|
||||
],
|
||||
displayType: 'percentage',
|
||||
showLegend: true,
|
||||
@@ -234,8 +175,8 @@ export const TaskStatus: Story = {
|
||||
export const TwoSlices: Story = {
|
||||
args: {
|
||||
data: [
|
||||
{ id: 'active', value: 75, label: 'Active', to: '/users/active' },
|
||||
{ id: 'inactive', value: 25, label: 'Inactive', to: '/users/inactive' },
|
||||
{ id: 'Active', value: 75 },
|
||||
{ id: 'Inactive', value: 25 },
|
||||
],
|
||||
displayType: 'percentage',
|
||||
showLegend: true,
|
||||
@@ -259,14 +200,14 @@ export const TwoSlices: Story = {
|
||||
export const ManySlices: Story = {
|
||||
args: {
|
||||
data: [
|
||||
{ id: 'category-1', value: 20, label: 'Category 1', to: '/categories/1' },
|
||||
{ id: 'category-2', value: 18, label: 'Category 2', to: '/categories/2' },
|
||||
{ id: 'category-3', value: 16, label: 'Category 3', to: '/categories/3' },
|
||||
{ id: 'category-4', value: 14, label: 'Category 4', to: '/categories/4' },
|
||||
{ id: 'category-5', value: 12, label: 'Category 5', to: '/categories/5' },
|
||||
{ id: 'category-6', value: 10, label: 'Category 6', to: '/categories/6' },
|
||||
{ id: 'category-7', value: 6, label: 'Category 7' },
|
||||
{ id: 'category-8', value: 4, label: 'Category 8' },
|
||||
{ id: 'Category 1', value: 20 },
|
||||
{ id: 'Category 2', value: 18 },
|
||||
{ id: 'Category 3', value: 16 },
|
||||
{ id: 'Category 4', value: 14 },
|
||||
{ id: 'Category 5', value: 12 },
|
||||
{ id: 'Category 6', value: 10 },
|
||||
{ id: 'Category 7', value: 6 },
|
||||
{ id: 'Category 8', value: 4 },
|
||||
],
|
||||
showLegend: true,
|
||||
id: 'pie-chart-many-slices',
|
||||
@@ -289,9 +230,9 @@ export const ManySlices: Story = {
|
||||
export const WithoutLegend: Story = {
|
||||
args: {
|
||||
data: [
|
||||
{ id: 'web', value: 45, label: 'Web', to: '/platforms/web' },
|
||||
{ id: 'mobile', value: 35, label: 'Mobile', to: '/platforms/mobile' },
|
||||
{ id: 'desktop', value: 20, label: 'Desktop', to: '/platforms/desktop' },
|
||||
{ id: 'Web', value: 45 },
|
||||
{ id: 'Mobile', value: 35 },
|
||||
{ id: 'Desktop', value: 20 },
|
||||
],
|
||||
displayType: 'percentage',
|
||||
showLegend: false,
|
||||
@@ -315,10 +256,10 @@ export const WithoutLegend: Story = {
|
||||
export const MarketShare: Story = {
|
||||
args: {
|
||||
data: [
|
||||
{ id: 'brand-a', value: 35.5, label: 'Brand A', to: '/market/brand-a' },
|
||||
{ id: 'brand-b', value: 28.2, label: 'Brand B', to: '/market/brand-b' },
|
||||
{ id: 'brand-c', value: 18.7, label: 'Brand C', to: '/market/brand-c' },
|
||||
{ id: 'others', value: 17.6, label: 'Others', to: '/market/others' },
|
||||
{ id: 'Brand A', value: 35.5 },
|
||||
{ id: 'Brand B', value: 28.2 },
|
||||
{ id: 'Brand C', value: 18.7 },
|
||||
{ id: 'Others', value: 17.6 },
|
||||
],
|
||||
displayType: 'percentage',
|
||||
showLegend: true,
|
||||
@@ -342,20 +283,10 @@ export const MarketShare: Story = {
|
||||
export const Storage: Story = {
|
||||
args: {
|
||||
data: [
|
||||
{
|
||||
id: 'documents',
|
||||
value: 125,
|
||||
label: 'Documents',
|
||||
to: '/storage/documents',
|
||||
},
|
||||
{ id: 'media', value: 280, label: 'Media', to: '/storage/media' },
|
||||
{
|
||||
id: 'applications',
|
||||
value: 95,
|
||||
label: 'Applications',
|
||||
to: '/storage/applications',
|
||||
},
|
||||
{ id: 'system', value: 50, label: 'System', to: '/storage/system' },
|
||||
{ id: 'Documents', value: 125 },
|
||||
{ id: 'Media', value: 280 },
|
||||
{ id: 'Applications', value: 95 },
|
||||
{ id: 'System', value: 50 },
|
||||
],
|
||||
suffix: ' GB',
|
||||
showLegend: true,
|
||||
@@ -377,7 +308,7 @@ export const Storage: Story = {
|
||||
};
|
||||
|
||||
export const Catalog: Story = {
|
||||
decorators: [CatalogDecorator],
|
||||
decorators: [CatalogDecorator, I18nFrontDecorator],
|
||||
parameters: {
|
||||
catalog: {
|
||||
dimensions: [
|
||||
@@ -387,23 +318,23 @@ export const Catalog: Story = {
|
||||
props: (sliceCount: number) => {
|
||||
const dataMap: Record<
|
||||
number,
|
||||
Array<{ id: string; value: number; label?: string }>
|
||||
Array<{ id: string; value: number }>
|
||||
> = {
|
||||
2: [
|
||||
{ id: 'yes', value: 65, label: 'Yes' },
|
||||
{ id: 'no', value: 35, label: 'No' },
|
||||
{ id: 'Yes', value: 65 },
|
||||
{ id: 'No', value: 35 },
|
||||
],
|
||||
3: [
|
||||
{ id: 'gold', value: 45, label: 'Gold' },
|
||||
{ id: 'silver', value: 35, label: 'Silver' },
|
||||
{ id: 'bronze', value: 20, label: 'Bronze' },
|
||||
{ id: 'Gold', value: 45 },
|
||||
{ id: 'Silver', value: 35 },
|
||||
{ id: 'Bronze', value: 20 },
|
||||
],
|
||||
5: [
|
||||
{ id: 'item-1', value: 30, label: 'Item 1' },
|
||||
{ id: 'item-2', value: 25, label: 'Item 2' },
|
||||
{ id: 'item-3', value: 20, label: 'Item 3' },
|
||||
{ id: 'item-4', value: 15, label: 'Item 4' },
|
||||
{ id: 'item-5', value: 10, label: 'Item 5' },
|
||||
{ id: 'Item 1', value: 30 },
|
||||
{ id: 'Item 2', value: 25 },
|
||||
{ id: 'Item 3', value: 20 },
|
||||
{ id: 'Item 4', value: 15 },
|
||||
{ id: 'Item 5', value: 10 },
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user