Skip to content

feat: replace quadrant with scatter with selectable axes#2472

Merged
graphieros merged 22 commits intomainfrom
compare-scatter-with-selectable-axes
Apr 12, 2026
Merged

feat: replace quadrant with scatter with selectable axes#2472
graphieros merged 22 commits intomainfrom
compare-scatter-with-selectable-axes

Conversation

@graphieros
Copy link
Copy Markdown
Contributor

@graphieros graphieros commented Apr 11, 2026

Resolves #2449

This replaces the controversial quadrant chart with a scatter plot, where 2 facets can be compared.
No weights, no debates.

Dark mode Light mode
image image
  • Hovered datapoint (or accessed via keyboard):
image

@graphieros graphieros linked an issue Apr 11, 2026 that may be closed by this pull request
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 11, 2026

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

Project Deployment Actions Updated (UTC)
npmx.dev Ready Ready Preview, Comment Apr 12, 2026 4:50am
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview Apr 12, 2026 4:50am
npmx-lunaria Ignored Ignored Apr 12, 2026 4:50am

Request Review

@graphieros graphieros changed the title Compare scatter with selectable axes feat: replace quadrant with scatter with selectable axes Apr 11, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 11, 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/cs-CZ.json Localization changed, will be marked as complete.
i18n/locales/de.json Localization changed, will be marked as complete.
i18n/locales/en.json Source changed, localizations will be marked as outdated.
i18n/locales/fr-FR.json Localization changed, will be marked as complete.
i18n/locales/nb-NO.json Localization changed, will be marked as complete.
i18n/locales/ru-RU.json Localization changed, will be marked as complete.
i18n/locales/zh-CN.json Localization changed, will be marked as complete.
i18n/locales/zh-TW.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.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 11, 2026

⚠️ Duplicate Dependencies (found: 4, threshold: 4)

📦 Package 📋 Versions
h3
5 versions
  • root@
    • @nuxt/fonts@0.14.0
      • fontless@0.2.1
        • unstorage@1.17.5
          • h3@1.15.11

  • root@
    • @nuxt/fonts@0.14.0
      • h3@1.15.8

h3@2.0.1-rc.11
h3@2.0.1-rc.16
h3@2.0.1-rc.20
glob
5 versions
  • root@
    • @nuxt/test-utils@4.0.0
      • @vue/test-utils@2.4.6
        • js-beautify@1.15.4
          • glob@10.5.0

  • root@
    • @vite-pwa/nuxt@1.1.1
      • vite-plugin-pwa@1.2.0
        • workbox-build@7.4.0
          • glob@11.1.0

  • root@
    • @vueuse/nuxt@14.2.1
      • ...
        • nitropack@2.13.3
          • @vercel/nft@1.5.0
            • glob@13.0.6

  • root@
    • vue-i18n-extract@2.0.7
      • dot-object@2.1.5
        • glob@7.2.3

  • root@
    • vue-i18n-extract@2.0.7
      • glob@8.1.0

@rolldown/pluginutils
5 versions
  • root@
    • @vueuse/nuxt@14.2.1
      • ...
        • rollup-plugin-visualizer@7.0.1
          • rolldown@1.0.0-rc.12
            • @rolldown/pluginutils@1.0.0-rc.12

  • root@
    • @vueuse/nuxt@14.2.1
      • nuxt@4.3.1
        • @nuxt/vite-builder@4.3.1
          • @vitejs/plugin-vue-jsx@5.1.5
            • @rolldown/pluginutils@1.0.0-rc.13

  • root@
    • @vueuse/nuxt@14.2.1
      • nuxt@4.3.1
        • @nuxt/vite-builder@4.3.1
          • @vitejs/plugin-vue@6.0.5
            • @rolldown/pluginutils@1.0.0-rc.2

  • root@
    • @nuxt/a11y@1.0.0-alpha.1
      • @nuxt/devtools-kit@3.2.4
        • vite@8.0.0-beta.18
          • rolldown@1.0.0-rc.8
            • @rolldown/pluginutils@1.0.0-rc.8

