Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
9f780bb
chore: bump vue-data-ui from 3.17.3 to 3.17.8
graphieros Apr 5, 2026
88dce54
feat: add quadrant chart utility
graphieros Apr 5, 2026
3174980
feat: make watermark generator more flexible
graphieros Apr 5, 2026
3805191
feat: add facet quadrant chart to compare page
graphieros Apr 5, 2026
85e6ac8
chore: add translations
graphieros Apr 5, 2026
e4dff84
[autofix.ci] apply automated fixes
autofix-ci[bot] Apr 5, 2026
b363f85
fix: only render quadrant if packages are selected
graphieros Apr 5, 2026
47976d1
ChartPatternSlotProps
graphieros Apr 5, 2026
0123e31
[autofix.ci] apply automated fixes
autofix-ci[bot] Apr 5, 2026
b6501a5
fix: allow teleport warning for chart legend
graphieros Apr 5, 2026
845b221
chore: bump vue-data-ui from 3.17.8 to 3.17.9
graphieros Apr 5, 2026
7b040b1
fix: remove log
graphieros Apr 5, 2026
1cad7a2
fix: restore a11y test
graphieros Apr 5, 2026
8466bcb
[autofix.ci] apply automated fixes
autofix-ci[bot] Apr 5, 2026
11fd407
fix: set a max width on quadrant wrapper
graphieros Apr 5, 2026
b548437
fix: use log ceilings instead of relative normalisations
graphieros Apr 5, 2026
23f5438
fix: use more readable text color
graphieros Apr 5, 2026
5ab59d6
fix: add translations and other fixes
graphieros Apr 5, 2026
ef970f7
fix: add missing type and guard
graphieros Apr 5, 2026
4857c61
fix: add translations
graphieros Apr 5, 2026
b6a4bb3
fix: add missing import
graphieros Apr 5, 2026
df7afbc
fix: improve quadrant labels
graphieros Apr 5, 2026
901f8c2
[autofix.ci] apply automated fixes
autofix-ci[bot] Apr 5, 2026
5c6564c
fix: adjust efficiency weights to sum to 1
graphieros Apr 5, 2026
0385f67
fix: translations
graphieros Apr 5, 2026
7079805
fix: add missing type
graphieros Apr 5, 2026
d7d203b
Merge branch 'compare-quadrant-chart' of https://github.com/npmx-dev/…
graphieros Apr 5, 2026
c27eb19
[autofix.ci] apply automated fixes
autofix-ci[bot] Apr 5, 2026
2150f0a
fix: add translation for the tooltip trigger's aria-label
graphieros Apr 5, 2026
92e693f
fix: add fallbacks in tooltip values
graphieros Apr 5, 2026
7c071f3
fix: include vue-data-ui components in optimizeDeps
graphieros Apr 5, 2026
7f4b3b3
fix: typo...
graphieros Apr 5, 2026
745b3eb
fix: filter out no dependency id package
graphieros Apr 5, 2026
e07675b
fix: address no-map-spread warning
graphieros Apr 6, 2026
cd795dd
fix: remove redundant guard
graphieros Apr 6, 2026
25d82ae
Merge branch 'main' into compare-quadrant-chart
graphieros Apr 6, 2026
0324237
fix: do not crop overflowing long data labels on the rim
graphieros Apr 6, 2026
b209867
chore: bump vue-data-ui from 3.17.9 to 3.17.10
graphieros Apr 6, 2026
65330e4
Merge branch 'main' into compare-quadrant-chart
graphieros Apr 6, 2026
41059cb
Merge branch 'main' into compare-quadrant-chart
graphieros Apr 6, 2026
f8fe74f
chore: bump vue-data-ui from 3.17.10 to 3.17.11
graphieros Apr 6, 2026
8e3d902
Merge branch 'main' into compare-quadrant-chart
graphieros Apr 6, 2026
ac1a97c
Merge branch 'main' into compare-quadrant-chart
graphieros Apr 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
481 changes: 481 additions & 0 deletions app/components/Compare/FacetQuadrantChart.vue

Large diffs are not rendered by default.

