Skip to content

fix(insights): split aggregated bar bands per series#60488

Merged
sampennington merged 10 commits into
masterfrom
sam/horizontal-bar-hover-color
May 29, 2026
Merged

fix(insights): split aggregated bar bands per series#60488
sampennington merged 10 commits into
masterfrom
sam/horizontal-bar-hover-color

Conversation

@sampennington
Copy link
Copy Markdown
Contributor

@sampennington sampennington commented May 28, 2026

Problem

Two related bugs in the aggregated horizontal bar chart (TrendsBarChart / ActionsBarValue, hog-charts path):

  1. Four trends series of the same event (e.g. four \$pageview rows with no breakdown) all surface label="\$pageview". The band-key was the display label, so d3.scaleBand collapsed every series onto one band slot. The sparse-stacked layout drew them all at the same position; only the last-painted (typically largest) bar was visible.
  2. On hover, the highlight pass iterated every series whose bar matched on the band axis — including those drawn at the same position but belonging to a different series. The darken pass then used that other series's color, so the visible purple bar appeared to flash blue.

The intended overlap behavior for formula+breakdown stays correct (one band per formula, breakdown bars overlap by descending size inside it) — the bug only surfaces when different series happen to share a display label.

Changes

  • buildTrendsBarAggregatedSeries now returns displayLabels (human strings, compare-suffix preserved) and labels (synthetic band keys ${displayLabel}__${seriesId}). Series id is action.order for normal rows or the top-level order for formula rows.
  • Different series with the same display label → different band keys → separate rows.
  • Breakdown rows of one series share their series id → one band key → existing overlap visual preserved.
  • TrendsBarChart reads displayLabels and feeds an xTickFormatter that maps band keys back to human strings, returning null for repeats so band-shared rows don't draw the same tick text on top of itself.

How did you test this code?

I'm an agent — needs a visual re-check on the affected setups.

  • pnpm exec jest products/product_analytics/frontend/insights/trends/TrendsBarChart/trendsBarChartTransforms.test.ts products/product_analytics/frontend/insights/trends/TrendsBarChart/TrendsBarChart.test.tsx — 52 pass. Includes two new transform tests that lock the rule in both directions:
    • 4 same-event series → 4 distinct band slots.
    • 3 formulas × multiple breakdown rows → 3 distinct band slots.

🤖 Agent context

Authored by Claude Opus 4.7 via Claude Code. Earlier branch attempts on this PR were the wrong shape:

  1. Darken hover for the legacy ActionsHorizontalBar — covered a different code path the reporter wasn't using.
  2. Narrow BarChart.drawHover to full-rect containment — treated the hover symptom but the bars themselves were still mis-grouped.
  3. Force every aggregated result into its own band — fixed the four-series case but broke the formula+breakdown case the reporter validated against (which depends on same-label rows sharing a band so the larger bars peek past the smaller ones).

This version distinguishes "same label because same series" (group) from "same label because different series" (split) using the series id the trends data layer already carries.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 28, 2026

Size Change: +5.42 kB (+0.01%)

Total Size: 80.7 MB