@rolldown/pluginutils@1.0.0-rc.9
@oxc-project/types
6 versions
  • root@
    • @vueuse/nuxt@14.2.1
      • nuxt@4.3.1
        • oxc-parser@0.112.0
          • @oxc-project/types@0.112.0

  • root@
    • @nuxt/a11y@1.0.0-alpha.1
      • @nuxt/devtools-kit@3.2.4
        • vite@8.0.0-beta.18
          • rolldown@1.0.0-rc.8
            • @oxc-project/types@0.115.0

  • root@
    • knip@6.0.5
      • oxc-parser@0.120.0
        • @oxc-project/types@0.120.0

  • root@
    • @vueuse/nuxt@14.2.1
      • ...
        • rollup-plugin-visualizer@7.0.1
          • rolldown@1.0.0-rc.12
            • @oxc-project/types@0.122.0

  • root@
    • vite-plus@0.1.16
      • @oxc-project/types@0.123.0

  • root@
    • @nuxtjs/i18n@10.2.3
      • oxc-parser@0.95.0
        • @oxc-project/types@0.95.0

💡 To find out what depends on a specific package, run: pnpm -r why example-package

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 11, 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

This PR removes the quadrant chart and its scoring pipeline, replacing it with a selectable-axis scatter chart. It adds FacetScatterChart.vue, app/utils/compare-scatter-chart.ts, scatter-specific alt-text helpers, updated facet metadata and formatters, adjusted watermark helper signature, i18n schema/locale changes (quadrant → scatter), Vite prebundle update, vue-data-ui version bump, and replaces/removes related tests and utilities for the quadrant chart.

Possibly related PRs

Suggested labels

ux

Suggested reviewers

  • serhalp
  • danielroe
  • alexdln
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed All objectives from #2449 are met: quadrant chart replaced with scatter, facet selection implemented for X/Y axes, same facet selection supported, weight-based approach removed.
Out of Scope Changes check ✅ Passed All changes align with issue #2449 objectives. Additional changes to CSS variables (--accent-color to --accent) and test updates support the main scatter chart implementation.
Description check ✅ Passed The PR description clearly describes the change: replacing a quadrant chart with a scatter plot using selectable facets, including specific implementation details, linked issues, and visual examples.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch compare-scatter-with-selectable-axes

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
Copy Markdown
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 (2)
app/pages/compare.vue (1)

429-456: ⚠️ Potential issue | 🟡 Minor

Don't show the empty-state copy for scatter-only facet sets.

This branch still keys off facet.chartable, which now only covers the bar charts. If the user selects only scatter-capable facets such as vulnerabilities or lastUpdated, the page tells them “No chartable data available” even though FacetScatterChart below can still render. Gate this message on chartable_scatter as well, or scope it to the bar-chart section only.

💡 Suggested tweak
-              <p v-else class="py-12 text-center text-fg-subtle">
+              <p
+                v-else-if="!selectedFacets.some(facet => facet.chartable_scatter)"
+                class="py-12 text-center text-fg-subtle"
+              >
                 {{ $t('compare.packages.no_chartable_data') }}
               </p>
test/nuxt/a11y.spec.ts (1)

1020-1127: ⚠️ Potential issue | 🟠 Major

Fixture does not exercise the populated scatter render path.

Since FacetScatterChart defaults to Downloads/wk (X-axis) × Install Size (Y-axis), and getNumericFacetValue returns null when installSize is missing, both items in this fixture will be filtered out by the if (x === null || y === null) check in buildCompareScatterChartDataset. The chart will render empty, so the test only covers the empty-state path. Add installSize to the fixture to exercise the actual populated scatter render.

🧹 Nitpick comments (1)
app/utils/charts.ts (1)

700-705: Rename the typoed export before it spreads further.

coopyAltTextForCompareScatterChart looks accidental and makes the helper harder to discover by grep/autocomplete.

