- "content": "<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\r\nimport type { BaseChartProps } from \".\"\r\nimport { type BulletLegendItemInterface, CurveType } from \"@unovis/ts\"\r\nimport { Area, Axis, Line } from \"@unovis/ts\"\r\nimport { VisArea, VisAxis, VisLine, VisXYContainer } from \"@unovis/vue\"\r\nimport { useMounted } from \"@vueuse/core\"\r\nimport { useId } from \"reka-ui\"\r\nimport { type Component, computed, ref } from \"vue\"\r\nimport { cn } from \"@/lib/utils\"\r\nimport { ChartCrosshair, ChartLegend, defaultColors } from \"@/registry/new-york/ui/chart\"\r\n\r\nconst props = withDefaults(defineProps<BaseChartProps<T> & {\r\n /**\r\n * Render custom tooltip component.\r\n */\r\n customTooltip?: Component\r\n /**\r\n * Type of curve\r\n */\r\n curveType?: CurveType\r\n /**\r\n * Controls the visibility of gradient.\r\n * @default true\r\n */\r\n showGradient?: boolean\r\n}>(), {\r\n curveType: CurveType.MonotoneX,\r\n filterOpacity: 0.2,\r\n margin: () => ({ top: 0, bottom: 0, left: 0, right: 0 }),\r\n showXAxis: true,\r\n showYAxis: true,\r\n showTooltip: true,\r\n showLegend: true,\r\n showGridLine: true,\r\n showGradient: true,\r\n})\r\n\r\nconst emits = defineEmits<{\r\n legendItemClick: [d: BulletLegendItemInterface, i: number]\r\n}>()\r\n\r\ntype KeyOfT = Extract<keyof T, string>\r\ntype Data = typeof props.data[number]\r\n\r\nconst chartRef = useId()\r\n\r\nconst index = computed(() => props.index as KeyOfT)\r\nconst colors = computed(() => props.colors?.length ? props.colors : defaultColors(props.categories.length))\r\n\r\nconst legendItems = ref<BulletLegendItemInterface[]>(props.categories.map((category, i) => ({\r\n name: category,\r\n color: colors.value[i],\r\n inactive: false,\r\n})))\r\n\r\nconst isMounted = useMounted()\r\n\r\nfunction handleLegendItemClick(d: BulletLegendItemInterface, i: number) {\r\n emits(\"legendItemClick\", d, i)\r\n}\r\n</script>\r\n\r\n<template>\r\n <div :class=\"cn('w-full h-[400px] flex flex-col items-end', $attrs.class ?? '')\">\r\n <ChartLegend v-if=\"showLegend\" v-model:items=\"legendItems\" @legend-item-click=\"handleLegendItemClick\" />\r\n\r\n <VisXYContainer :style=\"{ height: isMounted ? '100%' : 'auto' }\" :margin=\"{ left: 20, right: 20 }\" :data=\"data\">\r\n <svg width=\"0\" height=\"0\">\r\n <defs>\r\n <linearGradient v-for=\"(color, i) in colors\" :id=\"`${chartRef}-color-${i}`\" :key=\"i\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\r\n <template v-if=\"showGradient\">\r\n <stop offset=\"5%\" :stop-color=\"color\" stop-opacity=\"0.4\" />\r\n <stop offset=\"95%\" :stop-color=\"color\" stop-opacity=\"0\" />\r\n </template>\r\n <template v-else>\r\n <stop offset=\"0%\" :stop-color=\"color\" />\r\n </template>\r\n </linearGradient>\r\n </defs>\r\n </svg>\r\n\r\n <ChartCrosshair v-if=\"showTooltip\" :colors=\"colors\" :items=\"legendItems\" :index=\"index\" :custom-tooltip=\"customTooltip\" />\r\n\r\n <template v-for=\"(category, i) in categories\" :key=\"category\">\r\n <VisArea\r\n :x=\"(d: Data, i: number) => i\"\r\n :y=\"(d: Data) => d[category]\"\r\n color=\"auto\"\r\n :curve-type=\"curveType\"\r\n :attributes=\"{\r\n [Area.selectors.area]: {\r\n fill: `url(#${chartRef}-color-${i})`,\r\n },\r\n }\"\r\n :opacity=\"legendItems.find(item => item.name === category)?.inactive ? filterOpacity : 1\"\r\n />\r\n </template>\r\n\r\n <template v-for=\"(category, i) in categories\" :key=\"category\">\r\n <VisLine\r\n :x=\"(d: Data, i: number) => i\"\r\n :y=\"(d: Data) => d[category]\"\r\n :color=\"colors[i]\"\r\n :curve-type=\"curveType\"\r\n :attributes=\"{\r\n [Line.selectors.line]: {\r\n opacity: legendItems.find(item => item.name === category)?.inactive ? filterOpacity : 1,\r\n },\r\n }\"\r\n />\r\n </template>\r\n\r\n <VisAxis\r\n v-if=\"showXAxis\"\r\n type=\"x\"\r\n :tick-format=\"xFormatter ?? ((v: number) => data[v]?.[index])\"\r\n :grid-line=\"false\"\r\n :tick-line=\"false\"\r\n tick-text-color=\"hsl(var(--vis-text-color))\"\r\n />\r\n <VisAxis\r\n v-if=\"showYAxis\"\r\n type=\"y\"\r\n :tick-line=\"false\"\r\n :tick-format=\"yFormatter\"\r\n :domain-line=\"false\"\r\n :grid-line=\"showGridLine\"\r\n :attributes=\"{\r\n [Axis.selectors.grid]: {\r\n class: 'text-muted',\r\n },\r\n }\"\r\n tick-text-color=\"hsl(var(--vis-text-color))\"\r\n />\r\n\r\n <slot />\r\n </VisXYContainer>\r\n </div>\r\n</template>\r\n",
0 commit comments