@@ -3,7 +3,9 @@ import { ref, computed } from 'vue'
33import { VueUiHorizontalBar } from ' vue-data-ui/vue-ui-horizontal-bar'
44import type { VueUiHorizontalBarConfig , VueUiHorizontalBarDatasetItem } from ' vue-data-ui'
55import { getFrameworkColor , isListedFramework } from ' ~/utils/frameworks'
6+ import { createChartPatternSlotMarkup } from ' ~/utils/charts'
67import { drawSmallNpmxLogoAndTaglineWatermark } from ' ~/composables/useChartWatermark'
8+
79import {
810 loadFile ,
911 insertLineBreaks ,
@@ -213,13 +215,40 @@ const config = computed<VueUiHorizontalBarConfig>(() => {
213215 backdropFilter: false ,
214216 backgroundColor: ' transparent' ,
215217 customFormat : ({ datapoint }) => {
216- const name = datapoint ?.name ?.replace (/ \n / g , ' <br>' )
218+ const name = datapoint ?.name ?.replace (/ \n / g , ' <br>' ) ?? ' '
219+ const safeSeriesIndex = (datapoint ?.absoluteIndex as number ) ?? 0
220+ const patternId = ` tooltip-pattern-${safeSeriesIndex } `
221+ const usePattern = safeSeriesIndex !== 0
222+
223+ const patternMarkup = usePattern
224+ ? createChartPatternSlotMarkup ({
225+ id: patternId ,
226+ seed: safeSeriesIndex ,
227+ foregroundColor: colors .value .bg ! ,
228+ fallbackColor: ' transparent' ,
229+ maxSize: 24 ,
230+ minSize: 16 ,
231+ })
232+ : ' '
233+
234+ const markerMarkup = usePattern
235+ ? `
236+ <rect x="0" y="0" width="20" height="20" rx="3" fill="${datapoint ?.color ?? ' transparent' }" />
237+ <rect x="0" y="0" width="20" height="20" rx="3" fill="url(#${patternId })" />
238+ `
239+ : `
240+ <rect x="0" y="0" width="20" height="20" rx="3" fill="${datapoint ?.color ?? ' transparent' }" />
241+ `
242+
217243 return `
218244 <div class="font-mono p-3 border border-border rounded-md bg-[var(--bg)]/10 backdrop-blur-md">
219245 <div class="grid grid-cols-[12px_minmax(0,1fr)_max-content] items-center gap-x-3">
220246 <div class="w-3 h-3">
221- <svg viewBox="0 0 2 2" class="w-full h-full">
222- <rect x="0" y="0" width="2" height="2" rx="0.3" fill="${datapoint ?.color }" />
247+ <svg viewBox="0 0 20 20" class="w-full h-full" aria-hidden="true">
248+ <defs>
249+ ${patternMarkup }
250+ </defs>
251+ ${markerMarkup }
223252 </svg>
224253 </div>
225254 <span class="text-3xs uppercase tracking-wide text-[var(--fg)]/70 truncate">
@@ -230,7 +259,7 @@ const config = computed<VueUiHorizontalBarConfig>(() => {
230259 </span>
231260 </div>
232261 </div>
233- `
262+ `
234263 },
235264 },
236265 },
@@ -243,8 +272,19 @@ const config = computed<VueUiHorizontalBarConfig>(() => {
243272 <div class =" font-mono facet-bar" >
244273 <ClientOnly v-if =" dataset.length" >
245274 <VueUiHorizontalBar :key =" chartKey" :dataset :config class =" [direction:ltr]" >
275+ <template #pattern =" { patternId , seriesIndex } " >
276+ <ChartPatternSlot
277+ v-if =" seriesIndex != 0"
278+ :id =" patternId"
279+ :seed =" seriesIndex"
280+ :foreground-color =" colors.bg!"
281+ fallback-color =" transparent"
282+ :max-size =" 24"
283+ :min-size =" 16"
284+ />
285+ </template >
286+
246287 <template #svg =" { svg } " >
247- <!-- Inject npmx logo & tagline during SVG and PNG print -->
248288 <g
249289 v-if =" svg.isPrintingSvg || svg.isPrintingImg"
250290 v-html ="
@@ -261,15 +301,19 @@ const config = computed<VueUiHorizontalBarConfig>(() => {
261301 <span v-if =" isOpen" class =" i-lucide:x w-6 h-6" aria-hidden =" true" />
262302 <span v-else class =" i-lucide:ellipsis-vertical w-6 h-6" aria-hidden =" true" />
263303 </template >
304+
264305 <template #optionCsv >
265306 <span class =" text-fg-subtle font-mono pointer-events-none" >CSV</span >
266307 </template >
308+
267309 <template #optionImg >
268310 <span class =" text-fg-subtle font-mono pointer-events-none" >PNG</span >
269311 </template >
312+
270313 <template #optionSvg >
271314 <span class =" text-fg-subtle font-mono pointer-events-none" >SVG</span >
272315 </template >
316+
273317 <template #optionAltCopy >
274318 <span
275319 class =" w-6 h-6"
0 commit comments