📦 View Changed
Filename Size Change
frontend/dist-report/exporter/_chunks/chunk 8.42 MB +1.72 kB (+0.02%)
frontend/dist-report/posthog-app/_chunks/chunk 8.62 MB +1.73 kB (+0.02%)
frontend/dist-report/render-query/src/render-query/render-query 27.4 MB +1.97 kB (+0.01%)
ℹ️ View Unchanged
Filename Size Change
frontend/dist-report/decompression-worker/src/scenes/session-recordings/player/snapshot-processing/decompressionWorker 2.85 kB 0 B
frontend/dist-report/exporter/_parent/products/actions/frontend/pages/Action 24.9 kB 0 B
frontend/dist-report/exporter/_parent/products/actions/frontend/pages/Actions 1.3 kB 0 B
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/AIObservabilityScene 118 kB 0 B
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/AIObservabilitySessionScene 18.3 kB 0 B
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/AIObservabilityTraceScene 130 kB 0 B
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/AIObservabilityUsers 838 B 0 B
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/clusters/AIObservabilityClusterScene 21.7 kB 0 B
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/clusters/AIObservabilityClustersScene 55 kB 0 B
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/datasets/AIObservabilityDatasetScene 20.9 kB 0 B
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/datasets/AIObservabilityDatasetsScene 3.6 kB 0 B
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/evaluations/AIObservabilityEvaluation 59.8 kB 0 B
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/evaluations/AIObservabilityEvaluationsScene 28.1 kB 0 B
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/evaluations/EvaluationTemplates 881 B 0 B
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/LLMASessionFeedbackDisplay 5.16 kB 0 B
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/playground/AIObservabilityPlaygroundScene 37.7 kB 0 B
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/prompts/LLMPromptScene 29.1 kB 0 B
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/prompts/LLMPromptsScene 4.79 kB 0 B
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/skills/LLMSkillScene 895 B 0 B
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/skills/LLMSkillsScene 912 B 0 B
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/tags/AIObservabilityTag 27.3 kB 0 B
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/tags/AIObservabilityTagsScene 7.27 kB 0 B
frontend/dist-report/exporter/_parent/products/business_knowledge/frontend/scenes/BusinessKnowledgeScene 19 kB 0 B
frontend/dist-report/exporter/_parent/products/conversations/frontend/components/Assignee/CyclotronJobInputAssignee 1.64 kB 0 B
frontend/dist-report/exporter/_parent/products/conversations/frontend/components/SlaBusinessHours/CyclotronJobInputBusinessHours 3.02 kB 0 B
frontend/dist-report/exporter/_parent/products/conversations/frontend/components/TicketTags/CyclotronJobInputTicketTags 1.02 kB 0 B
frontend/dist-report/exporter/_parent/products/conversations/frontend/scenes/settings/SupportSettingsScene 1.78 kB 0 B
frontend/dist-report/exporter/_parent/products/conversations/frontend/scenes/ticket/SupportTicketScene 33.9 kB 0 B
frontend/dist-report/exporter/_parent/products/conversations/frontend/scenes/tickets/SupportTicketsScene 1.04 kB 0 B
frontend/dist-report/exporter/_parent/products/customer_analytics/frontend/CustomerAnalyticsScene 39.2 kB 0 B
frontend/dist-report/exporter/_parent/products/customer_analytics/frontend/scenes/CustomerAnalyticsConfigurationScene/CustomerAnalyticsConfigurationScene 2.61 kB 0 B
frontend/dist-report/exporter/_parent/products/customer_analytics/frontend/scenes/CustomerJourneyBuilderScene/CustomerJourneyBuilderScene 2.15 kB 0 B
frontend/dist-report/exporter/_parent/products/customer_analytics/frontend/scenes/CustomerJourneyTemplatesScene/CustomerJourneyTemplatesScene 7.83 kB 0 B
frontend/dist-report/exporter/_parent/products/data_warehouse/DataWarehouseScene 46.8 kB 0 B
frontend/dist-report/exporter/_parent/products/data_warehouse/frontend/scenes/NewSourceScene/NewSourceScene 1.08 kB 0 B
frontend/dist-report/exporter/_parent/products/data_warehouse/frontend/scenes/SchemaScene/SchemaScene 24 kB 0 B
frontend/dist-report/exporter/_parent/products/data_warehouse/frontend/scenes/SourceScene/SourceScene 1.03 kB 0 B
frontend/dist-report/exporter/_parent/products/data_warehouse/frontend/scenes/SourcesScene/SourcesScene 6.27 kB 0 B
frontend/dist-report/exporter/_parent/products/deployments/frontend/Deployment 4.02 kB 0 B
frontend/dist-report/exporter/_parent/products/deployments/frontend/DeploymentProject 5.54 kB 0 B
frontend/dist-report/exporter/_parent/products/deployments/frontend/Deployments 9.28 kB 0 B
frontend/dist-report/exporter/_parent/products/early_access_features/frontend/EarlyAccessFeature 991 B 0 B
frontend/dist-report/exporter/_parent/products/early_access_features/frontend/EarlyAccessFeatures 3.21 kB 0 B
frontend/dist-report/exporter/_parent/products/endpoints/frontend/EndpointScene 40.6 kB 0 B
frontend/dist-report/exporter/_parent/products/endpoints/frontend/EndpointsScene 24.5 kB 0 B
frontend/dist-report/exporter/_parent/products/error_tracking/frontend/scenes/ErrorTrackingFingerprintsScene/ErrorTrackingIssueFingerprintsScene 7.37 kB 0 B
frontend/dist-report/exporter/_parent/products/error_tracking/frontend/scenes/ErrorTrackingIssueScene/ErrorTrackingIssueScene 104 kB 0 B
frontend/dist-report/exporter/_parent/products/error_tracking/frontend/scenes/ErrorTrackingScene/ErrorTrackingScene 27.1 kB 0 B
frontend/dist-report/exporter/_parent/products/feature_flags/frontend/FeatureFlagTemplatesScene 7.35 kB 0 B
frontend/dist-report/exporter/_parent/products/games/368Hedgehogs/368Hedgehogs 5.58 kB 0 B
frontend/dist-report/exporter/_parent/products/games/FlappyHog/FlappyHog 6.09 kB 0 B
frontend/dist-report/exporter/_parent/products/legal_documents/frontend/scenes/LegalDocumentNewScene 59.7 kB 0 B
frontend/dist-report/exporter/_parent/products/legal_documents/frontend/scenes/LegalDocumentsScene 5.28 kB 0 B
frontend/dist-report/exporter/_parent/products/links/frontend/LinkScene 25.2 kB 0 B
frontend/dist-report/exporter/_parent/products/links/frontend/LinksScene 4.51 kB 0 B
frontend/dist-report/exporter/_parent/products/live_debugger/frontend/LiveDebugger 19.4 kB 0 B
frontend/dist-report/exporter/_parent/products/logs/frontend/LogsScene 17.8 kB 0 B
frontend/dist-report/exporter/_parent/products/logs/frontend/scenes/LogsAlertDetailScene/LogsAlertDetailScene 17.3 kB 0 B
frontend/dist-report/exporter/_parent/products/logs/frontend/scenes/LogsSamplingDetailScene/LogsSamplingDetailScene 5.27 kB 0 B
frontend/dist-report/exporter/_parent/products/logs/frontend/scenes/LogsSamplingNewScene/LogsSamplingNewScene 2.22 kB 0 B
frontend/dist-report/exporter/_parent/products/managed_migrations/frontend/ManagedMigration 14.9 kB 0 B
frontend/dist-report/exporter/_parent/products/mcp_analytics/frontend/MCPAnalyticsScene 40.5 kB 0 B
frontend/dist-report/exporter/_parent/products/mcp_analytics/frontend/MCPAnalyticsToolDetail 18.5 kB 0 B
frontend/dist-report/exporter/_parent/products/metrics/frontend/MetricsScene 16.2 kB 0 B
frontend/dist-report/exporter/_parent/products/product_analytics/frontend/insights/stickiness/StickinessBarChart/StickinessBarChart 3.27 kB 0 B
frontend/dist-report/exporter/_parent/products/product_analytics/frontend/insights/stickiness/StickinessLineChart/StickinessLineChart 3.11 kB 0 B
frontend/dist-report/exporter/_parent/products/product_analytics/frontend/insights/trends/TrendsBarChart/TrendsBarChart 7.33 kB +210 B (+2.95%)
frontend/dist-report/exporter/_parent/products/product_analytics/frontend/insights/trends/TrendsLifecycleChart/TrendsLifecycleChart 4.21 kB 0 B
frontend/dist-report/exporter/_parent/products/product_analytics/frontend/insights/trends/TrendsLineChart/TrendsLineChart 4.57 kB 0 B
frontend/dist-report/exporter/_parent/products/product_analytics/frontend/insights/trends/TrendsPieChart/TrendsPieChart 4.31 kB 0 B
frontend/dist-report/exporter/_parent/products/replay_vision/frontend/observations/ReplayObservation 8.13 kB 0 B
frontend/dist-report/exporter/_parent/products/replay_vision/frontend/replay_scanners/ReplayScanner 32.8 kB 0 B
frontend/dist-report/exporter/_parent/products/replay_vision/frontend/replay_scanners/ReplayScannersScene 11.5 kB 0 B
frontend/dist-report/exporter/_parent/products/replay_vision/frontend/replay_scanners/ScannerTemplatesScene 4.56 kB 0 B
frontend/dist-report/exporter/_parent/products/revenue_analytics/frontend/RevenueAnalyticsScene 26.5 kB 0 B
frontend/dist-report/exporter/_parent/products/session_summaries/frontend/SessionGroupSummariesTable 5.02 kB 0 B
frontend/dist-report/exporter/_parent/products/session_summaries/frontend/SessionGroupSummaryScene 19.2 kB 0 B
frontend/dist-report/exporter/_parent/products/tasks/frontend/TaskDetailScene 23.5 kB 0 B
frontend/dist-report/exporter/_parent/products/tasks/frontend/TaskTracker 14.6 kB 0 B
frontend/dist-report/exporter/_parent/products/tracing/frontend/TracingScene 54.4 kB 0 B
frontend/dist-report/exporter/_parent/products/user_interviews/frontend/UserInterview 9.28 kB 0 B
frontend/dist-report/exporter/_parent/products/user_interviews/frontend/UserInterviewResponse 5.64 kB 0 B
frontend/dist-report/exporter/_parent/products/user_interviews/frontend/UserInterviews 6.04 kB 0 B
frontend/dist-report/exporter/_parent/products/visual_review/frontend/scenes/VisualReviewIndexScene 2.52 kB 0 B
frontend/dist-report/exporter/_parent/products/visual_review/frontend/scenes/VisualReviewRunScene 44.6 kB 0 B
frontend/dist-report/exporter/_parent/products/visual_review/frontend/scenes/VisualReviewRunsScene 7.29 kB 0 B
frontend/dist-report/exporter/_parent/products/visual_review/frontend/scenes/VisualReviewSettingsScene 11.1 kB 0 B
frontend/dist-report/exporter/_parent/products/visual_review/frontend/scenes/VisualReviewSnapshotHistoryScene 13.9 kB 0 B
frontend/dist-report/exporter/_parent/products/visual_review/frontend/scenes/VisualReviewSnapshotOverviewScene 19.5 kB 0 B
frontend/dist-report/exporter/_parent/products/workflows/frontend/TemplateLibrary/MessageTemplate 16.6 kB 0 B
frontend/dist-report/exporter/_parent/products/workflows/frontend/Workflows/WorkflowScene 111 kB 0 B
frontend/dist-report/exporter/_parent/products/workflows/frontend/WorkflowsScene 60.1 kB 0 B
frontend/dist-report/exporter/src/exporter/exporter 19.6 kB 0 B
frontend/dist-report/exporter/src/exporter/scenes/ExporterDashboardScene 1.99 kB 0 B
frontend/dist-report/exporter/src/exporter/scenes/ExporterHeatmapScene 19.6 kB 0 B
frontend/dist-report/exporter/src/exporter/scenes/ExporterInsightScene 2.98 kB 0 B
frontend/dist-report/exporter/src/exporter/scenes/ExporterInterviewScene 310 kB 0 B
frontend/dist-report/exporter/src/exporter/scenes/ExporterNotebookScene 2.71 MB 0 B
frontend/dist-report/exporter/src/exporter/scenes/ExporterRecordingScene 1.1 kB 0 B
frontend/dist-report/exporter/src/exporterSharedChunkAnchors 1.19 kB 0 B
frontend/dist-report/exporter/src/lib/components/Cards/TextCard/TextCardMarkdownEditor 11.3 kB 0 B
frontend/dist-report/exporter/src/lib/components/MonacoDiffEditor 471 B 0 B
frontend/dist-report/exporter/src/lib/lemon-ui/LemonMarkdown/MermaidDiagram 2.22 kB 0 B
frontend/dist-report/exporter/src/lib/lemon-ui/LemonTextArea/LemonTextAreaMarkdown 808 B 0 B
frontend/dist-report/exporter/src/lib/lemon-ui/Link/Link 359 B 0 B
frontend/dist-report/exporter/src/lib/monaco/CodeEditorInline 798 B 0 B
frontend/dist-report/exporter/src/lib/monaco/vimMode 211 kB 0 B
frontend/dist-report/exporter/src/lib/ui/Button/ButtonPrimitives 422 B 0 B
frontend/dist-report/exporter/src/queries/nodes/WebVitals/WebVitals 7.48 kB 0 B
frontend/dist-report/exporter/src/queries/nodes/WebVitals/WebVitalsPathBreakdown 4.05 kB 0 B
frontend/dist-report/exporter/src/queries/schema 840 kB 0 B
frontend/dist-report/exporter/src/scenes/approvals/changeRequestsLogic 850 B 0 B
frontend/dist-report/exporter/src/scenes/authentication/passkeyLogic 790 B 0 B
frontend/dist-report/exporter/src/scenes/data-pipelines/event-filtering/EventFilterScene 22.2 kB 0 B
frontend/dist-report/exporter/src/scenes/data-pipelines/TransformationsScene 6.51 kB 0 B
frontend/dist-report/exporter/src/scenes/insights/views/BoxPlot/BoxPlot 5.35 kB 0 B
frontend/dist-report/exporter/src/scenes/insights/views/CalendarHeatMap/CalendarHeatMap 8.81 kB 0 B
frontend/dist-report/exporter/src/scenes/insights/views/RegionMap/RegionMap 29.7 kB 0 B
frontend/dist-report/exporter/src/scenes/insights/views/WorldMap/WorldMap 1.04 MB 0 B
frontend/dist-report/exporter/src/scenes/models/ModelsScene 19 kB 0 B
frontend/dist-report/exporter/src/scenes/models/NodeDetailScene 17 kB 0 B
frontend/dist-report/monaco-editor-worker/src/lib/monaco/workers/monacoEditorWorker 288 kB 0 B
frontend/dist-report/monaco-json-worker/src/lib/monaco/workers/monacoJsonWorker 419 kB 0 B
frontend/dist-report/monaco-typescript-worker/src/lib/monaco/workers/monacoTsWorker 7.02 MB 0 B
frontend/dist-report/posthog-app/_parent/products/actions/frontend/pages/Action 25.1 kB 0 B
frontend/dist-report/posthog-app/_parent/products/actions/frontend/pages/Actions 1.36 kB 0 B
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/AIObservabilityScene 119 kB 0 B
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/AIObservabilitySessionScene 18.4 kB 0 B
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/AIObservabilityTraceScene 130 kB 0 B
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/AIObservabilityUsers 872 B 0 B
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/clusters/AIObservabilityClusterScene 21.7 kB 0 B
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/clusters/AIObservabilityClustersScene 55.1 kB 0 B
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/datasets/AIObservabilityDatasetScene 21 kB 0 B
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/datasets/AIObservabilityDatasetsScene 3.64 kB 0 B
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/evaluations/AIObservabilityEvaluation 59.9 kB 0 B
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/evaluations/AIObservabilityEvaluationsScene 28.2 kB 0 B
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/evaluations/EvaluationTemplates 915 B 0 B
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/LLMASessionFeedbackDisplay 5.19 kB 0 B
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/playground/AIObservabilityPlaygroundScene 37.8 kB 0 B
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/prompts/LLMPromptScene 29.2 kB 0 B
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/prompts/LLMPromptsScene 4.83 kB 0 B
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/skills/LLMSkillScene 929 B 0 B
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/skills/LLMSkillsScene 946 B 0 B
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/tags/AIObservabilityTag 27.4 kB 0 B
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/tags/AIObservabilityTagsScene 7.31 kB 0 B
frontend/dist-report/posthog-app/_parent/products/business_knowledge/frontend/scenes/BusinessKnowledgeScene 19 kB 0 B
frontend/dist-report/posthog-app/_parent/products/conversations/frontend/components/Assignee/CyclotronJobInputAssignee 1.67 kB 0 B
frontend/dist-report/posthog-app/_parent/products/conversations/frontend/components/SlaBusinessHours/CyclotronJobInputBusinessHours 3.06 kB 0 B
frontend/dist-report/posthog-app/_parent/products/conversations/frontend/components/TicketTags/CyclotronJobInputTicketTags 1.06 kB 0 B
frontend/dist-report/posthog-app/_parent/products/conversations/frontend/scenes/settings/SupportSettingsScene 1.82 kB 0 B
frontend/dist-report/posthog-app/_parent/products/conversations/frontend/scenes/ticket/SupportTicketScene 26.5 kB 0 B
frontend/dist-report/posthog-app/_parent/products/conversations/frontend/scenes/tickets/SupportTicketsScene 1.07 kB 0 B
frontend/dist-report/posthog-app/_parent/products/customer_analytics/frontend/CustomerAnalyticsScene 38 kB 0 B
frontend/dist-report/posthog-app/_parent/products/customer_analytics/frontend/scenes/CustomerAnalyticsConfigurationScene/CustomerAnalyticsConfigurationScene 2.65 kB 0 B
frontend/dist-report/posthog-app/_parent/products/customer_analytics/frontend/scenes/CustomerJourneyBuilderScene/CustomerJourneyBuilderScene 2.18 kB 0 B
frontend/dist-report/posthog-app/_parent/products/customer_analytics/frontend/scenes/CustomerJourneyTemplatesScene/CustomerJourneyTemplatesScene 7.86 kB 0 B
frontend/dist-report/posthog-app/_parent/products/data_warehouse/DataWarehouseScene 1.78 kB 0 B
frontend/dist-report/posthog-app/_parent/products/data_warehouse/frontend/scenes/NewSourceScene/NewSourceScene 1.15 kB 0 B
frontend/dist-report/posthog-app/_parent/products/data_warehouse/frontend/scenes/SchemaScene/SchemaScene 24.1 kB 0 B
frontend/dist-report/posthog-app/_parent/products/data_warehouse/frontend/scenes/SourceScene/SourceScene 1.06 kB 0 B
frontend/dist-report/posthog-app/_parent/products/data_warehouse/frontend/scenes/SourcesScene/SourcesScene 6.31 kB 0 B
frontend/dist-report/posthog-app/_parent/products/deployments/frontend/Deployment 4.05 kB 0 B
frontend/dist-report/posthog-app/_parent/products/deployments/frontend/DeploymentProject 5.58 kB 0 B
frontend/dist-report/posthog-app/_parent/products/deployments/frontend/Deployments 9.31 kB 0 B
frontend/dist-report/posthog-app/_parent/products/early_access_features/frontend/EarlyAccessFeature 1.16 kB 0 B
frontend/dist-report/posthog-app/_parent/products/early_access_features/frontend/EarlyAccessFeatures 3.24 kB 0 B
frontend/dist-report/posthog-app/_parent/products/endpoints/frontend/EndpointScene 40.7 kB 0 B
frontend/dist-report/posthog-app/_parent/products/endpoints/frontend/EndpointsScene 22.4 kB 0 B
frontend/dist-report/posthog-app/_parent/products/error_tracking/frontend/scenes/ErrorTrackingFingerprintsScene/ErrorTrackingIssueFingerprintsScene 7.44 kB 0 B
frontend/dist-report/posthog-app/_parent/products/error_tracking/frontend/scenes/ErrorTrackingIssueScene/ErrorTrackingIssueScene 103 kB 0 B
frontend/dist-report/posthog-app/_parent/products/error_tracking/frontend/scenes/ErrorTrackingScene/ErrorTrackingScene 27.2 kB 0 B
frontend/dist-report/posthog-app/_parent/products/feature_flags/frontend/FeatureFlagTemplatesScene 7.38 kB 0 B
frontend/dist-report/posthog-app/_parent/products/games/368Hedgehogs/368Hedgehogs 5.61 kB 0 B
frontend/dist-report/posthog-app/_parent/products/games/FlappyHog/FlappyHog 6.12 kB 0 B
frontend/dist-report/posthog-app/_parent/products/legal_documents/frontend/scenes/LegalDocumentNewScene 59.7 kB 0 B
frontend/dist-report/posthog-app/_parent/products/legal_documents/frontend/scenes/LegalDocumentsScene 5.32 kB 0 B
frontend/dist-report/posthog-app/_parent/products/links/frontend/LinkScene 25.2 kB 0 B
frontend/dist-report/posthog-app/_parent/products/links/frontend/LinksScene 4.55 kB 0 B
frontend/dist-report/posthog-app/_parent/products/live_debugger/frontend/LiveDebugger 19.5 kB 0 B
frontend/dist-report/posthog-app/_parent/products/logs/frontend/LogsScene 17.8 kB 0 B
frontend/dist-report/posthog-app/_parent/products/logs/frontend/scenes/LogsAlertDetailScene/LogsAlertDetailScene 17.3 kB 0 B
frontend/dist-report/posthog-app/_parent/products/logs/frontend/scenes/LogsSamplingDetailScene/LogsSamplingDetailScene 5.31 kB 0 B
frontend/dist-report/posthog-app/_parent/products/logs/frontend/scenes/LogsSamplingNewScene/LogsSamplingNewScene 2.26 kB 0 B
frontend/dist-report/posthog-app/_parent/products/managed_migrations/frontend/ManagedMigration 14.9 kB 0 B
frontend/dist-report/posthog-app/_parent/products/mcp_analytics/frontend/MCPAnalyticsScene 40.5 kB 0 B
frontend/dist-report/posthog-app/_parent/products/mcp_analytics/frontend/MCPAnalyticsToolDetail 18.5 kB 0 B
frontend/dist-report/posthog-app/_parent/products/metrics/frontend/MetricsScene 16.2 kB 0 B
frontend/dist-report/posthog-app/_parent/products/product_analytics/frontend/insights/stickiness/StickinessBarChart/StickinessBarChart 3.31 kB 0 B
frontend/dist-report/posthog-app/_parent/products/product_analytics/frontend/insights/stickiness/StickinessLineChart/StickinessLineChart 3.14 kB 0 B
frontend/dist-report/posthog-app/_parent/products/product_analytics/frontend/insights/trends/TrendsBarChart/TrendsBarChart 7.36 kB +210 B (+2.94%)
frontend/dist-report/posthog-app/_parent/products/product_analytics/frontend/insights/trends/TrendsLifecycleChart/TrendsLifecycleChart 4.24 kB 0 B
frontend/dist-report/posthog-app/_parent/products/product_analytics/frontend/insights/trends/TrendsLineChart/TrendsLineChart 4.6 kB 0 B
frontend/dist-report/posthog-app/_parent/products/product_analytics/frontend/insights/trends/TrendsPieChart/TrendsPieChart 4.35 kB 0 B
frontend/dist-report/posthog-app/_parent/products/replay_vision/frontend/observations/ReplayObservation 8.17 kB 0 B
frontend/dist-report/posthog-app/_parent/products/replay_vision/frontend/replay_scanners/ReplayScanner 32.9 kB 0 B
frontend/dist-report/posthog-app/_parent/products/replay_vision/frontend/replay_scanners/ReplayScannersScene 11.6 kB 0 B
frontend/dist-report/posthog-app/_parent/products/replay_vision/frontend/replay_scanners/ScannerTemplatesScene 4.59 kB 0 B
frontend/dist-report/posthog-app/_parent/products/revenue_analytics/frontend/RevenueAnalyticsScene 26.6 kB 0 B
frontend/dist-report/posthog-app/_parent/products/session_summaries/frontend/SessionGroupSummariesTable 5.05 kB 0 B
frontend/dist-report/posthog-app/_parent/products/session_summaries/frontend/SessionGroupSummaryScene 19.2 kB 0 B
frontend/dist-report/posthog-app/_parent/products/tasks/frontend/TaskDetailScene 23.6 kB 0 B
frontend/dist-report/posthog-app/_parent/products/tasks/frontend/TaskTracker 14.6 kB 0 B
frontend/dist-report/posthog-app/_parent/products/tracing/frontend/TracingScene 54.4 kB 0 B
frontend/dist-report/posthog-app/_parent/products/user_interviews/frontend/UserInterview 9.32 kB 0 B
frontend/dist-report/posthog-app/_parent/products/user_interviews/frontend/UserInterviewResponse 5.68 kB 0 B
frontend/dist-report/posthog-app/_parent/products/user_interviews/frontend/UserInterviews 6.08 kB 0 B
frontend/dist-report/posthog-app/_parent/products/visual_review/frontend/scenes/VisualReviewIndexScene 2.56 kB 0 B
frontend/dist-report/posthog-app/_parent/products/visual_review/frontend/scenes/VisualReviewRunScene 44.7 kB 0 B
frontend/dist-report/posthog-app/_parent/products/visual_review/frontend/scenes/VisualReviewRunsScene 7.32 kB 0 B
frontend/dist-report/posthog-app/_parent/products/visual_review/frontend/scenes/VisualReviewSettingsScene 11.1 kB 0 B
frontend/dist-report/posthog-app/_parent/products/visual_review/frontend/scenes/VisualReviewSnapshotHistoryScene 13.9 kB 0 B
frontend/dist-report/posthog-app/_parent/products/visual_review/frontend/scenes/VisualReviewSnapshotOverviewScene 19.6 kB 0 B
frontend/dist-report/posthog-app/_parent/products/workflows/frontend/TemplateLibrary/MessageTemplate 16.6 kB 0 B
frontend/dist-report/posthog-app/_parent/products/workflows/frontend/Workflows/WorkflowScene 104 kB 0 B
frontend/dist-report/posthog-app/_parent/products/workflows/frontend/WorkflowsScene 60.2 kB 0 B
frontend/dist-report/posthog-app/src/index 61.1 kB 0 B
frontend/dist-report/posthog-app/src/layout/panel-layout/ai-first/tabs/NavTabChat 7.16 kB 0 B
frontend/dist-report/posthog-app/src/lib/components/Cards/TextCard/TextCardMarkdownEditor 11.3 kB 0 B
frontend/dist-report/posthog-app/src/lib/components/MonacoDiffEditor 471 B 0 B
frontend/dist-report/posthog-app/src/lib/lemon-ui/LemonMarkdown/MermaidDiagram 2.25 kB 0 B
frontend/dist-report/posthog-app/src/lib/lemon-ui/LemonTextArea/LemonTextAreaMarkdown 842 B 0 B
frontend/dist-report/posthog-app/src/lib/lemon-ui/Link/Link 359 B 0 B
frontend/dist-report/posthog-app/src/lib/monaco/CodeEditorInline 832 B 0 B
frontend/dist-report/posthog-app/src/lib/monaco/vimMode 211 kB 0 B
frontend/dist-report/posthog-app/src/lib/ui/Button/ButtonPrimitives 426 B 0 B
frontend/dist-report/posthog-app/src/queries/nodes/WebVitals/WebVitals 7.52 kB 0 B
frontend/dist-report/posthog-app/src/queries/nodes/WebVitals/WebVitalsPathBreakdown 4.09 kB 0 B
frontend/dist-report/posthog-app/src/queries/schema 840 kB 0 B
frontend/dist-report/posthog-app/src/scenes/activity/explore/EventsScene 3.28 kB 0 B
frontend/dist-report/posthog-app/src/scenes/activity/explore/SessionsScene 4.69 kB 0 B
frontend/dist-report/posthog-app/src/scenes/activity/live/LiveEventsTable 5.58 kB 0 B
frontend/dist-report/posthog-app/src/scenes/agentic/AgenticAuthorize 5.84 kB 0 B
frontend/dist-report/posthog-app/src/scenes/approvals/ApprovalDetail 16.6 kB 0 B
frontend/dist-report/posthog-app/src/scenes/approvals/changeRequestsLogic 884 B 0 B
frontend/dist-report/posthog-app/src/scenes/audit-logs/AdvancedActivityLogsScene 42.1 kB 0 B
frontend/dist-report/posthog-app/src/scenes/AuthenticatedShell 165 kB 0 B
frontend/dist-report/posthog-app/src/scenes/authentication/AccountConnected 3.33 kB 0 B
frontend/dist-report/posthog-app/src/scenes/authentication/AgenticAccountMismatch 2.73 kB 0 B
frontend/dist-report/posthog-app/src/scenes/authentication/CLIAuthorize 11.7 kB 0 B
frontend/dist-report/posthog-app/src/scenes/authentication/CLILive 4.37 kB 0 B
frontend/dist-report/posthog-app/src/scenes/authentication/credential-review/CredentialReview 3.95 kB 0 B
frontend/dist-report/posthog-app/src/scenes/authentication/EmailMFAVerify 3.37 kB 0 B
frontend/dist-report/posthog-app/src/scenes/authentication/InviteSignup 15.4 kB 0 B
frontend/dist-report/posthog-app/src/scenes/authentication/Login 10.2 kB 0 B
frontend/dist-report/posthog-app/src/scenes/authentication/Login2FA 5.08 kB 0 B
frontend/dist-report/posthog-app/src/scenes/authentication/passkeyLogic 824 B 0 B
frontend/dist-report/posthog-app/src/scenes/authentication/PasswordReset 4.71 kB 0 B
frontend/dist-report/posthog-app/src/scenes/authentication/PasswordResetComplete 3.34 kB 0 B
frontend/dist-report/posthog-app/src/scenes/authentication/signup/SignupContainer 28.5 kB 0 B
frontend/dist-report/posthog-app/src/scenes/authentication/signup/verify-email/VerifyEmail 5.13 kB 0 B
frontend/dist-report/posthog-app/src/scenes/authentication/TwoFactorReset 4.37 kB 0 B
frontend/dist-report/posthog-app/src/scenes/authentication/VercelConnect 5.33 kB 0 B
frontend/dist-report/posthog-app/src/scenes/authentication/VercelLinkError 2.61 kB 0 B
frontend/dist-report/posthog-app/src/scenes/billing/AuthorizationStatus 1.07 kB 0 B
frontend/dist-report/posthog-app/src/scenes/billing/Billing 833 B 0 B
frontend/dist-report/posthog-app/src/scenes/billing/BillingSection 21.1 kB 0 B
frontend/dist-report/posthog-app/src/scenes/cohorts/Cohort 28.4 kB 0 B
frontend/dist-report/posthog-app/src/scenes/cohorts/CohortCalculationHistory 6.58 kB 0 B
frontend/dist-report/posthog-app/src/scenes/cohorts/Cohorts 9.78 kB 0 B
frontend/dist-report/posthog-app/src/scenes/coupons/Coupons 1.06 kB 0 B
frontend/dist-report/posthog-app/src/scenes/dashboard/Dashboard 1.65 kB 0 B
frontend/dist-report/posthog-app/src/scenes/dashboard/dashboards/Dashboards 19.8 kB 0 B
frontend/dist-report/posthog-app/src/scenes/dashboard/dashboards/templates/DashboardTemplateCopyScene 6.06 kB 0 B
frontend/dist-report/posthog-app/src/scenes/data-management/DataManagementScene 986 B 0 B
frontend/dist-report/posthog-app/src/scenes/data-management/definition/DefinitionEdit 17.2 kB 0 B
frontend/dist-report/posthog-app/src/scenes/data-management/definition/DefinitionView 24.4 kB 0 B
frontend/dist-report/posthog-app/src/scenes/data-management/MaterializedColumns/MaterializedColumns 12 kB 0 B
frontend/dist-report/posthog-app/src/scenes/data-management/variables/SqlVariableEditScene 7.6 kB 0 B
frontend/dist-report/posthog-app/src/scenes/data-pipelines/batch-exports/BatchExportScene 61 kB 0 B
frontend/dist-report/posthog-app/src/scenes/data-pipelines/DataPipelinesNewScene 2.66 kB 0 B
frontend/dist-report/posthog-app/src/scenes/data-pipelines/DestinationsScene 3.03 kB 0 B
frontend/dist-report/posthog-app/src/scenes/data-pipelines/event-filtering/EventFilterScene 22.2 kB 0 B
frontend/dist-report/posthog-app/src/scenes/data-pipelines/legacy-plugins/LegacyPluginScene 21 kB 0 B
frontend/dist-report/posthog-app/src/scenes/data-pipelines/TransformationsScene 2.27 kB 0 B
frontend/dist-report/posthog-app/src/scenes/data-pipelines/WebScriptsScene 2.89 kB 0 B
frontend/dist-report/posthog-app/src/scenes/data-warehouse/DataWarehouseScene 1.72 kB 0 B
frontend/dist-report/posthog-app/src/scenes/data-warehouse/editor/EditorScene 1.48 kB 0 B
frontend/dist-report/posthog-app/src/scenes/debug/DebugScene 20.3 kB 0 B
frontend/dist-report/posthog-app/src/scenes/debug/hog/HogRepl 7.72 kB 0 B
frontend/dist-report/posthog-app/src/scenes/experiments/Experiment 207 kB 0 B
frontend/dist-report/posthog-app/src/scenes/experiments/Experiments 20.8 kB 0 B
frontend/dist-report/posthog-app/src/scenes/experiments/SharedMetrics/SharedMetric 6.41 kB 0 B
frontend/dist-report/posthog-app/src/scenes/experiments/SharedMetrics/SharedMetrics 889 B 0 B
frontend/dist-report/posthog-app/src/scenes/exports/ExportsScene 4.33 kB 0 B
frontend/dist-report/posthog-app/src/scenes/feature-flags/FeatureFlag 146 kB 0 B
frontend/dist-report/posthog-app/src/scenes/feature-flags/FeatureFlags 1.08 kB 0 B
frontend/dist-report/posthog-app/src/scenes/groups/Group 15.5 kB 0 B
frontend/dist-report/posthog-app/src/scenes/groups/Groups 4.26 kB 0 B
frontend/dist-report/posthog-app/src/scenes/groups/GroupsNew 7.7 kB 0 B
frontend/dist-report/posthog-app/src/scenes/health-alerts/HealthAlertsScene 4.14 kB 0 B
frontend/dist-report/posthog-app/src/scenes/health/categoryDetail/HealthCategoryDetailScene 7.6 kB 0 B
frontend/dist-report/posthog-app/src/scenes/health/HealthScene 12.7 kB 0 B
frontend/dist-report/posthog-app/src/scenes/health/pipelineStatus/PipelineStatusScene 11.5 kB 0 B
frontend/dist-report/posthog-app/src/scenes/heatmaps/scenes/heatmap/HeatmapNewScene 5.38 kB 0 B
frontend/dist-report/posthog-app/src/scenes/heatmaps/scenes/heatmap/HeatmapRecordingScene 4.27 kB 0 B
frontend/dist-report/posthog-app/src/scenes/heatmaps/scenes/heatmap/HeatmapScene 6.91 kB 0 B
frontend/dist-report/posthog-app/src/scenes/heatmaps/scenes/heatmaps/HeatmapsScene 4.23 kB 0 B
frontend/dist-report/posthog-app/src/scenes/hog-functions/HogFunctionScene 59.6 kB 0 B
frontend/dist-report/posthog-app/src/scenes/inbox/InboxScene 63.3 kB 0 B
frontend/dist-report/posthog-app/src/scenes/insights/InsightQuickStart/InsightQuickStart 5.77 kB 0 B
frontend/dist-report/posthog-app/src/scenes/insights/InsightScene 34.8 kB 0 B
frontend/dist-report/posthog-app/src/scenes/insights/views/BoxPlot/BoxPlot 5.39 kB 0 B
frontend/dist-report/posthog-app/src/scenes/insights/views/CalendarHeatMap/CalendarHeatMap 4.84 kB 0 B
frontend/dist-report/posthog-app/src/scenes/insights/views/RegionMap/RegionMap 29.8 kB 0 B
frontend/dist-report/posthog-app/src/scenes/insights/views/WorldMap/WorldMap 5.13 kB 0 B
frontend/dist-report/posthog-app/src/scenes/instance/AsyncMigrations/AsyncMigrations 13.5 kB 0 B
frontend/dist-report/posthog-app/src/scenes/instance/DeadLetterQueue/DeadLetterQueue 5.74 kB 0 B
frontend/dist-report/posthog-app/src/scenes/instance/QueryPerformance/QueryPerformance 8.97 kB 0 B
frontend/dist-report/posthog-app/src/scenes/instance/SystemStatus/SystemStatus 17.4 kB 0 B
frontend/dist-report/posthog-app/src/scenes/IntegrationsRedirect/IntegrationsRedirect 1.08 kB 0 B
frontend/dist-report/posthog-app/src/scenes/marketing-analytics/MarketingAnalyticsScene 42 kB 0 B
frontend/dist-report/posthog-app/src/scenes/max/Max 1.02 kB 0 B
frontend/dist-report/posthog-app/src/scenes/models/ModelsScene 19 kB 0 B
frontend/dist-report/posthog-app/src/scenes/models/NodeDetailScene 17.1 kB 0 B
frontend/dist-report/posthog-app/src/scenes/moveToPostHogCloud/MoveToPostHogCloud 4.81 kB 0 B
frontend/dist-report/posthog-app/src/scenes/new-tab/NewTabScene 1.82 kB 0 B
frontend/dist-report/posthog-app/src/scenes/notebooks/NotebookCanvasScene 3.89 kB 0 B
frontend/dist-report/posthog-app/src/scenes/notebooks/NotebookPanel/NotebookPanel 5.94 kB 0 B
frontend/dist-report/posthog-app/src/scenes/notebooks/NotebookScene 9.26 kB 0 B
frontend/dist-report/posthog-app/src/scenes/notebooks/NotebooksScene 7.95 kB 0 B
frontend/dist-report/posthog-app/src/scenes/oauth/OAuthAuthorize 980 B 0 B
frontend/dist-report/posthog-app/src/scenes/onboarding/coupon/OnboardingCouponRedemption 1.55 kB 0 B
frontend/dist-report/posthog-app/src/scenes/onboarding/Onboarding 791 kB 0 B
frontend/dist-report/posthog-app/src/scenes/onboarding/sdks/SdkDoctorScene 10.2 kB 0 B
frontend/dist-report/posthog-app/src/scenes/organization/ConfirmOrganization/ConfirmOrganization 4.88 kB 0 B
frontend/dist-report/posthog-app/src/scenes/organization/Create/Create 1 kB 0 B
frontend/dist-report/posthog-app/src/scenes/organization/Deactivated 1.48 kB 0 B
frontend/dist-report/posthog-app/src/scenes/organization/PendingDeletion 2.45 kB 0 B
frontend/dist-report/posthog-app/src/scenes/persons/PersonScene 19 kB 0 B
frontend/dist-report/posthog-app/src/scenes/persons/PersonsScene 6.09 kB 0 B
frontend/dist-report/posthog-app/src/scenes/PreflightCheck/PreflightCheck 5.91 kB 0 B
frontend/dist-report/posthog-app/src/scenes/product-tours/ProductTour 275 kB 0 B
frontend/dist-report/posthog-app/src/scenes/product-tours/ProductTours 5.03 kB 0 B
frontend/dist-report/posthog-app/src/scenes/project-homepage/ProjectHomepage 18.4 kB 0 B
frontend/dist-report/posthog-app/src/scenes/project/Create/Create 1.18 kB 0 B
frontend/dist-report/posthog-app/src/scenes/resource-transfer/ResourceTransfer 9.53 kB 0 B
frontend/dist-report/posthog-app/src/scenes/saved-insights/SavedInsights 1 kB 0 B
frontend/dist-report/posthog-app/src/scenes/session-recordings/detail/SessionRecordingDetail 2.1 kB 0 B
frontend/dist-report/posthog-app/src/scenes/session-recordings/file-playback/SessionRecordingFilePlaybackScene 4.82 kB 0 B
frontend/dist-report/posthog-app/src/scenes/session-recordings/kiosk/SessionRecordingsKiosk 10.3 kB 0 B
frontend/dist-report/posthog-app/src/scenes/session-recordings/player/snapshot-processing/DecompressionWorkerManager 329 B 0 B
frontend/dist-report/posthog-app/src/scenes/session-recordings/playlist/SessionRecordingsPlaylistScene 5.45 kB 0 B
frontend/dist-report/posthog-app/src/scenes/session-recordings/SessionRecordings 1.12 kB 0 B
frontend/dist-report/posthog-app/src/scenes/session-recordings/settings/SessionRecordingsSettingsScene 2.31 kB 0 B
frontend/dist-report/posthog-app/src/scenes/sessions/SessionProfileScene 15.4 kB 0 B
frontend/dist-report/posthog-app/src/scenes/settings/SettingsScene 3.9 kB 0 B
frontend/dist-report/posthog-app/src/scenes/sites/Site 1.53 kB 0 B
frontend/dist-report/posthog-app/src/scenes/startups/StartupProgram 21.5 kB 0 B
frontend/dist-report/posthog-app/src/scenes/StripeConfirmInstall/StripeConfirmInstall 3.88 kB 0 B
frontend/dist-report/posthog-app/src/scenes/subscriptions/SubscriptionScene 14.4 kB 0 B
frontend/dist-report/posthog-app/src/scenes/subscriptions/SubscriptionsScene 5.2 kB 0 B
frontend/dist-report/posthog-app/src/scenes/surveys/forms/SurveyFormBuilder 1.89 kB 0 B
frontend/dist-report/posthog-app/src/scenes/surveys/Survey 1.36 kB 0 B
frontend/dist-report/posthog-app/src/scenes/surveys/Surveys 26.7 kB 0 B
frontend/dist-report/posthog-app/src/scenes/surveys/wizard/SurveyWizard 72.7 kB 0 B
frontend/dist-report/posthog-app/src/scenes/themes/CustomCssScene 3.91 kB 0 B
frontend/dist-report/posthog-app/src/scenes/toolbar-launch/ToolbarLaunch 2.82 kB 0 B
frontend/dist-report/posthog-app/src/scenes/Unsubscribe/Unsubscribe 2 kB 0 B
frontend/dist-report/posthog-app/src/scenes/web-analytics/SessionAttributionExplorer/SessionAttributionExplorerScene 6.97 kB 0 B
frontend/dist-report/posthog-app/src/scenes/web-analytics/WebAnalyticsScene 13.2 kB 0 B
frontend/dist-report/posthog-app/src/scenes/wizard/Wizard 4.8 kB 0 B
frontend/dist-report/posthog-app/src/sharedChunkAnchors 1.19 kB 0 B
frontend/dist-report/toolbar/src/toolbar/toolbar 15.7 MB 0 B

