UNPKG

sigma-ui

Version:
20 lines 4.7 kB
{ "name": "chart-donut", "dependencies": [ "@unovis/vue", "@unovis/ts", "@vueuse/core" ], "registryDependencies": [], "files": [ { "name": "DonutChart.vue", "content": "<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport { VisDonut, VisSingleContainer } from '@unovis/vue';\nimport { Donut } from '@unovis/ts';\nimport { type Component, computed, ref } from 'vue';\nimport { useMounted } from '@vueuse/core';\nimport type { BaseChartProps } from '.';\nimport { ChartSingleTooltip, defaultColors } from '@ui/registry/tailwind/ui/chart';\nimport { cn } from '@ui/utils';\n\nconst props = withDefaults(defineProps<Pick<BaseChartProps<T>, 'data' | 'colors' | 'index' | 'margin' | 'showLegend' | 'showTooltip' | 'filterOpacity'> & {\n /**\n * Sets the name of the key containing the quantitative chart values.\n */\n category: KeyOfT;\n /**\n * Change the type of the chart\n * @default \"donut\"\n */\n type?: 'donut' | 'pie';\n /**\n * Function to sort the segment\n */\n sortFunction?: (a: any, b: any) => number | undefined;\n /**\n * Controls the formatting for the label.\n */\n valueFormatter?: (tick: number, i?: number, ticks?: number[]) => string;\n /**\n * Render custom tooltip component.\n */\n customTooltip?: Component;\n}>(), {\n margin: () => ({ top: 0, bottom: 0, left: 0, right: 0 }),\n sortFunction: () => undefined,\n valueFormatter: (tick: number) => `${tick}`,\n type: 'donut',\n filterOpacity: 0.2,\n showTooltip: true,\n showLegend: true,\n});\n\ntype KeyOfT = Extract<keyof T, string>;\ntype Data = typeof props.data[number];\n\nconst category = computed(() => props.category as KeyOfT);\nconst index = computed(() => props.index as KeyOfT);\n\nconst isMounted = useMounted();\nconst activeSegmentKey = ref<string>();\nconst colors = computed(() => props.colors?.length ? props.colors : defaultColors(props.data.filter(d => d[props.category]).filter(Boolean).length));\nconst legendItems = computed(() => props.data.map((item, i) => ({\n name: item[props.index],\n color: colors.value[i],\n inactive: false,\n})));\n\nconst totalValue = computed(() => props.data.reduce((prev, curr) => {\n return prev + curr[props.category];\n}, 0));\n</script>\n\n<template>\n <div :class=\"cn('w-full h-48 flex flex-col items-end', $attrs.class ?? '')\">\n <VisSingleContainer\n :style=\"{ height: isMounted ? '100%' : 'auto' }\"\n :margin=\"{ left: 20, right: 20 }\"\n :data=\"data\"\n >\n <ChartSingleTooltip\n :selector=\"Donut.selectors.segment\"\n :index=\"category\"\n :items=\"legendItems\"\n :value-formatter=\"valueFormatter\"\n :custom-tooltip=\"customTooltip\"\n />\n\n <VisDonut\n :value=\"(d: Data) => d[category]\"\n :sort-function=\"sortFunction\"\n :color=\"colors\"\n :arc-width=\"type === 'donut' ? 20 : 0\"\n :show-background=\"false\"\n :central-label=\"type === 'donut' ? valueFormatter(totalValue) : ''\"\n :events=\"{\n [Donut.selectors.segment]: {\n click: (d: Data, ev: PointerEvent, i: number, elements: HTMLElement[]) => {\n if (d?.data?.[index] === activeSegmentKey) {\n activeSegmentKey = undefined\n elements.forEach(el => el.style.opacity = '1')\n }\n else {\n activeSegmentKey = d?.data?.[index]\n elements.forEach(el => el.style.opacity = `${filterOpacity}`)\n elements[i].style.opacity = '1'\n }\n },\n },\n }\"\n />\n\n <slot />\n </VisSingleContainer>\n </div>\n</template>\n" }, { "name": "index.ts", "content": "export { default as DonutChart } from './DonutChart.vue';\n\nimport type { Spacing } from '@unovis/ts';\n\ntype KeyOf<T extends Record<string, any>> = Extract<keyof T, string>;\n\nexport interface BaseChartProps<T extends Record<string, any>> {\n /**\n * The source data, in which each entry is a dictionary.\n */\n data: T[];\n /**\n * Sets the key to map the data to the axis.\n */\n index: KeyOf<T>;\n /**\n * Change the default colors.\n */\n colors?: string[];\n /**\n * Margin of each the container\n */\n margin?: Spacing;\n /**\n * Change the opacity of the non-selected field\n * @default 0.2\n */\n filterOpacity?: number;\n /**\n * Controls the visibility of tooltip.\n * @default true\n */\n showTooltip?: boolean;\n /**\n * Controls the visibility of legend.\n * @default true\n */\n showLegend?: boolean;\n}\n" } ], "type": "components:ui" }