Skip to content

feat: add bar chart view to compare page#1974

Open
graphieros wants to merge 22 commits intonpmx-dev:mainfrom
graphieros:main
Open

feat: add bar chart view to compare page#1974
graphieros wants to merge 22 commits intonpmx-dev:mainfrom
graphieros:main

Conversation

@graphieros
Copy link
Contributor

@graphieros graphieros commented Mar 7, 2026

Some users find it easier to read information from tables, others from charts.
This offers the possibility to switch from one view to the other to compare chartable facets.

The charts for downloads history remains independent, and visible with both views.

  • bump vue-data-ui to 3.15.11 (bar charts improvements)
  • centralise some shared chart utils
  • add bar chart component: minimal chart, without CSV download feature since the whole table remains copiable

Desktop:
desktop

Mobile:
mobile

@vercel
Copy link

vercel bot commented Mar 7, 2026

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

Project Deployment Actions Updated (UTC)
npmx.dev (canary) Ready Ready Preview, Comment Mar 8, 2026 4:52am
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview Mar 8, 2026 4:52am
npmx-lunaria Ignored Ignored Mar 8, 2026 4:52am

Request Review

@github-actions
Copy link

github-actions bot commented Mar 7, 2026

Lunaria Status Overview

🌕 This pull request will trigger status changes.

Learn more

By default, every PR changing files present in the Lunaria configuration's files property will be considered and trigger status changes accordingly.

You can change this by adding one of the keywords present in the ignoreKeywords property in your Lunaria configuration file in the PR's title (ignoring all files) or by including a tracker directive in the merged commit's description.

Tracked Files

File Note
i18n/locales/en.json Source changed, localizations will be marked as outdated.
i18n/locales/fr-FR.json Localization changed, will be marked as complete.
Warnings reference
Icon Description
🔄️ The source for this localization has been updated since the creation of this pull request, make sure all changes in the source have been applied.

@codecov
Copy link

codecov bot commented Mar 7, 2026

Codecov Report

❌ Patch coverage is 50.00000% with 76 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
app/utils/charts.ts 40.67% 33 Missing and 2 partials ⚠️
app/components/Compare/FacetBarChart.vue 66.23% 24 Missing and 2 partials ⚠️
app/composables/useChartWatermark.ts 0.00% 12 Missing and 1 partial ⚠️
app/components/Package/TrendsChart.vue 0.00% 1 Missing ⚠️
app/components/Package/VersionDistribution.vue 0.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 7, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a new Vue 3 component Compare/FacetBarChart.vue that renders horizontal facet comparison bar charts with export callbacks (CSV/PNG/SVG) and alt-text copy support. Introduces new chart utilities and helpers in app/utils/charts.ts (loadFile, sanitise, insertLineBreaks, applyEllipsis, and facet-bar alt-text functions). Propagates a new boolean chartable on facet metadata via useFacetSelection.ts and updates the compare page to toggle between table and charts views, rendering FacetBarChart for chartable facets. Adds i18n keys, accessibility tests for FacetBarChart, unit tests for chart utilities, and bumps vue-data-ui.

Possibly related PRs

Suggested labels

front, a11y

Suggested reviewers

  • danielroe
  • serhalp
  • alexdln
🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The pull request description clearly relates to the changeset, explaining the addition of a bar chart view toggle for the compare page and detailing the specific changes made.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/pages/compare.vue (1)

285-365: ⚠️ Potential issue | 🟠 Major

This view switch is not keyboard-operable as a tabs control.

The inactive tab is removed from the tab order with tabindex="-1", but there is no arrow-key roving focus logic, so keyboard users cannot reach the other view. The panels also never expose the IDs referenced by aria-controls, so the tab/panel relationship is incomplete for assistive tech. Either implement the full tabs pattern or keep these as ordinary toggle buttons.

🧹 Nitpick comments (4)
app/composables/useFacetSelection.ts (1)

12-16: Keep chartable in shared facet metadata.

chartable is behavioural metadata rather than translated copy. Keeping it inside facetLabels ties chart support to i18n and makes this composable the only source of truth. I’d move it into FacetInfo/FACET_INFO and leave facetLabels responsible only for label and description.

Also applies to: 27-104

app/pages/compare.vue (1)

297-297: Use the shared button focus treatment here instead.

