Skip to content

Add reusable BarChart component and chart utilities to fidesui#7699

Draft
kruulik wants to merge 12 commits intomainfrom
access-control-charts
Draft

Add reusable BarChart component and chart utilities to fidesui#7699
kruulik wants to merge 12 commits intomainfrom
access-control-charts

Conversation

@kruulik
Copy link
Contributor

@kruulik kruulik commented Mar 19, 2026

Ticket: N/A part of PBAC work

Description Of Changes

Add generic, reusable chart components and time-series utilities to fidesui in preparation for the access control dashboard feature. These components are domain-agnostic and can be used by any feature requiring bar charts or time-series visualizations.

Components added:

  • BarChart — responsive bar chart with Ant Design theme integration, supports both categorical and time-series data
  • XAxisTick — custom X-axis tick renderer with smart timestamp formatting based on interval

Utilities added to chart-utils.ts:

  • pickInterval(startMs, endMs) — selects appropriate chart granularity (hourly/6h/daily) based on date range
  • formatTimestamp(timestamp, intervalMs) — formats ISO timestamps for tick labels with invalid-date fallback
  • deriveInterval(data) — auto-detects interval from consecutive data points
  • tooltipLabelFormatter(label, intervalMs) — formats tooltip labels with full date/time info
  • useTooltipContentStyle() — memoized hook returning Ant Design-themed tooltip styles

Quality improvements to existing utilities:

  • Invalid date guards on formatTimestamp and tooltipLabelFormatter
  • useChartAnimation in BarChart for consistency with Sparkline, DonutChart, RadarChart, StackedBarChart
  • Defensive defaults on XAxisTick props
  • Memoized useTooltipContentStyle to prevent unnecessary re-renders

Code Changes

  • clients/fidesui/src/components/charts/BarChart.tsx - New reusable bar chart component
  • clients/fidesui/src/components/charts/BarChart.stories.tsx - Storybook stories covering categorical, time-series, colored, and custom formatter variants
  • clients/fidesui/src/components/charts/XAxisTick.tsx - New custom X-axis tick renderer
  • clients/fidesui/src/components/charts/chart-utils.ts - New time-series utilities + hardening of date formatting
  • clients/fidesui/src/index.ts - Export new components and utilities

Steps to Confirm

  1. Run cd clients/fidesui && npm run storybook
  2. Navigate to Charts > BarChart in the Storybook sidebar
  3. Verify all 6 stories render correctly (Default, Colored, HourlyTimeSeries, DailyTimeSeries, NoAnimation, CustomTickFormatter)
  4. Verify bar animation plays once and does not re-trigger on interaction
  5. Hover over bars to confirm tooltip styling matches Ant Design theme

Pre-Merge Checklist

  • Issue requirements met
  • All CI pipelines succeeded
  • CHANGELOG.md updated
    • Add a db-migration This indicates that a change includes a database migration label to the entry if your change includes a DB migration
    • Add a high-risk This issue suggests changes that have a high-probability of breaking existing code label to the entry if your change includes a high-risk change (i.e. potential for performance impact or unexpected regression) that should be flagged
    • Updates unreleased work already in Changelog, no new entry necessary
  • UX feedback:
    • All UX related changes have been reviewed by a designer
    • No UX review needed
  • Followup issues:
    • Followup issues created
    • No followup issues
  • Database migrations:
    • No migrations
  • Documentation:
    • No documentation updates required

kruulik and others added 7 commits March 18, 2026 17:09
Adds BarChart component, XAxisTick renderer, and time-series utility
functions (pickInterval, formatTimestamp, deriveInterval, tooltipLabelFormatter)
to support upcoming access control dashboard visualizations.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds the summary tab for the access control feature (behind feature flag):
- Time-series violations chart, violation rate donut, data consumers table
- Paginated findings table with policy violation aggregates
- RTK Query endpoints for summary data
- Mock data and MSW handlers for local development

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Guard formatTimestamp/tooltipLabelFormatter against invalid dates
- Add defensive defaults to XAxisTick props and document deriveInterval contract
- Use useChartAnimation in BarChart (consistent with Sparkline, DonutChart, etc.)
- Memoize useTooltipContentStyle to avoid unnecessary re-renders
- Fix lint: merge duplicate react imports, sort imports

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Contributor

vercel bot commented Mar 19, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Actions Updated (UTC)
fides-plus-nightly Ignored Ignored Preview Mar 19, 2026 8:51pm
fides-privacy-center Ignored Ignored Mar 19, 2026 8:51pm

Request Review

kruulik and others added 2 commits March 19, 2026 00:26
Categorical labels were rendered by Recharts' default tick (browser
sans-serif) while time-series labels went through ChartText (Bazier Mono).
Now both paths use ChartText so the font is always consistent.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@kruulik
Copy link
Contributor Author

