From 301fb58917af02af54e64a8dde339516b67912a0 Mon Sep 17 00:00:00 2001 From: MaysWind Date: Sat, 7 Mar 2026 21:16:03 +0800 Subject: [PATCH] hide some statistics when the number of transactions is not enough --- src/stores/explorer.ts | 47 ++++++++++--------- .../insights/tabs/ExplorerDataTableTab.vue | 12 ++--- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/stores/explorer.ts b/src/stores/explorer.ts index cb994963..fc20b0a8 100644 --- a/src/stores/explorer.ts +++ b/src/stores/explorer.ts @@ -120,14 +120,14 @@ export interface InsightsExplorerTransactionStatisticData { averageAmount: number; medianAmount: number; p90Amount: number; - top5AmountShare: number; - transactionsFor80PercentAmount: number; + top5AmountShare?: number; + transactionsFor80PercentAmount?: number; minimumAmount: number; maximumAmount: number; range: number; interquartileRange: number; - variance: number; - standardDeviation: number; + variance?: number; + standardDeviation?: number; } export const useExplorersStore = defineStore('explorers', () => { @@ -607,14 +607,14 @@ export const useExplorersStore = defineStore('explorers', () => { averageAmount: 0, medianAmount: 0, p90Amount: 0, - top5AmountShare: 0, - transactionsFor80PercentAmount: 0, + top5AmountShare: undefined, + transactionsFor80PercentAmount: undefined, minimumAmount: Number.MAX_SAFE_INTEGER, maximumAmount: Number.MIN_SAFE_INTEGER, range: 0, interquartileRange: 0, - variance: 0, - standardDeviation: 0 + variance: undefined, + standardDeviation: undefined }; const sourceAmounts: number[] = []; @@ -670,26 +670,29 @@ export const useExplorersStore = defineStore('explorers', () => { const top5Count = Math.ceil(sourceAmounts.length * 0.05); const top5AmountSum = sourceAmounts.slice(-top5Count).reduce((sum, amount) => sum + amount, 0); statisticData.top5AmountShare = statisticData.totalAmount > 0 ? 100.0 * top5AmountSum / statisticData.totalAmount : 0; - } else { - statisticData.top5AmountShare = 100.0; } - const eightyPercentAmountThreshold: number = 0.8 * statisticData.totalAmount; - let cumulativeAmount: number = 0; - let cumulativeCount: number = 0; - for (const amount of reversed(sourceAmounts)) { - cumulativeAmount += amount; - cumulativeCount++; + if (sourceAmounts.length > 0) { + const eightyPercentAmountThreshold: number = 0.8 * statisticData.totalAmount; + let cumulativeAmount: number = 0; + let cumulativeCount: number = 0; + for (const amount of reversed(sourceAmounts)) { + cumulativeAmount += amount; + cumulativeCount++; - if (cumulativeAmount >= eightyPercentAmountThreshold) { - statisticData.transactionsFor80PercentAmount = 100.0 * cumulativeCount / statisticData.totalCount; - break; + if (cumulativeAmount >= eightyPercentAmountThreshold) { + statisticData.transactionsFor80PercentAmount = 100.0 * cumulativeCount / statisticData.totalCount; + break; + } } } - const sumOfSquaredDifferences: number = sourceAmounts.reduce((sum, amount) => sum + Math.pow(amount / 100.0 - statisticData.averageAmount / 100.0, 2), 0); - statisticData.variance = sourceAmounts.length > 0 ? sumOfSquaredDifferences / sourceAmounts.length : 0; - statisticData.standardDeviation = Math.sqrt(statisticData.variance); + if (statisticData.totalCount > 0 && sourceAmounts.length > 0) { + const averageAmountForVarianceCalculation: number = statisticData.totalAmount / statisticData.totalCount / 100.0; + const sumOfSquaredDifferences: number = sourceAmounts.reduce((sum, amount) => sum + Math.pow(amount / 100.0 - averageAmountForVarianceCalculation, 2), 0); + statisticData.variance = sumOfSquaredDifferences / sourceAmounts.length; + statisticData.standardDeviation = Math.sqrt(statisticData.variance); + } return statisticData; }); diff --git a/src/views/desktop/insights/tabs/ExplorerDataTableTab.vue b/src/views/desktop/insights/tabs/ExplorerDataTableTab.vue index 7b321797..a216de60 100644 --- a/src/views/desktop/insights/tabs/ExplorerDataTableTab.vue +++ b/src/views/desktop/insights/tabs/ExplorerDataTableTab.vue @@ -41,7 +41,7 @@ {{ formatAmountToLocalizedNumeralsWithCurrency(filteredTransactionsStatistic.totalAmount) }} - + @@ -74,11 +74,11 @@ {{ tt('Top 5 Amount Share') }} - {{ formatPercentToLocalizedNumerals(filteredTransactionsStatistic.top5AmountShare, 2, '<0.01') }} + {{ isDefined(filteredTransactionsStatistic.top5AmountShare) ? formatPercentToLocalizedNumerals(filteredTransactionsStatistic.top5AmountShare, 2, '<0.01') : '-' }} {{ tt('Transactions for 80% of Amount') }} - {{ formatPercentToLocalizedNumerals(filteredTransactionsStatistic.transactionsFor80PercentAmount, 2, '<0.01') }} + {{ isDefined(filteredTransactionsStatistic.transactionsFor80PercentAmount) ? formatPercentToLocalizedNumerals(filteredTransactionsStatistic.transactionsFor80PercentAmount, 2, '<0.01') : '-' }} {{ tt('Minimum Amount') }} @@ -98,11 +98,11 @@ {{ tt('Variance') }} - {{ formatNumberToLocalizedNumerals(filteredTransactionsStatistic.variance, 2) }} + {{ isDefined(filteredTransactionsStatistic.variance) ? formatNumberToLocalizedNumerals(filteredTransactionsStatistic.variance, 2) : '-' }} {{ tt('Standard Deviation') }} - {{ formatNumberToLocalizedNumerals(filteredTransactionsStatistic.standardDeviation, 2) }} + {{ isDefined(filteredTransactionsStatistic.standardDeviation) ? formatNumberToLocalizedNumerals(filteredTransactionsStatistic.standardDeviation, 2) : '-' }} @@ -218,7 +218,7 @@ import { TransactionType } from '@/core/transaction.ts'; import type { TransactionInsightDataItem } from '@/models/transaction.ts'; import type { InsightsExplorer} from '@/models/explorer.ts'; -import { replaceAll } from '@/lib/common.ts'; +import { isDefined, replaceAll } from '@/lib/common.ts'; import { getUtcOffsetByUtcOffsetMinutes,