These tab buttons are native <button> elements, so the inline focus-visible:outline-accent/70 class just duplicates and diverges from the project-wide focus ring.

Based on learnings, focus-visible styling for buttons and selects is applied globally in app/assets/main.css, and individual buttons should not add inline focus-visible:outline-accent/70 utilities.

Also applies to: 316-316

app/utils/charts.ts (1)

614-618: Remove the stray console log from the alt-text helper.

createAltTextForCompareFacetBarChart() sits on a user-facing menu action, so this will log every alt-text copy in production and pollute tests/devtools for no value.

🧹 Proposed fix
   if (!dataset) return ''
   const { facet, description, $t } = config
-
-  console.log(config)
 
   const packages = dataset.map(d => d.name).join(', ')
test/unit/app/utils/charts.spec.ts (1)

1-23: Please cover the compare-facet alt-text helpers as well.

This file adds good coverage for the new formatting utilities, but createAltTextForCompareFacetBarChart() and copyAltTextForCompareFacetBarChart() are the new public accessibility path behind FacetBarChart and are still untested here. A small suite mirroring the trend/version chart tests would catch translation-param and copy-forwarding regressions.

As per coding guidelines, **/*.{test,spec}.{ts,tsx}: Write unit tests for core functionality using vitest.

Also applies to: 1244-1455


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bb495d21-75d7-4d37-bb84-c076617d44fb

📥 Commits

Reviewing files that changed from the base of the PR and between 0d952fa and f46d93b.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (11)
  • app/components/Compare/FacetBarChart.vue
  • app/components/Package/TrendsChart.vue
  • app/components/Package/VersionDistribution.vue
  • app/composables/useFacetSelection.ts
  • app/pages/compare.vue
  • app/utils/charts.ts
  • i18n/locales/en.json
  • i18n/schema.json
  • package.json
  • test/nuxt/a11y.spec.ts
  • test/unit/app/utils/charts.spec.ts

graphieros and others added 2 commits March 7, 2026 11:42
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
app/components/Compare/FacetBarChart.vue (1)

238-246: Fallback skeleton uses pkg as key—confirm uniqueness.

Using the package name directly as :key="pkg" is fine if package names are guaranteed unique within the comparison. If duplicates are ever possible, consider ${pkg}-${index} to ensure stable keys.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3d299d82-5cae-43ec-aa88-35ebad1cb04d

📥 Commits

Reviewing files that changed from the base of the PR and between f46d93b and ab5c8d5.

📒 Files selected for processing (1)
  • app/components/Compare/FacetBarChart.vue

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
app/components/Compare/FacetBarChart.vue (2)

14-14: Consider using a standard CSS import for critical styles.

The dynamic import() at module level for stylesheets works but is unconventional. The discarded promise means styles load asynchronously, which could cause a brief flash of unstyled content on slower connections. A regular import ensures styles are bundled and available synchronously.

-import('vue-data-ui/style.css')
+import 'vue-data-ui/style.css'

If lazy-loading is intentional for bundle optimisation, consider documenting the rationale.


66-72: Add a clarifying comment for the watcher logic.

The early return when lengths differ is correct (the chart re-renders naturally when dataset size changes), but the intent isn't immediately obvious. A brief comment would help future maintainers.

 watch(
   () => props.packages,
   (newP, oldP) => {
+    // When length changes, the chart re-renders via dataset change.
+    // When packages are swapped (same length), force re-render via key.
     if (newP.length !== oldP.length) return
     chartKey.value += 1
   },
 )

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7b3fb29c-1836-4f5f-aa80-5ffb3f95d3d4

📥 Commits

Reviewing files that changed from the base of the PR and between 9e20fcb and 2217d65.

📒 Files selected for processing (1)
  • app/components/Compare/FacetBarChart.vue

@alexdln
Copy link
Member

alexdln commented Mar 7, 2026

Visually, I really like everything except the text size. The package name is initially 16px, but since the container is scaled down, it's now ~9px.

I don't know if we can safely increase it, but I think it would be helpful to add a title to the entire line, in the format <title>{name}: {value}<title>

@knowler wdyt?

@graphieros
Copy link
Contributor Author

graphieros commented Mar 8, 2026

@alexdln I enabled the tooltip, and also increased the font size for names slightly, which should solve the problem

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.

2 participants