kruulik commented Mar 19, 2026

@greptile

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 19, 2026

Greptile Summary

This PR adds a reusable BarChart component, a custom XAxisTick renderer, and a set of time-series chart utilities (pickInterval, formatTimestamp, deriveInterval, tooltipLabelFormatter, useTooltipContentStyle) to fidesui in preparation for the access control dashboard. It also adds fontFamilyCode to CustomStatistic and exports everything from index.ts.

Key observations:

  • tickFormatter is ignored when intervalMs is set — the renderTick branch for time-series always renders <XAxisTick> directly without consulting the formatLabel variable (which correctly incorporates tickFormatter). This means a caller who provides both intervalMs and a custom tickFormatter silently gets the wrong tick labels.
  • deriveInterval field name mismatch — the function signature accepts { timestamp: string }[] but BarChartDataPoint uses label: string. Passing BarChart data directly to deriveInterval will silently derive a NaN gap and always fall back to HOUR_MS.
  • Stories use Math.random() for time-series data values, making renders non-deterministic — consider seeding or using fixed values if snapshot/visual regression tests are added later.

Confidence Score: 3/5

  • Safe to merge after fixing the tickFormatter/intervalMs interaction bug and the deriveInterval field name mismatch.
  • Two logic-level inconsistencies exist: the tickFormatter prop is silently ignored for time-series charts, and deriveInterval will always return the default HOUR_MS fallback when called with BarChartDataPoint data because it reads a non-existent timestamp field. Both will produce incorrect but non-crashing behavior, making them easy to miss without targeted tests.
  • clients/fidesui/src/components/charts/BarChart.tsx and clients/fidesui/src/components/charts/chart-utils.ts need the most attention.

Important Files Changed

Filename Overview
clients/fidesui/src/components/charts/BarChart.tsx New reusable bar chart component — has a logic bug where tickFormatter is silently ignored whenever intervalMs is provided, because the XAxisTick path bypasses the already-computed formatLabel variable.
clients/fidesui/src/components/charts/chart-utils.ts New time-series utilities added cleanly; however deriveInterval uses a timestamp field name that does not match the label field on BarChartDataPoint, making it unusable directly with BarChart data.
clients/fidesui/src/components/charts/XAxisTick.tsx Simple, well-structured custom axis tick renderer; defensive defaults on all optional props. No issues found.
clients/fidesui/src/components/charts/BarChart.stories.tsx Storybook stories cover the main use cases; uses a bare <div> wrapper (violates project convention) and a single-character variable i; Math.random() makes data non-deterministic across renders.
clients/fidesui/src/hoc/CustomStatistic.tsx Minor addition of fontFamilyCode to statistic value style; straightforward and correct.
clients/fidesui/src/index.ts New exports added for BarChart, XAxisTick, and chart utilities; follows existing export ordering convention. No issues found.

Last reviewed commit: "update barchart"

Comment on lines +81 to +89
export const deriveInterval = (data: { timestamp: string }[]): number => {
if (data.length < 2) {
return HOUR_MS;
}
const gap =
new Date(data[1].timestamp).getTime() -
new Date(data[0].timestamp).getTime();
return gap > 0 ? gap : HOUR_MS;
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 deriveInterval expects timestamp but BarChart uses label

The deriveInterval utility takes data: { timestamp: string }[], but BarChartDataPoint declares the field as label: string. A caller who tries to pass BarChart's data array directly to deriveInterval will find zero matching properties — the derived gap will be NaN, gap > 0 will be false, and the function will fall back to HOUR_MS silently regardless of the actual data.

Since this utility is intended to auto-detect the interval from BarChart data, the field name should either match label:

Suggested change
export const deriveInterval = (data: { timestamp: string }[]): number => {
if (data.length < 2) {
return HOUR_MS;
}
const gap =
new Date(data[1].timestamp).getTime() -
new Date(data[0].timestamp).getTime();
return gap > 0 ? gap : HOUR_MS;
};
export const deriveInterval = (data: { label: string }[]): number => {
if (data.length < 2) {
return HOUR_MS;
}
const gap =
new Date(data[1].label).getTime() -
new Date(data[0].label).getTime();
return gap > 0 ? gap : HOUR_MS;
};

Or, if deriveInterval is intentionally designed for a different, more general-purpose shape, document that clearly and provide a separate helper that accepts BarChartDataPoint[].

kruulik and others added 3 commits March 19, 2026 09:34
- Fix tickFormatter being silently ignored when intervalMs is set by
  unifying both tick paths into a single ChartText-based renderer
- Rename i → index in story generator
- Replace div with Flex in story decorator

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant