UNPKG

@mozaic-ds/chart

Version:

This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.

174 lines (159 loc) 5.01 kB
import { ref } from 'vue'; import type { Ref } from 'vue'; import { getHtmlLegendPlugin } from '@/services/ChartsCommonLegend'; import { formatWithThousandsSeprators } from '@/services/FormatUtilities'; import { addAlpha } from './ColorFunctions'; import { DoughnutData, DoughnutPlugin } from '@/types/DoughnutData'; export default function () { const doughnutRef: Ref = ref(null); const onHoverIndex: Ref<number | null> = ref(null); const backgroundColor: Ref<CanvasPattern[] | null> = ref(null); const centeredLabel: Ref = ref(null); function privateGetHtmlLegendPlugin( legendContainer: Ref, selectMode: Ref<boolean>, disableAccessibility: Ref<boolean>, patternsColors: Ref<string[]>, patternsList: Ref< (( hover: boolean, color: string, disableAccessibility: boolean ) => CanvasPattern)[] >, maxValueToDisplay: number, doughnutData: any, enableHoverFeature: Ref<boolean> ) { return getHtmlLegendPlugin( legendContainer, selectMode, onHoverIndex, disableAccessibility, patternsColors, patternsList, enableHoverFeature, maxValueToDisplay, doughnutData ); } function getBackgroundColor( patternsColors: string[], patternsList: (( hover: boolean, color: string, disableAccessibility: boolean ) => CanvasPattern)[], disableAccessibility: boolean, enableHoverFeature: boolean ) { if (onHoverIndex.value !== null && enableHoverFeature) { return patternsList.map((pattern, index) => onHoverIndex.value === index ? pattern(false, patternsColors[index], disableAccessibility) : pattern(true, patternsColors[index], disableAccessibility) ); } else { return patternsList.map((pattern, index) => pattern(false, patternsColors[index], disableAccessibility) ); } } function getBorderColor( patternsColors: string[], enableHoverFeature: boolean ): string[] { if (onHoverIndex.value !== null && enableHoverFeature) { return patternsColors.map((color, index) => onHoverIndex.value === index ? color : addAlpha(color, 0.2) ); } else { return patternsColors; } } function getOnHoverOptions() { return (_ignore: unknown, activeElements: Array<any>): void => { if (activeElements[0] !== undefined) { onHoverIndex.value = activeElements[0].element.$context.index; } else { onHoverIndex.value = null; } }; } const getFormatedText = (str: string) => { return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase(); }; function getCenteredLabelPlugin( doughnutData: DoughnutData[] ): DoughnutPlugin { return { id: 'centeredLabelPlugin', afterDatasetDraw: (chart) => { const selectedIndexes: Number[] = []; const arcElements = chart.getDatasetMeta(0).data; arcElements.forEach((arcElement: any, index: Number) => { if (arcElement.startAngle !== arcElement.endAngle) { selectedIndexes.push(index); } }); const total = (chart as any)._metasets[0]?._dataset?.raw_value ?.filter((_: any, index: Number) => selectedIndexes.includes(index)) .reduce((acc: number, currentValue: any) => acc + currentValue, 0); const unit = doughnutData[0].unit ?? ''; centeredLabel.value = `${formatWithThousandsSeprators(total)}${unit}`; } }; } function getDoughnutLabels( labels: string[], data: DoughnutData[], maxValues: number, othersLabel: string ) { let truncatedLabels = labels.slice(0); let truncatedData = data.slice(0); if (labels.length > maxValues) { truncatedData = groupDataAfterNthValue(data, maxValues); truncatedLabels = truncatedLabels.slice(0, maxValues - 1); truncatedLabels.push(othersLabel); } return truncatedLabels.map( (label: string, index: number) => `${getFormatedText(label)} (${formatWithThousandsSeprators( truncatedData[index].rate as number )} %)` ); } function groupDataAfterNthValue(data: DoughnutData[], maxValues: number) { if (maxValues < 1) { return data; } let truncatedData = data.slice(0); if (data.length > maxValues) { truncatedData = truncatedData.slice(0, maxValues); truncatedData[maxValues - 1] = data.slice(maxValues).reduce( (result, current) => { result.rate += current.rate; result.value += current.value; return result; }, { ...data[maxValues - 1] } ); } return truncatedData; } return { onHoverIndex, privateGetHtmlLegendPlugin, getOnHoverOptions, groupDataAfterNthValue, getDoughnutLabels, getBackgroundColor, getFormatedText, getBorderColor, backgroundColor, doughnutRef, getCenteredLabelPlugin, centeredLabel }; }