From 28322bad5e0551ca9912f854bba3daddd840fbaf Mon Sep 17 00:00:00 2001 From: MaysWind Date: Thu, 23 Jan 2025 21:57:53 +0800 Subject: [PATCH] code refactor --- src/components/base/PieChartBase.ts | 96 +++++++++++ src/components/desktop/PieChart.vue | 97 +++-------- src/components/mobile/PieChart.vue | 162 ++++++------------ .../mobile/statistics/TransactionPage.vue | 1 + 4 files changed, 167 insertions(+), 189 deletions(-) create mode 100644 src/components/base/PieChartBase.ts diff --git a/src/components/base/PieChartBase.ts b/src/components/base/PieChartBase.ts new file mode 100644 index 00000000..0c779273 --- /dev/null +++ b/src/components/base/PieChartBase.ts @@ -0,0 +1,96 @@ +import { ref, computed, watch } from 'vue'; + +import { useI18n } from '@/locales/helpers.ts'; + +import { DEFAULT_CHART_COLORS } from '@/consts/color.ts'; + +import { isNumber } from '@/lib/common.ts'; +import { formatPercent } from '@/lib/numeral.ts'; + +export interface CommonPieChartDataItem { + id: string; + name: string; + displayName: string; + value: number; + percent: number; + actualPercent: number; + color: string; + sourceItem: Record; + displayPercent?: string; + displayValue?: string; +} + +export interface CommonPieChartProps { + skeleton?: boolean; + items: Record[]; + idField?: string; + nameField: string; + valueField: string; + percentField?: string; + colorField?: string; + hiddenField?: string; + minValidPercent?: number; + defaultCurrency?: string; + showValue?: boolean; + enableClickItem?: boolean; +} + +export function usePieChartBase(props: CommonPieChartProps) { + const { formatAmountWithCurrency } = useI18n(); + + const selectedIndex = ref(0); + + const validItems = computed(() => { + let totalValidValue = 0; + + for (let i = 0; i < props.items.length; i++) { + const item = props.items[i]; + const value = item[props.valueField]; + + if (isNumber(value) && value > 0 && (!props.hiddenField || !item[props.hiddenField])) { + totalValidValue += value; + } + } + + const validItems: CommonPieChartDataItem[] = []; + + for (let i = 0; i < props.items.length; i++) { + const item = props.items[i]; + const value = item[props.valueField]; + const percent = props.percentField ? item[props.percentField] : -1; + + if (isNumber(value) && value > 0 && + (!props.hiddenField || !item[props.hiddenField]) && + (!props.minValidPercent || value / totalValidValue > props.minValidPercent)) { + const finalItem: CommonPieChartDataItem = { + id: (props.idField && item[props.idField]) ? item[props.idField] as string : item[props.nameField] as string, + name: (props.idField && item[props.idField]) ? item[props.idField] as string : item[props.nameField] as string, + displayName: item[props.nameField] as string, + value: value, + percent: (isNumber(percent) && percent >= 0) ? percent : (value / totalValidValue * 100), + actualPercent: value / totalValidValue, + color: (props.colorField && item[props.colorField]) ? item[props.colorField] as string : DEFAULT_CHART_COLORS[validItems.length % DEFAULT_CHART_COLORS.length], + sourceItem: item + }; + + finalItem.displayPercent = formatPercent(finalItem.percent, 2, '<0.01'); + finalItem.displayValue = formatAmountWithCurrency(finalItem.value, props.defaultCurrency) as string; + + validItems.push(finalItem); + } + } + + return validItems; + }); + + watch(() => props.items, () => { + selectedIndex.value = 0; + }); + + return { + // states + selectedIndex, + // computed states + validItems + }; +} diff --git a/src/components/desktop/PieChart.vue b/src/components/desktop/PieChart.vue index 08d5f643..33752399 100644 --- a/src/components/desktop/PieChart.vue +++ b/src/components/desktop/PieChart.vue @@ -4,51 +4,29 @@