compressed-size-action

@sampennington sampennington changed the title fix(insights): darken horizontal bar hover color fix(insights): tighten horizontal bar hover highlight May 28, 2026
@sampennington sampennington force-pushed the sam/horizontal-bar-hover-color branch from 06a52d7 to 445e13a Compare May 28, 2026 20:59
@sampennington sampennington changed the title fix(insights): tighten horizontal bar hover highlight fix(insights): aggregated trends bars collapse on duplicate labels May 28, 2026
@sampennington sampennington force-pushed the sam/horizontal-bar-hover-color branch from 445e13a to 9da7914 Compare May 28, 2026 21:12
@posthog
Copy link
Copy Markdown
Contributor

posthog Bot commented May 28, 2026

👋 Visual changes detected for this PR.

Review and approve in PostHog Visual Review

If these changes are unexpected, they may be caused by a flaky test or a broken snapshot on master. Don't approve — rerun the job or wait for a fix.

@sampennington sampennington changed the title fix(insights): aggregated trends bars collapse on duplicate labels fix(insights): split aggregated bar bands per series May 28, 2026
@sampennington sampennington reopened this May 28, 2026
sampennington and others added 5 commits May 29, 2026 00:22
`buildTrendsBarAggregatedSeries` used the display label as the
d3.scaleBand domain key. Multiple trends series of the same event
(e.g. four \"\$pageview\" series with no breakdown) all collapsed onto
one band slot, so the sparse-stacked layout drew every series at the
same position and only the largest bar was visible. Hover
iter-by-band then picked highlights from non-visible series,
producing the \"purple bar turns blue\" effect.

Suffix the band key with the series identifier (action.order, or the
top-level `order` field formula-mode rows carry) so:

  - Different series with the same label get their own band (the four
    \$pageview case shows four rows).
  - Breakdown rows of one series share the same id and keep collapsing
    onto one band (formula + breakdown still renders as one row per
    formula, with the existing overlap-on-larger-bar visual intact).

Display labels are returned separately and wired through the
horizontal axis tick formatter, with repeats suppressed so the shared
band doesn't render the same text on top of itself.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Horizontal bar charts with many bands previously crushed every row
into a 5-pixel strip — tick labels and bars both became unreadable.
Mirror the legacy ActionsHorizontalBar's `beforeFit` height behaviour:
enforce a default 24 px per row, grow the chart's wrapper minHeight to
`uniqueBands * minBandSize + chart margins`, and let the outer scene
scroll vertically when content overflows.

Expose `BarChartConfig.minBandSize` so consumers can override or
opt out (pass `0`).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
drawHover filtered candidate bars with `barContainsPointOnBandAxis`,
which only checks the categorical axis. Stacked segments share that
slot, so every series in the hovered row passed the check and all got
darkened. The last-drawn (typically biggest) bar then painted its
darkened color over every smaller segment — hovering a small green
segment made the whole row read as the blue series.

For stacked/percent, require full-rect containment so only the
segment under the cursor is highlighted. Grouped keeps the band-axis
check so cursor-above-bar still narrows correctly — covered by the
existing `grouped layout still narrows when the cursor is above every
bar` test.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sparse-stacked aggregated bars overlap at the value-axis baseline:
static paints largest-first, so each bar's visible slice is the region
between the next-smaller bar's far edge and its own. The old
band-axis-only hit-test darkened every overlapping bar, and the largest
re-painted the whole row on hover.

- Add `findVisibleStackedSegment` that walks every dataIndex sharing
  the hovered band and returns the last-painted (smallest) bar
  whose rect contains the cursor.
- `drawHover` clips the highlight rect to that segment's slice so
  z-order doesn't shift on hover.
- `BarTooltip` uses the same helper to put the visible segment at
  `seriesData[0]` and re-reads its value at its own dataIndex (the
  sparse cell at `ctx.dataIndex` would have been 0).
- Tests cover small/mid/big visible slices with both series and
  value assertions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The aggregated TrendsBarChart was filtering tooltip rows by
`data[ctx.dataIndex] !== 0` — for sparse-stacked overlap that picks
whichever series owns the hovered dataIndex, which is rarely the
segment the cursor is actually over.

- Take `seriesData.slice(0, 1)` instead. BarTooltip already put the
  visible segment at index 0 (with its value re-read at its own
  dataIndex).
- Add an integration test asserting the tooltip on a breakdown surfaces
  that breakdown's label and value, not 0 or the wrong row.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@sampennington sampennington force-pushed the sam/horizontal-bar-hover-color branch from 5971cb8 to d6d93da Compare May 28, 2026 23:22
Copy link
Copy Markdown
Contributor Author

@sampennington sampennington left a comment

Choose a reason for hiding this comment

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

🤖 Automated review

Verdict: Needs changes

Main blocker: the click path doesn't yet have the tooltip's fix applied. On formula+breakdown shapes the tooltip will say row X but the persons modal opens row Y. Same bug shape as the tooltip-value fix — same mirror needed in resolveClickedStackedSegment and the two trends consumers. After that lands, ship it: the rest is small.

Non-anchored findings

Critical: click routing in sparse-stacked overlap (3 callsites, all on unchanged lines)

  • frontend/src/lib/hog-charts/charts/BarChart/BarChart.tsx:594 resolveClickedStackedSegment (hog-charts) — still calls resolveBarsAtCursor with dataIndex: clickData.dataIndex (band index). For shared bands the visible segment lives at a different dataIndex. The rewrite to clickData.series is correct as far as it goes, but clickData.dataIndex is left pointing at the band. Apply the same findVisibleStackedSegment walk and rewrite both clickData.dataIndex and clickData.value.
  • products/product_analytics/frontend/insights/trends/TrendsBarChart/TrendsBarChart.tsx:259 onPointClick (code-reviewer, hog-charts)handleTrendsBarAggregatedChartClick(clickData.dataIndex, …) dispatches the persons modal for whichever row owns the band index, not the visible segment. Use clickData.seriesIndex (the visible series's row index) instead, mirroring the tooltip-value fix.
  • products/product_analytics/frontend/insights/trends/TrendsBarChart/TrendsBarChart.tsx:279 tooltip onRowClick (code-reviewer, hog-charts) — same shape, datum.dataIndex traces back to context.dataIndex (band), not the visible segment.

Should Fix

  • Missing regression test for the click path on shared bands (code-reviewer, hog-charts)TrendsBarChart.test.tsx covers tooltip text only. Add a personsModal.expectOpened(...) test for clicking the visible segment on a formula+breakdown band.
  • Missing tests for BarChartConfig.minBandSize (hog-charts) — public API + DOM-shape change has zero coverage. At minimum: minBandSize: 0 opts out; horizontal default of 24 grows wrapper; vertical never wraps.
  • TooltipContext.seriesData[].value semantics drift from ctx.dataIndex for stacked layouts (hog-charts)BarTooltip.tsx now re-reads value at visibleDataIndexctx.dataIndex. Consumers reading both (the trends adapter) see an undocumented contract mismatch. Either add entry.dataIndex per entry, or update ctx.dataIndex itself.

Performance / Suggestions

  • findVisibleStackedSegment runs twice per mousemove (drawHover + BarTooltip). Same inputs, same answer. Consolidate via _private on ChartScales or a hover-context cache. (efficiency, hog-charts)
  • Extract clipBarToSlice and findNextSmallerStackedExtent helpers into utils/bars-under-cursor.ts. (reuse, quality)
  • Hoist the static portion of the wrapper style to Tailwind (flex flex-col flex-1), keep only minHeight inline. (react)
  • Extract buildDedupedTickFormatter out of TrendsBarChart.aggregatedConfig's memo. (quality)
  • narrowSeriesByCursor has 7 positional args — convert to options object. (quality)

Nits — comment cleanups (personal)

  • BarChart.test.tsx:21 // Value scale [0, 100] (already nice). — narrates the next line.
  • TrendsBarChart.test.tsx:409-410 regression-history comment ("used to read at ctx.dataIndex…") — belongs in commit message.
  • TrendsBarChart.test.tsx:420 ("Spike has aggregated_value 11 — largest…") — restates the assertion.

Positive

  • Clean separation of displayLabels (humans) and synthetic __seriesId band keys (d3) — right seam.
  • New parameterized transform tests cleanly enumerate the band-keying rules.
  • xTickFormatter skip-repeats lives in the adapter, not the library — keeps hog-charts core formatter-agnostic.
  • findVisibleStackedSegment composes iterBarsAtCursor instead of reimplementing it.
  • New TrendsBarChart.test.tsx integration test pins the original 0-value regression with a real query path.

Reviewers: code-reviewer, react, personal, reuse, quality, efficiency, hog-charts. Inline comments below are tagged with the reviewer that raised them and the level of concern.

)

if (wrapperMinHeight === undefined) {
return chart
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤖 [hog-charts] · Should Fix

Returning bare chart vs <div>{chart}</div> based on wrapperMinHeight means toggling axisOrientation (or transitioning to/from no labels) changes the DOM tree shape, which causes React to unmount the inner Chart. That blows away the canvas, the scales memo, any pinned tooltip, and the hover-fade ref. Cheap fix: always wrap; pass minHeight: undefined when not needed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in a772a0247a8 — wrapper is now unconditional with flex flex-col flex-1 Tailwind classes, only minHeight is inline.

// the wrapper grows and the outer scene scrolls. Margin matches DEFAULT_MARGINS + axis
// title floor in useChartMargins.
const HORIZONTAL_MIN_BAND_SIZE_DEFAULT = 24
const HORIZONTAL_CHART_MARGIN_PX = 64
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤖 [react+quality+hog-charts] · Should Fix

HORIZONTAL_MIN_BAND_SIZE_DEFAULT and HORIZONTAL_CHART_MARGIN_PX are module-level constants in spirit (SCREAMING_CASE, no closure refs) but live inside BarChartInner so they're re-bound every render. Hoist above BarChartInner alongside DEFAULT_BAR_SHADOW.

Also: the comment couples HORIZONTAL_CHART_MARGIN_PX = 64 to DEFAULT_MARGINS + axis-title floor in useChartMargins. That coupling isn't enforced — import / derive from the source rather than mirror the magic number.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in a772a0247a8 — both hoisted to module scope. Exported X_AXIS_TITLE_MARGIN from useChartMargins and derived HORIZONTAL_CHART_MARGIN_PX = DEFAULT_MARGINS.top + DEFAULT_MARGINS.bottom + X_AXIS_TITLE_MARGIN so the value tracks.

nextSmallerExtent = ext
}
}
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤖 [efficiency+reuse+hog-charts] · Performance