Proposed fix
-export async function coopyAltTextForCompareScatterChart({
+export async function copyAltTextForCompareScatterChart({
   dataset,
   config,
 }: AltCopyArgs<VueUiScatterSeries[], CompareScatterChartConfig>) {
   const altText = createAltTextForCompareScatterChart({ dataset, config })
   await config.copy(altText)
 }

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6257ac32-ed17-41e5-adc4-4084e3970520

📥 Commits

Reviewing files that changed from the base of the PR and between 0164064 and 28fd394.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (21)
  • app/components/Compare/FacetQuadrantChart.vue
  • app/components/Compare/FacetScatterChart.vue
  • app/components/Package/TrendsChart.vue
  • app/composables/useChartWatermark.ts
  • app/composables/useFacetSelection.ts
  • app/pages/compare.vue
  • app/utils/charts.ts
  • app/utils/compare-quadrant-chart.ts
  • app/utils/compare-scatter-chart.ts
  • i18n/locales/cs-CZ.json
  • i18n/locales/en.json
  • i18n/locales/fr-FR.json
  • i18n/locales/ru-RU.json
  • i18n/locales/zh-CN.json
  • i18n/locales/zh-TW.json
  • i18n/schema.json
  • nuxt.config.ts
  • package.json
  • test/nuxt/a11y.spec.ts
  • test/unit/app/utils/compare-quadrant-chart.spec.ts
  • test/unit/app/utils/compare-scatter-chart.spec.ts
💤 Files with no reviewable changes (7)
  • i18n/locales/cs-CZ.json
  • i18n/locales/zh-CN.json
  • app/components/Compare/FacetQuadrantChart.vue
  • i18n/locales/zh-TW.json
  • i18n/locales/ru-RU.json
  • test/unit/app/utils/compare-quadrant-chart.spec.ts
  • app/utils/compare-quadrant-chart.ts

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 11, 2026

@graphieros graphieros marked this pull request as ready for review April 11, 2026 09:41
Copy link
Copy Markdown
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/FacetScatterChart.vue (2)

125-269: Split the chart config builder into smaller helpers.

This computed now mixes export callbacks, alt-copy wiring, axis formatting, and style/layout in one block. Pulling those sections into dedicated helpers will make future chart changes much easier to review and safer to extend.

As per coding guidelines, **/*.{ts,tsx,vue} should “Keep functions focused and manageable (generally under 50 lines)”.


82-89: Refactor to avoid fragile index-based fallback logic.

The scatter chart function iterates packagesData by index and accesses packages[index] for fallback names. When NO_DEPENDENCY_ID is in the packages list, packagesData includes its entry, but the filtered packages passed to the component does not. This creates an array length mismatch: if packages.value = ["react", "vue", "__no_dependency__"], then packagesData has 3 items but filtered packages has 2. Accessing packages[2] would be undefined.

This latent misalignment is currently masked because NO_DEPENDENCY_ID entries have null x/y facet values and filter out at line 98 before the fallback is used. However, the code is fragile and depends on external data shape to avoid the actual index-out-of-bounds risk.

Instead of relying on index-based fallbacks, pass the filtered packagesData directly (already filtered alongside packages), or refactor buildCompareScatterChartDataset to not assume index alignment between the two arrays.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 94752aba-4f36-4762-91b0-4dab9eacee01

📥 Commits

Reviewing files that changed from the base of the PR and between 28fd394 and 8aa7684.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (14)
  • app/components/Compare/FacetScatterChart.vue
  • app/utils/charts.ts
  • app/utils/compare-scatter-chart.ts
  • i18n/locales/cs-CZ.json
  • i18n/locales/en.json
  • i18n/locales/fr-FR.json
  • i18n/locales/nb-NO.json
  • i18n/locales/ru-RU.json
  • i18n/locales/zh-CN.json
  • i18n/locales/zh-TW.json
  • i18n/schema.json
  • nuxt.config.ts
  • package.json
  • test/unit/app/utils/compare-scatter-chart.spec.ts
💤 Files with no reviewable changes (4)
  • i18n/locales/cs-CZ.json
  • i18n/locales/zh-TW.json
  • i18n/locales/zh-CN.json
  • i18n/locales/ru-RU.json
✅ Files skipped from review due to trivial changes (2)
  • package.json
  • test/unit/app/utils/compare-scatter-chart.spec.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • nuxt.config.ts
  • i18n/schema.json

Copy link
Copy Markdown
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 (1)
app/components/Compare/FacetScatterChart.vue (1)

488-493: Please remove the commented-out CSS block.

Keeping dead positioning rules in a brand-new component makes it harder to see which scatter-specific tweaks are still intentional.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e96ba54d-a497-4122-844f-227c3fc5d91e

📥 Commits

Reviewing files that changed from the base of the PR and between ecab11e and d611dc6.

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

@graphieros graphieros added the needs review This PR is waiting for a review from a maintainer label Apr 11, 2026
</template>
<template #skeleton>
<!-- This empty div overrides the default built-in scanning animation on load -->
<div />
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
<div />
<div></div>

:p sveltejs/svelte#11052

@graphieros graphieros added this pull request to the merge queue Apr 12, 2026
Merged via the queue into main with commit c5b3b0f Apr 12, 2026
25 checks passed
@graphieros graphieros deleted the compare-scatter-with-selectable-axes branch April 12, 2026 04:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs review This PR is waiting for a review from a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replace quadrant chart with scatter with selectable axes Improve skeleton loaders in compare page bar charts

2 participants