@@ -84,7 +84,7 @@ export default function Component() {
diff --git a/apps/design-system/styles/globals.css b/apps/design-system/styles/globals.css
index 32c9d5d396b..0a55d08da3e 100644
--- a/apps/design-system/styles/globals.css
+++ b/apps/design-system/styles/globals.css
@@ -36,22 +36,6 @@
}
@layer base {
- :root {
- --chart-1: 12 76% 61%;
- --chart-2: 173 58% 39%;
- --chart-3: 197 37% 24%;
- --chart-4: 43 74% 66%;
- --chart-5: 27 87% 67%;
- }
-
- .dark {
- --chart-1: 220 70% 50%;
- --chart-2: 160 60% 45%;
- --chart-3: 30 80% 55%;
- --chart-4: 280 65% 60%;
- --chart-5: 340 75% 55%;
- }
-
* {
@apply border-border;
}
diff --git a/apps/learn/styles/globals.css b/apps/learn/styles/globals.css
index 1478d871f62..a0fc87d4f3f 100644
--- a/apps/learn/styles/globals.css
+++ b/apps/learn/styles/globals.css
@@ -30,11 +30,6 @@
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
- --color-chart-1: hsl(var(--chart-1));
- --color-chart-2: hsl(var(--chart-2));
- --color-chart-3: hsl(var(--chart-3));
- --color-chart-4: hsl(var(--chart-4));
- --color-chart-5: hsl(var(--chart-5));
}
@layer base {
@@ -58,11 +53,6 @@
--border: hsl(220 13% 91%);
--input: hsl(220 13% 91%);
--ring: hsl(220 13% 70.8%);
- --chart-1: 12 76% 61%;
- --chart-2: 173 58% 39%;
- --chart-3: 197 37% 24%;
- --chart-4: 43 74% 66%;
- --chart-5: 27 87% 67%;
--radius: 0.625rem;
--sidebar: hsl(210 20% 98.5%);
--sidebar-foreground: hsl(224 71.4% 4.1%);
@@ -94,11 +84,6 @@
--border: hsl(215 27.9% 16.9%);
--input: hsl(215 27.9% 16.9%);
--ring: hsl(217.9 10.6% 55.6%);
- --chart-1: 220 70% 50%;
- --chart-2: 160 60% 45%;
- --chart-3: 30 80% 55%;
- --chart-4: 280 65% 60%;
- --chart-5: 340 75% 55%;
--sidebar: hsl(220.9 39.3% 11%);
--sidebar-foreground: hsl(210 20% 98%);
--sidebar-primary: hsl(220 70% 50%);
diff --git a/apps/studio/components/interfaces/Explorer/QueryEditor/QueryResultChart.tsx b/apps/studio/components/interfaces/Explorer/QueryEditor/QueryResultChart.tsx
index 32e018133a6..25412b9ea91 100644
--- a/apps/studio/components/interfaces/Explorer/QueryEditor/QueryResultChart.tsx
+++ b/apps/studio/components/interfaces/Explorer/QueryEditor/QueryResultChart.tsx
@@ -17,11 +17,7 @@ interface QueryResultChartProps {
result?: QueryResult
}
-const Y_SERIES_COLORS = [
- 'hsl(var(--brand-default))',
- 'hsl(var(--chart-blue))',
- 'hsl(var(--chart-3))',
-]
+const Y_SERIES_COLORS = ['hsl(var(--brand-default))', 'var(--chart-2)', 'var(--chart-3)']
const toChartValue = (value: unknown): string | number => {
if (typeof value === 'number' || typeof value === 'string') return value
diff --git a/apps/studio/components/interfaces/Functions/EdgeFunctionOverview/EdgeFunctionOverview.utils.ts b/apps/studio/components/interfaces/Functions/EdgeFunctionOverview/EdgeFunctionOverview.utils.ts
index dbb91f1aed2..a0d90f31fd9 100644
--- a/apps/studio/components/interfaces/Functions/EdgeFunctionOverview/EdgeFunctionOverview.utils.ts
+++ b/apps/studio/components/interfaces/Functions/EdgeFunctionOverview/EdgeFunctionOverview.utils.ts
@@ -88,7 +88,7 @@ export const INVOCATION_CHART_CONFIG = {
},
warning_count: {
label: 'Warnings',
- color: 'var(--chart-warning)',
+ color: 'var(--chart-status-warning)',
},
error_count: {
label: 'Errors',
diff --git a/apps/studio/components/interfaces/QueryInsights/QueryInsightsChart/QueryInsightsChart.constants.ts b/apps/studio/components/interfaces/QueryInsights/QueryInsightsChart/QueryInsightsChart.constants.ts
index 35ec04d9a08..ebcad57322f 100644
--- a/apps/studio/components/interfaces/QueryInsights/QueryInsightsChart/QueryInsightsChart.constants.ts
+++ b/apps/studio/components/interfaces/QueryInsights/QueryInsightsChart/QueryInsightsChart.constants.ts
@@ -9,7 +9,7 @@ export const CHART_TABS = [
export const LEGEND_ITEMS: Record
= {
query_latency: [
- { label: 'P50', color: 'hsl(var(--chart-4))', dataKey: 'p50' },
+ { label: 'P50', color: 'var(--chart-4)', dataKey: 'p50' },
{ label: 'P95', color: CHART_COLORS.GREEN_1, dataKey: 'p95' },
],
rows_read: [{ label: 'Rows Read', color: CHART_COLORS.GREEN_1, dataKey: 'rows_read' }],
@@ -19,4 +19,4 @@ export const LEGEND_ITEMS: Record= threshold.danger
- ? 'var(--chart-destructive)'
+ ? 'var(--chart-status-destructive)'
: value >= threshold.warning
- ? 'var(--chart-warning)'
+ ? 'var(--chart-status-warning)'
: 'var(--chart-1)'
} else {
return value <= threshold.danger
- ? 'var(--chart-destructive)'
+ ? 'var(--chart-status-destructive)'
: value <= threshold.warning
- ? 'var(--chart-warning)'
+ ? 'var(--chart-status-warning)'
: 'var(--chart-1)'
}
}
diff --git a/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.tsx b/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.tsx
index f67b3f1040a..b5099542a44 100644
--- a/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.tsx
+++ b/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.tsx
@@ -77,11 +77,11 @@ import { useShortcut } from '@/state/shortcuts/useShortcut'
export const CHART_CONFIG = {
success: {
label: ,
- color: 'var(--chart-success)',
+ color: 'var(--chart-muted)',
},
warning: {
label: ,
- color: 'var(--chart-warning)',
+ color: 'var(--chart-status-warning)',
},
error: {
label: ,
diff --git a/apps/studio/components/ui/Charts/ComposedChart.tsx b/apps/studio/components/ui/Charts/ComposedChart.tsx
index 90b1babe16e..757556976d4 100644
--- a/apps/studio/components/ui/Charts/ComposedChart.tsx
+++ b/apps/studio/components/ui/Charts/ComposedChart.tsx
@@ -40,6 +40,7 @@ import {
CustomTooltip,
getStackId,
MultiAttribute,
+ resolveChartColor,
} from './ComposedChart.utils'
import NoDataPlaceholder from './NoDataPlaceholder'
import { ChartHighlight } from './useChartHighlight'
@@ -307,7 +308,7 @@ export function ComposedChart({
const maxAttribute = attributes.find((a) => a.isMaxValue)
const maxAttributeData = {
name: maxAttribute?.attribute,
- color: CHART_COLORS.REFERENCE_LINE,
+ color: resolveChartColor(maxAttribute?.color, isDarkMode) ?? CHART_COLORS.REFERENCE_LINE,
}
const referenceLines = attributes.filter((attribute) => {
@@ -342,16 +343,12 @@ export function ComposedChart({
const attribute = attributes.find((attr) => attr.attribute === att.name)
return {
...att,
- color: attribute?.color
- ? isDarkMode
- ? attribute.color.dark
- : attribute.color.light
- : STACKED_CHART_COLORS[index % STACKED_CHART_COLORS.length],
- fill: attribute?.fill
- ? isDarkMode
- ? attribute.fill.dark
- : attribute.fill.light
- : STACKED_CHART_FILLS[index % STACKED_CHART_FILLS.length],
+ color:
+ resolveChartColor(attribute?.color, isDarkMode) ??
+ STACKED_CHART_COLORS[index % STACKED_CHART_COLORS.length],
+ fill:
+ resolveChartColor(attribute?.fill, isDarkMode) ??
+ STACKED_CHART_FILLS[index % STACKED_CHART_FILLS.length],
}
})
: []
@@ -600,7 +597,9 @@ export function ComposedChart({
key={maxAttribute.attribute}
type="linear"
dataKey={maxAttribute.attribute}
- stroke={CHART_COLORS.REFERENCE_LINE}
+ stroke={
+ resolveChartColor(maxAttribute.color, isDarkMode) ?? CHART_COLORS.REFERENCE_LINE
+ }
strokeWidth={2}
strokeDasharray={maxAttribute.strokeDasharray ?? '3 3'}
dot={false}
@@ -616,7 +615,7 @@ export function ComposedChart({
key={line.attribute}
y={line.value}
strokeWidth={1}
- stroke={isDarkMode ? line.color?.dark : line.color?.light}
+ stroke={resolveChartColor(line.color, isDarkMode)}
strokeDasharray={line.strokeDasharray ?? '3 3'}
label={undefined}
>
diff --git a/apps/studio/components/ui/Charts/ComposedChart.utils.tsx b/apps/studio/components/ui/Charts/ComposedChart.utils.tsx
index 3aa6b215d15..60690c6bdb2 100644
--- a/apps/studio/components/ui/Charts/ComposedChart.utils.tsx
+++ b/apps/studio/components/ui/Charts/ComposedChart.utils.tsx
@@ -40,18 +40,25 @@ export interface ReportAttributes {
export type Provider = 'infra-monitoring' | 'daily-stats' | 'mock' | 'reference-line' | 'logs'
+export type ThemedColor = {
+ light?: string
+ dark?: string
+}
+
+export const resolveChartColor = (
+ color: string | ThemedColor | undefined,
+ isDarkMode: boolean | undefined
+) => {
+ if (typeof color === 'string') return color
+ return isDarkMode ? color?.dark : color?.light
+}
+
export type MultiAttribute = {
attribute: string
provider?: Provider
label?: string
- color?: {
- light: string
- dark: string
- }
- fill?: {
- light?: string
- dark?: string
- }
+ color?: string | { light: string; dark: string }
+ fill?: string | ThemedColor
statusCode?: string
grantType?: string
providerType?: string
diff --git a/apps/studio/components/ui/DataTable/DataTable.utils.ts b/apps/studio/components/ui/DataTable/DataTable.utils.ts
index 54366ba78c7..b26e17c4d38 100644
--- a/apps/studio/components/ui/DataTable/DataTable.utils.ts
+++ b/apps/studio/components/ui/DataTable/DataTable.utils.ts
@@ -63,9 +63,9 @@ export function getLevelColor(
case 'success':
return {
text: 'text-muted',
- bg: 'bg-[var(--chart-success)] group-data-[state=selected]/row:bg-foreground-lighter',
+ bg: 'bg-[var(--chart-muted)] group-data-[state=selected]/row:bg-foreground-lighter',
border:
- 'border-[var(--chart-success)] group-data-[state=selected]/row:border-foreground-lighter',
+ 'border-[var(--chart-muted)] group-data-[state=selected]/row:border-foreground-lighter',
}
case 'warning':
return {
diff --git a/apps/studio/data/reports/database-charts.ts b/apps/studio/data/reports/database-charts.ts
index 65e300266e0..45682dbdc16 100644
--- a/apps/studio/data/reports/database-charts.ts
+++ b/apps/studio/data/reports/database-charts.ts
@@ -75,6 +75,8 @@ export const getReportAttributesV2: (
attribute: 'ram_usage_used',
provider: 'infra-monitoring',
label: 'Used',
+ color: 'var(--chart-1)',
+ fill: 'var(--chart-1-fill)',
tooltip:
'RAM in use by Postgres and the operating system. Sustained high usage may indicate memory pressure',
},
@@ -82,6 +84,8 @@ export const getReportAttributesV2: (
attribute: 'ram_usage_cache_and_buffers',
provider: 'infra-monitoring',
label: 'Cache + Buffers',
+ color: 'var(--chart-2)',
+ fill: 'var(--chart-2-fill)',
tooltip:
'RAM used by the operating system page cache and PostgreSQL buffers to accelerate disk reads/writes',
},
@@ -89,6 +93,8 @@ export const getReportAttributesV2: (
attribute: 'ram_usage_free',
provider: 'infra-monitoring',
label: 'Free',
+ color: 'var(--chart-muted)',
+ fill: 'var(--chart-muted-fill)',
tooltip:
'Unallocated memory available for use. A small portion is always reserved by the operating system',
},
@@ -105,6 +111,7 @@ export const getReportAttributesV2: (
provider: 'infra-monitoring',
label: 'Swap',
omitFromTotal: true,
+ color: 'var(--chart-3)',
tooltip:
'Swap space in use by the operating system. Sustained swap usage indicates memory pressure and may degrade database performance',
},
@@ -132,6 +139,8 @@ export const getReportAttributesV2: (
attribute: 'ram_commit_used',
provider: 'infra-monitoring',
label: 'Committed',
+ color: 'var(--chart-1)',
+ fill: 'var(--chart-1-fill)',
tooltip:
'Total memory the kernel has promised to processes (RAM plus swap). Sustained values near or above the commit limit indicate overcommitment and a high risk of out-of-memory failures',
},
@@ -139,6 +148,7 @@ export const getReportAttributesV2: (
attribute: 'ram_commit_limit',
provider: 'infra-monitoring',
label: 'Commit limit',
+ color: 'var(--chart-reference)',
isMaxValue: true,
omitFromTotal: true,
tooltip:
@@ -201,8 +211,8 @@ export const getReportAttributesV2: (
provider: 'infra-monitoring',
label: 'System',
format: '%',
- color: { light: '#EDC35E', dark: '#EDD35E' },
- fill: { light: '#F6D99F', dark: '#5C5230' },
+ color: 'var(--chart-2)',
+ fill: 'var(--chart-2-fill)',
tooltip:
'CPU time spent on kernel operations (e.g., process scheduling, memory management). High values may indicate system overhead',
},
@@ -211,8 +221,8 @@ export const getReportAttributesV2: (
provider: 'infra-monitoring',
label: 'User',
format: '%',
- color: { light: '#0063E8', dark: '#65BCD9' },
- fill: { light: '#80B1F4', dark: '#2A3D45' },
+ color: 'var(--chart-1)',
+ fill: 'var(--chart-1-fill)',
tooltip:
'CPU time used by database queries and user-space processes. High values may suggest CPU-intensive queries',
},
@@ -221,8 +231,8 @@ export const getReportAttributesV2: (
provider: 'infra-monitoring',
label: 'IOwait',
format: '%',
- color: { light: '#DB3A34', dark: '#FF6B6B' },
- fill: { light: '#F2A7A3', dark: '#5C2A2A' },
+ color: 'var(--chart-3)',
+ fill: 'var(--chart-3-fill)',
tooltip:
'CPU time waiting for disk or network I/O. High values may indicate disk bottlenecks',
},
@@ -231,8 +241,8 @@ export const getReportAttributesV2: (
provider: 'infra-monitoring',
label: 'IRQs',
format: '%',
- color: { light: '#DA760B', dark: '#DA760B' },
- fill: { light: '#FFB885', dark: '#5C3D0A' },
+ color: 'var(--chart-4)',
+ fill: 'var(--chart-4-fill)',
tooltip: 'CPU time handling hardware interrupt requests (IRQ)',
},
{
@@ -240,11 +250,30 @@ export const getReportAttributesV2: (
provider: 'infra-monitoring',
label: 'Other',
format: '%',
- color: { light: '#B616A6', dark: '#DB8DF9' },
- fill: { light: '#DB8BD3', dark: '#4A3D5C' },
+ color: 'var(--chart-5)',
+ fill: 'var(--chart-5-fill)',
tooltip:
'CPU time spent on other tasks (e.g., background processes, software interrupts)',
},
+ {
+ attribute: 'cpu_usage_busy_idle',
+ provider: 'infra-monitoring',
+ label: 'Idle',
+ format: '%',
+ omitFromTotal: true,
+ color: 'var(--chart-muted)',
+ fill: 'var(--chart-muted-fill)',
+ tooltip: 'CPU time spent idle and available for new work',
+ },
+ {
+ attribute: 'cpu_usage_max',
+ provider: 'reference-line',
+ label: 'Max',
+ value: 100,
+ color: 'var(--chart-reference)',
+ tooltip: 'Max CPU usage',
+ isMaxValue: true,
+ },
],
},
{
@@ -269,12 +298,16 @@ export const getReportAttributesV2: (
attribute: 'network_receive_bytes',
provider: 'infra-monitoring',
label: 'Network in',
+ color: 'var(--chart-in)',
+ fill: 'var(--chart-in-fill)',
tooltip: 'Inbound network throughput (bytes per second)',
},
{
attribute: 'network_transmit_bytes',
provider: 'infra-monitoring',
label: 'Network out',
+ color: 'var(--chart-out)',
+ fill: 'var(--chart-out-fill)',
tooltip: 'Outbound network throughput (bytes per second)',
},
],
@@ -301,6 +334,8 @@ export const getReportAttributesV2: (
attribute: 'disk_iops_write',
provider: 'infra-monitoring',
label: 'Write IOPS',
+ color: 'var(--chart-out)',
+ fill: 'var(--chart-out-fill)',
tooltip:
'Number of write operations per second. High values indicate frequent data writes, logging, or transaction activity',
},
@@ -308,6 +343,8 @@ export const getReportAttributesV2: (
attribute: 'disk_iops_read',
provider: 'infra-monitoring',
label: 'Read IOPS',
+ color: 'var(--chart-in)',
+ fill: 'var(--chart-in-fill)',
tooltip:
'Number of read operations per second. High values suggest frequent disk reads due to queries or poor caching',
},
@@ -315,6 +352,7 @@ export const getReportAttributesV2: (
attribute: 'disk_iops_max',
provider: 'reference-line',
label: 'Max IOPS',
+ color: 'var(--chart-reference)',
value: effectiveMaxIops,
tooltip:
'Effective maximum IOPS for your current compute and disk configuration. Equal to the lower of the compute IOPS limit and the provisioned disk IOPS',
@@ -345,18 +383,23 @@ export const getReportAttributesV2: (
attribute: 'disk_bytes_read',
provider: 'infra-monitoring',
label: 'Read throughput',
+ color: 'var(--chart-in)',
+ fill: 'var(--chart-in-fill)',
tooltip: 'Disk read throughput (bytes per second)',
},
{
attribute: 'disk_bytes_written',
provider: 'infra-monitoring',
label: 'Write throughput',
+ color: 'var(--chart-out)',
+ fill: 'var(--chart-out-fill)',
tooltip: 'Disk write throughput (bytes per second)',
},
{
attribute: 'disk_throughput_max',
provider: 'reference-line',
label: 'Max throughput',
+ color: 'var(--chart-reference)',
value:
diskConfig?.attributes?.type === 'gp3' &&
typeof diskConfig.attributes.throughput_mbps === 'number'
@@ -418,12 +461,15 @@ export const getReportAttributesV2: (
attribute: 'pg_stat_database_num_backends',
provider: 'infra-monitoring',
label: 'Total connections',
+ color: 'var(--chart-1)',
+ fill: 'var(--chart-1-fill)',
tooltip: 'Total number of active database connections',
},
{
attribute: 'max_db_connections',
provider: 'reference-line',
label: 'Max connections',
+ color: 'var(--chart-reference)',
value: maxConnections?.maxConnections,
tooltip: 'Max available connections for your current compute size',
isMaxValue: true,
@@ -452,6 +498,8 @@ export const getReportAttributesV2: (
attribute: 'client_connections_postgres',
provider: 'infra-monitoring',
label: 'Postgres',
+ color: 'var(--chart-1)',
+ fill: 'var(--chart-1-fill)',
tooltip:
'Direct connections to the Postgres database from your application and external clients',
},
@@ -459,12 +507,16 @@ export const getReportAttributesV2: (
attribute: 'client_connections_authenticator',
provider: 'infra-monitoring',
label: 'PostgREST',
+ color: 'var(--chart-2)',
+ fill: 'var(--chart-2-fill)',
tooltip: 'Connection pool managed by PostgREST',
},
{
attribute: 'client_connections_supabase_admin',
provider: 'infra-monitoring',
label: 'Reserved',
+ color: 'var(--chart-3)',
+ fill: 'var(--chart-3-fill)',
tooltip:
'Administrative connections used by various Supabase services for internal operations and maintenance tasks',
},
@@ -472,24 +524,31 @@ export const getReportAttributesV2: (
attribute: 'client_connections_supabase_auth_admin',
provider: 'infra-monitoring',
label: 'Auth',
+ color: 'var(--chart-4)',
+ fill: 'var(--chart-4-fill)',
tooltip: 'Connection pool managed by Supabase Auth',
},
{
attribute: 'client_connections_supabase_storage_admin',
provider: 'infra-monitoring',
label: 'Storage',
+ color: 'var(--chart-5)',
+ fill: 'var(--chart-5-fill)',
tooltip: 'Connection pool managed by Supabase Storage',
},
{
attribute: 'client_connections_other',
provider: 'infra-monitoring',
label: 'Other roles',
+ color: 'var(--chart-6)',
+ fill: 'var(--chart-6-fill)',
tooltip: "Miscellaneous database connections that don't fall into other categories.",
},
{
attribute: 'max_db_connections',
provider: 'reference-line',
label: 'Max connections',
+ color: 'var(--chart-reference)',
value: maxConnections?.maxConnections,
tooltip: 'Max available connections for your current compute size',
isMaxValue: true,
@@ -522,12 +581,15 @@ export const getReportAttributesV2: (
attribute: 'client_connections_pgbouncer',
provider: 'infra-monitoring',
label: isHighAvailability ? 'multipooler' : 'pgbouncer',
+ color: 'var(--chart-1)',
+ fill: 'var(--chart-1-fill)',
tooltip: isHighAvailability ? 'Multipooler connections' : 'PgBouncer connections',
},
{
attribute: 'pg_pooler_max_connections',
provider: 'reference-line',
label: 'Max pooler connections',
+ color: 'var(--chart-reference)',
value: pgBouncerMaxConnections,
tooltip: 'Maximum allowed pooler connections for your current compute size',
isMaxValue: true,
@@ -555,6 +617,8 @@ export const getReportAttributesV2: (
attribute: 'supavisor_connections_active',
provider: 'infra-monitoring',
label: 'supavisor',
+ color: 'var(--chart-1)',
+ fill: 'var(--chart-1-fill)',
tooltip: 'Supavisor connections',
},
],
@@ -582,6 +646,8 @@ export const getReportAttributesV2: (
provider: 'infra-monitoring',
format: 'bytes',
label: 'System',
+ color: 'var(--chart-3)',
+ fill: 'var(--chart-3-fill)',
tooltip: 'Reserved space for the system to ensure your database runs smoothly',
},
{
@@ -589,6 +655,8 @@ export const getReportAttributesV2: (
provider: 'infra-monitoring',
format: 'bytes',
label: 'WAL',
+ color: 'var(--chart-2)',
+ fill: 'var(--chart-2-fill)',
tooltip:
'Disk usage by the write-ahead log. The usage depends on your WAL settings and the amount of data being written to the database',
},
@@ -597,6 +665,8 @@ export const getReportAttributesV2: (
provider: 'infra-monitoring',
format: 'bytes',
label: 'Database',
+ color: 'var(--chart-1)',
+ fill: 'var(--chart-1-fill)',
tooltip: 'Disk usage by your database (tables, indexes, data, ...)',
},
{
@@ -605,6 +675,7 @@ export const getReportAttributesV2: (
isMaxValue: true,
format: 'bytes',
label: 'Disk Size',
+ color: 'var(--chart-reference)',
tooltip: 'Disk Size refers to the total space your project occupies on disk',
},
entitledFeatures.includes('database') &&
diff --git a/apps/studio/styles/globals.css b/apps/studio/styles/globals.css
index 44e8f55b3c1..d75d9ca72f4 100644
--- a/apps/studio/styles/globals.css
+++ b/apps/studio/styles/globals.css
@@ -138,16 +138,6 @@
}
:root {
- --chart-1: hsl(var(--brand-default));
- --chart-2: 173 58% 39%;
- --chart-3: 197 37% 24%;
- --chart-4: 43 74% 66%;
- --chart-5: 27 87% 67%;
- --chart-blue: 217 91% 60%;
- --chart-warning: hsl(var(--warning-500));
- --chart-warning-muted: hsl(var(--warning-400));
- --chart-destructive: hsl(var(--destructive-default));
- --chart-success: color-mix(in oklch, var(--foreground-muted) 50%, white);
--sidebar-background: var(--background-dash-sidebar);
--sidebar-foreground: var(--foreground-default);
--sidebar-primary: var(--foreground-default);
@@ -161,16 +151,6 @@
[data-theme='dark'],
.dark {
- --chart-1: hsl(var(--brand-default));
- --chart-2: 160 60% 45%;
- --chart-3: 30 80% 55%;
- --chart-4: 280 65% 60%;
- --chart-5: 340 75% 55%;
- --chart-blue: 217 91% 65%;
- --chart-warning: hsl(var(--warning-default));
- --chart-warning-muted: hsl(var(--warning-500));
- --chart-destructive: hsl(var(--destructive-default));
- --chart-success: color-mix(in oklch, var(--foreground-muted) 55%, var(--background));
--sidebar-background: var(--background-dash-sidebar);
--sidebar-foreground: var(--foreground-default);
--sidebar-primary: var(--foreground-default);
diff --git a/apps/ui-library/styles/globals.css b/apps/ui-library/styles/globals.css
index 6d89a7d3595..f1cb2bfd4d2 100644
--- a/apps/ui-library/styles/globals.css
+++ b/apps/ui-library/styles/globals.css
@@ -37,11 +37,6 @@
/* --color-border: var(--border); */
--color-input: var(--input);
--color-ring: var(--ring);
- --color-chart-1: hsl(var(--chart-1));
- --color-chart-2: hsl(var(--chart-2));
- --color-chart-3: hsl(var(--chart-3));
- --color-chart-4: hsl(var(--chart-4));
- --color-chart-5: hsl(var(--chart-5));
}
@layer base {
@@ -65,11 +60,6 @@
--border: hsl(0 0% 92.2%);
--input: hsl(0 0% 92.2%);
--ring: hsl(0 0% 70.8%);
- --chart-1: 41.1 22.2% 64.6%;
- --chart-2: 184.7 11.8% 60%;
- --chart-3: 227.4 7% 39.8%;
- --chart-4: 84.4 18.9% 82.8%;
- --chart-5: 70.1 18.8% 76.9%;
--radius: 0.625rem;
--sidebar: hsl(0 0% 98.5%);
--sidebar-foreground: hsl(0 0% 14.5%);
@@ -102,11 +92,6 @@
--border: hsl(0 0% 26.9%);
--input: hsl(0 0% 26.9%);
--ring: hsl(0 0% 55.6%);
- --chart-1: 264.4 24.3% 48.8%;
- --chart-2: 162.5 17% 69.6%;
- --chart-3: 70.1 18.8% 76.9%;
- --chart-4: 303.9 26.5% 62.7%;
- --chart-5: 16.4 24.6% 64.5%;
--sidebar: hsl(0 0% 20.5%);
--sidebar-foreground: hsl(0 0% 98.5%);
--sidebar-primary: hsl(264.4 24.3% 48.8%);
diff --git a/packages/config/css/charts.css b/packages/config/css/charts.css
new file mode 100644
index 00000000000..806419ac650
--- /dev/null
+++ b/packages/config/css/charts.css
@@ -0,0 +1,48 @@
+:root {
+ --chart-1: var(--color-brand-800);
+ --chart-2: var(--color-blue-900);
+ --chart-3: var(--color-pink-1000);
+ --chart-4: var(--color-violet-900);
+ --chart-5: var(--color-tomato-1000);
+ --chart-6: var(--color-indigo-1000);
+ --chart-7: var(--color-green-1100);
+ --chart-8: var(--color-purple-1000);
+
+ --chart-1-fill: var(--color-brand-500);
+ --chart-2-fill: var(--color-blue-500);
+ --chart-3-fill: var(--color-pink-500);
+ --chart-4-fill: var(--color-violet-500);
+ --chart-5-fill: var(--color-tomato-500);
+ --chart-6-fill: var(--color-indigo-500);
+ --chart-7-fill: var(--color-green-500);
+ --chart-8-fill: var(--color-purple-500);
+
+ --chart-in: var(--chart-2);
+ --chart-out: var(--chart-5);
+ --chart-in-fill: var(--chart-2-fill);
+ --chart-out-fill: var(--chart-5-fill);
+
+ --chart-reference: var(--color-scale-1000);
+ --chart-muted: var(--color-scale-700);
+ --chart-muted-fill: var(--color-scale-400);
+
+ --chart-status-success: hsl(var(--brand-default));
+ --chart-status-success-muted: hsl(var(--brand-500));
+ --chart-status-warning: var(--warning);
+ --chart-status-warning-muted: hsl(var(--warning-500));
+ --chart-status-destructive: var(--destructive);
+ --chart-status-destructive-muted: hsl(var(--destructive-500));
+}
+
+[data-theme*='dark'] {
+ --chart-1: var(--color-brand-900);
+ --chart-2: var(--color-blue-1100);
+ --chart-3: var(--color-pink-1100);
+ --chart-4: var(--color-violet-1100);
+ --chart-5: var(--color-tomato-1100);
+ --chart-6: var(--color-indigo-1100);
+ --chart-7: var(--color-green-1100);
+ --chart-8: var(--color-purple-1100);
+
+ --chart-muted: var(--color-scale-800);
+}
diff --git a/packages/config/tailwind.config.css b/packages/config/tailwind.config.css
index 329638a906a..28f167840a1 100644
--- a/packages/config/tailwind.config.css
+++ b/packages/config/tailwind.config.css
@@ -26,6 +26,7 @@
* consumes them from @theme inline so Tailwind generates the utilities. */
@import './css/colors.css';
@import './css/theme.css';
+@import './css/charts.css';
@import './css/animations.css';
@import './css/utilities.css';
@import './tailwind-plugins/hit-area.css';
diff --git a/packages/ui-patterns/src/Chart/charts/chart-bar.tsx b/packages/ui-patterns/src/Chart/charts/chart-bar.tsx
index 49825a36265..1418ac7ab9a 100644
--- a/packages/ui-patterns/src/Chart/charts/chart-bar.tsx
+++ b/packages/ui-patterns/src/Chart/charts/chart-bar.tsx
@@ -15,6 +15,8 @@ import {
import type { CategoricalChartState } from 'recharts/types/chart/types'
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent, cn } from 'ui'
+const DIMMED_FILL_OPACITY = 0.35
+
const CHART_COLORS = {
TICK: 'var(--background-overlay-hover)',
AXIS: 'var(--background-overlay-hover)',
@@ -66,6 +68,8 @@ export interface ChartBarProps {
showGrid?: boolean
showYAxis?: boolean
showXAxis?: boolean
+ isStacked?: boolean
+ margin?: { top?: number; right?: number; bottom?: number; left?: number }
XAxisProps?: {
tick?: boolean
tickFormatter?: (value: any) => string
@@ -102,6 +106,8 @@ export const ChartBar = ({
showGrid = false,
showYAxis = false,
showXAxis = false,
+ isStacked = false,
+ margin: marginProp,
XAxisProps,
YAxisProps,
}: ChartBarProps) => {
@@ -146,23 +152,28 @@ export const ChartBar = ({
...XAxisProps,
}
+ const yAxisWidth = showYAxis ? (YAxisProps?.width ?? 60) : 0
+
const yAxisConfig = {
tick: showYAxis
? { fill: 'var(--color-foreground-lighter)', fontSize: 10, fontFamily: 'var(--font-mono)' }
: false,
hide: !showYAxis,
tickMargin: showYAxis ? (YAxisProps?.tickMargin ?? 4) : 0,
- width: showYAxis ? (YAxisProps?.width ?? 60) : 0,
+ width: yAxisWidth,
axisLine: { stroke: CHART_COLORS.AXIS },
tickLine: { stroke: CHART_COLORS.AXIS },
...YAxisProps,
}
+ const hasDateRangeFooter = xKey === 'timestamp' && data.length > 0
+
const margin = {
top: 0,
right: 0,
left: 0,
bottom: 0,
+ ...marginProp,
}
return (
@@ -170,7 +181,10 @@ export const ChartBar = ({
data-testid="chart-bar"
className={cn('flex flex-col gap-y-3 w-full', isFullHeight ? 'h-full' : 'h-24', className)}
>
-
+
}
/>
- {/* Selection highlight area */}
{showHighlightActions && (
+ return (
+
+ {data.map((_entry: ChartBarTick, dataIndex: number) => (
+ |
+ ))}
+
+ )
})
) : (
@@ -267,8 +301,11 @@ export const ChartBar = ({
- {xKey === 'timestamp' && data && data.length > 0 && (
-
+ {hasDateRangeFooter && (
+
{dayjs(data[0][xKey]).format(DateTimeFormat)}
{dayjs(data[data.length - 1]?.[xKey]).format(DateTimeFormat)}
diff --git a/packages/ui-patterns/src/Chart/charts/chart-line.tsx b/packages/ui-patterns/src/Chart/charts/chart-line.tsx
index c100f8100fd..9ef6069064e 100644
--- a/packages/ui-patterns/src/Chart/charts/chart-line.tsx
+++ b/packages/ui-patterns/src/Chart/charts/chart-line.tsx
@@ -2,7 +2,7 @@
import dayjs from 'dayjs'
import { useTheme } from 'next-themes'
-import { ReactNode, useState } from 'react'
+import { ReactNode, useId, useState } from 'react'
import {
Area,
CartesianGrid,
@@ -118,6 +118,7 @@ export const ChartLine = ({
referenceLines,
}: ChartLineProps) => {
const [focusDataIndex, setFocusDataIndex] = useState
(null)
+ const gradientPrefix = `chart-line-fill-${useId().replace(/:/g, '')}`
const { resolvedTheme } = useTheme()
const isDarkMode = resolvedTheme?.includes('dark')
@@ -157,18 +158,30 @@ export const ChartLine = ({
...XAxisProps,
}
+ const yAxisWidth = showYAxis ? (YAxisProps?.width ?? 60) : 0
+
const yAxisConfig = {
tick: showYAxis
? { fill: 'var(--color-foreground-lighter)', fontSize: 10, fontFamily: 'var(--font-mono)' }
: false,
hide: !showYAxis,
tickMargin: showYAxis ? (YAxisProps?.tickMargin ?? 4) : 0,
- width: showYAxis ? (YAxisProps?.width ?? 60) : 0,
+ width: yAxisWidth,
axisLine: { stroke: CHART_COLORS.AXIS },
tickLine: { stroke: CHART_COLORS.AXIS },
...YAxisProps,
}
+ const hasDateRangeFooter = xKey === 'timestamp' && data.length > 0
+
+ const resolveSeriesColor = (key: string) => {
+ const keyConfig = chartConfig[key]
+ return (
+ keyConfig?.color ||
+ (keyConfig?.theme ? (isDarkMode ? keyConfig.theme.dark : keyConfig.theme.light) : color)
+ )
+ }
+
const margin = {
top: 0,
right: 0,
@@ -189,7 +202,10 @@ export const ChartLine = ({
data-testid="chart-line"
className={cn('flex flex-col gap-y-3 w-full', isFullHeight ? 'h-full' : 'h-24', className)}
>
-
+
+
+ {keysToRender.map((key, index) => (
+
+
+
+
+ ))}
+
{showGrid && }
@@ -275,7 +306,6 @@ export const ChartLine = ({
/>
}
/>
- {/* Selection highlight area */}
{showHighlightActions && (
))}
- {keysToRender.map((key, index) => {
- const keyConfig = chartConfig[key]
- const lineColor =
- keyConfig?.color ||
- (keyConfig?.theme
- ? isDarkMode
- ? keyConfig.theme.dark
- : keyConfig.theme.light
- : color)
- const baseOpacity = 0.2
- const opacityIncrement = 0.1
- const maxOpacity = 0.6
- const fillOpacity = Math.min(baseOpacity + index * opacityIncrement, maxOpacity)
-
- return (
- 1 ? `stack-${key}` : undefined}
- />
- )
- })}
+ {keysToRender.map((key, index) => (
+ 1 ? `stack-${key}` : undefined}
+ />
+ ))}
- {xKey === 'timestamp' && data && data.length > 0 && (
-
+ {hasDateRangeFooter && (
+
{dayjs(data[0][xKey]).format(DateTimeFormat)}
{dayjs(data[data.length - 1]?.[xKey]).format(DateTimeFormat)}
diff --git a/packages/ui-patterns/src/LogsBarChart/index.tsx b/packages/ui-patterns/src/LogsBarChart/index.tsx
index c22c003eda2..3d05eaed38e 100644
--- a/packages/ui-patterns/src/LogsBarChart/index.tsx
+++ b/packages/ui-patterns/src/LogsBarChart/index.tsx
@@ -13,8 +13,8 @@ const CHART_COLORS = {
GREEN_2: 'hsl(var(--brand-500))',
RED_1: 'hsl(var(--destructive-default))',
RED_2: 'hsl(var(--destructive-500))',
- YELLOW_1: 'var(--chart-warning, hsl(var(--warning-default)))',
- YELLOW_2: 'var(--chart-warning-muted, hsl(var(--warning-500)))',
+ YELLOW_1: 'var(--chart-status-warning)',
+ YELLOW_2: 'var(--chart-status-warning-muted)',
}
type LogsBarChartDatum = {