This nested loop re-walks the same labels × series set findVisibleStackedSegment just walked above, recomputing the BarRects it discarded. Cost: 2 · matching-dataIndices · |series| computeBarAtIndex calls per mousemove. For the typical aggregated bar shape it's small, but worth folding.

Have findVisibleStackedSegment return either all candidate extents or the second-largest in the same pass. drawHover then consumes one walk.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in a772a0247a8findVisibleStackedSegment now returns nextSmallerExtent from the same pass it walks for the visible bar. drawHover consumes it directly; the second walk is gone.

if (entry.series.key !== visibleKey) {
return entry
}
const raw = entry.series.data[visibleDataIndex!]
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤖 [quality] · Suggestion

Non-null assertion on visibleDataIndex! inside the .map closure, even though the outer if (line 110) already narrowed it. Hoist into a local const di = visibleDataIndex before the .map — TS narrows naturally and the ! disappears.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in a772a0247a8 — hoisted to const di = visibleDataIndex before the .map.

const raw = entry.series.data[ctx.dataIndex]
return typeof raw === 'number' && raw !== 0
}),
seriesData: ctx.seriesData.slice(0, 1),
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤖 [hog-charts+code-reviewer] · Suggestion

seriesData.slice(0, 1) relies entirely on BarTooltip having put the cursor-visible segment at [0]. If a future refactor changes the ordering semantics, this silently selects the wrong row. Defensive option: filter on whatever key BarTooltip flags as visible, or pull the slice up into BarTooltip itself so the product layer stops second-guessing the invariant.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Leaving the slice(0, 1) for now — BarTooltip is shared with other consumers that explicitly want all stacked entries (the stacked layout carries every visible series in the tooltip test locks that contract), so the slice has to live at the product layer. The new TrendsBarChart integration test (tooltip on a breakdown shows that breakdown row with its own value) plus the unit-level tooltip.seriesData[0].series.key assertions in BarChart.test.tsx lock the visible-segment-at-[0] invariant from both ends, so a future regression would surface. Open to a follow-up if we want a tagged isVisible field on SeriesDatum to make the contract explicit.