20 changes: 15 additions & 5 deletions app/composables/useChartWatermark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,23 @@ export function drawNpmxLogoAndTaglineWatermark({
colors,
translateFn,
positioning = 'bottom',
sizeRatioLogo = 1,
sizeRatioTagline = 1,
offsetYTagline = -6,
offsetYLogo = 0,
}: {
svg: Record<string, any>
colors: WatermarkColors
translateFn: (key: string) => string
positioning?: 'bottom' | 'belowDrawingArea'
sizeRatioLogo?: number
sizeRatioTagline?: number
offsetYTagline?: number
offsetYLogo?: number
}) {
if (!svg?.drawingArea) return ''
const npmxLogoWidthToHeight = 2.64
const npmxLogoWidth = 100
const npmxLogoWidthToHeight = 2.64 * sizeRatioLogo
const npmxLogoWidth = 100 * sizeRatioLogo
const npmxLogoHeight = npmxLogoWidth / npmxLogoWidthToHeight
Comment thread
coderabbitai[bot] marked this conversation as resolved.

// Position watermark based on the positioning strategy
Expand All @@ -94,18 +102,20 @@ export function drawNpmxLogoAndTaglineWatermark({
: svg.height - npmxLogoHeight

const taglineY =
positioning === 'belowDrawingArea' ? watermarkY - 6 : svg.height - npmxLogoHeight - 6
positioning === 'belowDrawingArea'
? watermarkY + offsetYTagline
: svg.height - npmxLogoHeight + offsetYTagline

// Center the watermark horizontally relative to the full SVG width
const watermarkX = svg.width / 2 - npmxLogoWidth / 2

return `
${generateWatermarkLogo({ x: watermarkX, y: watermarkY, width: npmxLogoWidth, height: npmxLogoHeight, fill: colors.fg })}
${generateWatermarkLogo({ x: watermarkX, y: watermarkY + offsetYLogo, width: npmxLogoWidth, height: npmxLogoHeight, fill: colors.fg })}
<text
fill="${colors.fgSubtle}"
x="${svg.width / 2}"
y="${taglineY}"
font-size="12"
font-size="${12 * sizeRatioTagline}"
text-anchor="middle"
>
${translateFn('tagline')}
Expand Down
10 changes: 9 additions & 1 deletion app/pages/compare.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { NO_DEPENDENCY_ID } from '~/composables/usePackageComparison'
import { useRouteQuery } from '@vueuse/router'
import FacetBarChart from '~/components/Compare/FacetBarChart.vue'
import FacetQuadrantChart from '~/components/Compare/FacetQuadrantChart.vue'

definePageMeta({
name: 'compare',
Expand Down Expand Up @@ -330,7 +331,7 @@ useSeoMeta({
</div>
</TabPanel>

<!-- bar charts -->
<!-- Charts: per-facet bars & quadrant -->
<TabPanel value="charts" panel-id="comparison-panel-charts">
<div
v-if="selectedFacets.some(facet => facet.chartable)"
Expand All @@ -353,6 +354,13 @@ useSeoMeta({
<p v-else class="py-12 text-center text-fg-subtle">
{{ $t('compare.packages.no_chartable_data') }}
</p>
<div class="max-w-[450px] mx-auto">
<FacetQuadrantChart
v-if="packages.length"
:packages-data="packagesData"
:packages="packages"
/>
</div>
</TabPanel>
</TabRoot>

Expand Down
68 changes: 68 additions & 0 deletions app/utils/charts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type {
AltCopyArgs,
VueUiHorizontalBarConfig,
VueUiHorizontalBarDatapoint,
VueUiQuadrantDatapoint,
VueUiXyConfig,
VueUiXyDatasetBarItem,
VueUiXyDatasetLineItem,
Expand Down Expand Up @@ -636,6 +637,73 @@ export async function copyAltTextForCompareFacetBarChart({
await config.copy(altText)
}

export function createAltTextForCompareQuadrantChart({
dataset,
config,
}: AltCopyArgs<VueUiQuadrantDatapoint[], any>) {
const packages = {
topRight: dataset.filter(d => d.quadrant === 'TOP_RIGHT'),
topLeft: dataset.filter(d => d.quadrant === 'TOP_LEFT'),
bottomRight: dataset.filter(d => d.quadrant === 'BOTTOM_RIGHT'),
bottomLeft: dataset.filter(d => d.quadrant === 'BOTTOM_LEFT'),
}

const descriptions = {
topRight: '',
topLeft: '',
bottomRight: '',
bottomLeft: '',
}

if (packages.topRight.length) {
descriptions.topRight = config.$t('compare.quadrant_chart.copy_alt.side_analysis_top_right', {
packages: packages.topRight.map(p => p.fullname).join(', '),
})
}

if (packages.topLeft.length) {
descriptions.topLeft = config.$t('compare.quadrant_chart.copy_alt.side_analysis_top_left', {
packages: packages.topLeft.map(p => p.fullname).join(', '),
})
}

if (packages.bottomRight.length) {
descriptions.bottomRight = config.$t(
'compare.quadrant_chart.copy_alt.side_analysis_bottom_right',
{
packages: packages.bottomRight.map(p => p.fullname).join(', '),
},
)
}

if (packages.bottomLeft.length) {
descriptions.bottomLeft = config.$t(
'compare.quadrant_chart.copy_alt.side_analysis_bottom_left',
{
packages: packages.bottomLeft.map(p => p.fullname).join(', '),
},
)
}

const analysis = Object.values(descriptions).filter(Boolean).join('. ')

const altText = config.$t('compare.quadrant_chart.copy_alt.description', {
packages: dataset.map(p => p.fullname).join(', '),
analysis,
watermark: config.$t('package.trends.copy_alt.watermark'),
})

return altText
}

export async function copyAltTextForCompareQuadrantChart({
dataset,
config,
}: AltCopyArgs<VueUiQuadrantDatapoint[], any>) {
const altText = createAltTextForCompareQuadrantChart({ dataset, config })
await config.copy(altText)
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

// Used in chart context menu callbacks
// @todo replace with downloadFileLink
export function loadFile(link: string, filename: string) {
Expand Down
Loading
Loading