// different series get distinct bands (breakdowns of one series still share a band).
const labels = visible.map((r, i) => {
const seriesId = r.action?.order ?? r.order ?? 0
return `${displayLabels[i]}__${seriesId}`
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤖 [quality+hog-charts] · Suggestion

Two small things on this line:

  1. The __ separator is a magic string. Any consumer that ever needs to parse a band key has to know it; if a real displayLabels[i] ever ends with __<n> matching another row's seriesId, two bands collide. Probability is low, but extract a named BAND_KEY_SEP constant or use a non-displayable delimiter.

  2. r.action?.order ?? r.order ?? 0 falls back to 0 — which collides with a legitimate order: 0 (the first formula, the first action). For rows missing both fields the fallback collapses them onto each other. Either fall back to ?? i (per-row unique) or comment why 0 is safe.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Partial fix in a772a0247a8:

  1. Separator: extracted BAND_KEY_SEP = '\\u001f' (Unit Separator, U+001F). Never appears in user-facing labels.

  2. ?? 0 fallback: left as-is. Display labels already differ when both action.order and order are missing across rows, so the seriesId fallback collapsing to 0 is fine — the band key (displayLabel + sep + seriesId) stays unique. The only collision case is two rows with the same displayLabel and both missing series ids, which isn't a real shape we see from the trends data layer. ?? i would change the semantics for the formula+breakdown case where multiple rows legitimately share order: 0.

- Always wrap BarChart so axisOrientation toggle doesn't remount Chart
- Hoist HORIZONTAL_MIN_BAND_SIZE_DEFAULT/HORIZONTAL_CHART_MARGIN_PX to module
  scope and derive the margin from DEFAULT_MARGINS + X_AXIS_TITLE_MARGIN
- Fold the next-smaller-extent walk into findVisibleStackedSegment so
  drawHover walks the band once instead of twice
- Drop the visibleDataIndex non-null assertion in BarTooltip
- Extract BAND_KEY_SEP (U+001F) to name the synthetic-band-key separator
- Critical: route clicks on shared bands through findVisibleStackedSegment
  and rewrite clickData.dataIndex + ctx.dataIndex so the persons modal /
  onPointClick / tooltip-row click open the segment the cursor is over,
  not whichever row owned the band index
- Tests cover sparse-stacked click dispatch for small/mid/big visible slices

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

Addressed review feedback in a772a0247a8. Summary:

Critical click-routing fix. resolveClickedStackedSegment now walks findVisibleStackedSegment, rewrites clickData.dataIndex (and value / seriesIndex) to the visible segment's, and BarTooltip also updates ctx.dataIndex so tooltip-row clicks land on the right row. New parameterized test onPointClick routes to the visible segment for cursor in the {small,mid,big} slice in BarChart.test.tsx locks the contract for all three slices.

Should Fix items from the body.

  • Always-wrap DOM: BarChart wrapper is now unconditional with flex flex-col flex-1 Tailwind classes, only minHeight is inline. No remount on axisOrientation toggle.
  • Module-scope constants: hoisted; HORIZONTAL_CHART_MARGIN_PX now derived from DEFAULT_MARGINS + exported X_AXIS_TITLE_MARGIN.

Not done in this pass:

  • TooltipContext.seriesData[].value semantics drift — keeping the implicit invariant (seriesData[0] carries the visible value for stacked) for now, locked by the new tests at both unit and integration level. Happy to follow up with an explicit isVisible flag on SeriesDatum if you'd prefer that as the contract.
  • Performance: findVisibleStackedSegment is still called twice per mousemove (drawHover + BarTooltip). Folding the two via the _private slot is a larger refactor; deferred.
  • Nit comment trims: not done — those are in test files and the load-bearing fixture context (e.g. "DESC, matching how trendsDataLogic sorts") would have to be moved somewhere; leaving for a separate cleanup.

The 98 tests in BarChart.test.tsx, TrendsBarChart.test.tsx, and trendsBarChartTransforms.test.ts pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sampennington sampennington marked this pull request as ready for review May 29, 2026 06:47
@assign-reviewers-posthog assign-reviewers-posthog Bot requested a review from a team May 29, 2026 06:47
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 29, 2026

Comments Outside Diff (1)

  1. frontend/src/lib/hog-charts/charts/BarChart/BarChart.tsx, line 116 (link)

    P2 wrapperMinHeight over-estimates when no x-axis title is present

    HORIZONTAL_CHART_MARGIN_PX always includes X_AXIS_TITLE_MARGIN (22 px), but useChartMargins only adds that margin when xAxisLabel is non-empty (see useChartMargins.ts line 125). In the common case where no title is set, wrapperMinHeight is inflated by 22 px, which can produce an unwanted scrollbar or extra whitespace below the chart in constrained containers.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: frontend/src/lib/hog-charts/charts/BarChart/BarChart.tsx
    Line: 116
    
    Comment:
    **`wrapperMinHeight` over-estimates when no x-axis title is present**
    
    `HORIZONTAL_CHART_MARGIN_PX` always includes `X_AXIS_TITLE_MARGIN` (22 px), but `useChartMargins` only adds that margin when `xAxisLabel` is non-empty (see `useChartMargins.ts` line 125). In the common case where no title is set, `wrapperMinHeight` is inflated by 22 px, which can produce an unwanted scrollbar or extra whitespace below the chart in constrained containers.
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
frontend/src/lib/hog-charts/charts/BarChart/BarChart.tsx:116
**`wrapperMinHeight` over-estimates when no x-axis title is present**

`HORIZONTAL_CHART_MARGIN_PX` always includes `X_AXIS_TITLE_MARGIN` (22 px), but `useChartMargins` only adds that margin when `xAxisLabel` is non-empty (see `useChartMargins.ts` line 125). In the common case where no title is set, `wrapperMinHeight` is inflated by 22 px, which can produce an unwanted scrollbar or extra whitespace below the chart in constrained containers.

Reviews (1): Last reviewed commit: "refactor(hog-charts): build clipped high..." | Re-trigger Greptile

Stacked-bar tooltips keyed only off band-axis containment, so a cursor in
the row but beyond the longest bar still surfaced a tooltip. Resolve the
visible segment under the cursor and bail when there is none.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Spec-driven .map fixtures for the same-label band-split tests — same
assertions, fewer lines.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sampennington sampennington added the stamphog Request AI review from stamphog label May 29, 2026
Copy link
Copy Markdown

@stamphog stamphog Bot left a comment

Choose a reason for hiding this comment

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

Review agent failed after 3 attempts — needs human review.

@stamphog stamphog Bot removed the stamphog Request AI review from stamphog label May 29, 2026
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sampennington sampennington added the stamphog Request AI review from stamphog label May 29, 2026
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Focused frontend bug fix for tooltip/click routing in sparse-stacked horizontal bar charts. The older-commit review concern about the click path not being fixed is resolved in the current diff — resolveClickedStackedSegment now uses findVisibleStackedSegment with correct dataIndex rewriting. All other review issues are outdated with resolution replies, and the one unresolved current-head suggestion has a well-reasoned author response backed by tests. No backend, data model, API, security, or CI changes.

@sampennington sampennington merged commit 73fa822 into master May 29, 2026
181 checks passed
@sampennington sampennington deleted the sam/horizontal-bar-hover-color branch May 29, 2026 12:54
@deployment-status-posthog
Copy link
Copy Markdown

deployment-status-posthog Bot commented May 29, 2026

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-05-29 13:25 UTC Run
prod-us ✅ Deployed 2026-05-29 13:54 UTC Run
prod-eu ✅ Deployed 2026-05-29 13:55 UTC Run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stamphog Request AI review from stamphog

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant