hide some statistics when the number of transactions is not enough

This commit is contained in:
MaysWind
2026-03-07 21:16:03 +08:00
parent aedebb1461
commit 301fb58917
2 changed files with 31 additions and 28 deletions
+15 -12
View File
@@ -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,10 +670,9 @@ 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;
}
if (sourceAmounts.length > 0) {
const eightyPercentAmountThreshold: number = 0.8 * statisticData.totalAmount;
let cumulativeAmount: number = 0;
let cumulativeCount: number = 0;
@@ -686,10 +685,14 @@ export const useExplorersStore = defineStore('explorers', () => {
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;
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;
});
@@ -41,7 +41,7 @@
<span class="text-subtitle-1 ms-2" v-else-if="!loading && filteredTransactionsStatistic">
{{ formatAmountToLocalizedNumeralsWithCurrency(filteredTransactionsStatistic.totalAmount) }}
</span>
<v-tooltip interactive class="table-tooltip" activator="parent" v-if="!loading && filteredTransactionsStatistic">
<v-tooltip interactive class="table-tooltip" activator="parent" v-if="!loading && filteredTransactions.length > 0 && filteredTransactionsStatistic">
<v-table density="compact">
<tbody>
<tr>
@@ -74,11 +74,11 @@
</tr>
<tr>
<td>{{ tt('Top 5 Amount Share') }}</td>
<td class="text-end">{{ formatPercentToLocalizedNumerals(filteredTransactionsStatistic.top5AmountShare, 2, '<0.01') }}</td>
<td class="text-end">{{ isDefined(filteredTransactionsStatistic.top5AmountShare) ? formatPercentToLocalizedNumerals(filteredTransactionsStatistic.top5AmountShare, 2, '<0.01') : '-' }}</td>
</tr>
<tr>
<td>{{ tt('Transactions for 80% of Amount') }}</td>
<td class="text-end">{{ formatPercentToLocalizedNumerals(filteredTransactionsStatistic.transactionsFor80PercentAmount, 2, '<0.01') }}</td>
<td class="text-end">{{ isDefined(filteredTransactionsStatistic.transactionsFor80PercentAmount) ? formatPercentToLocalizedNumerals(filteredTransactionsStatistic.transactionsFor80PercentAmount, 2, '<0.01') : '-' }}</td>
</tr>
<tr>
<td>{{ tt('Minimum Amount') }}</td>
@@ -98,11 +98,11 @@
</tr>
<tr>
<td>{{ tt('Variance') }}</td>
<td class="text-end">{{ formatNumberToLocalizedNumerals(filteredTransactionsStatistic.variance, 2) }}</td>
<td class="text-end">{{ isDefined(filteredTransactionsStatistic.variance) ? formatNumberToLocalizedNumerals(filteredTransactionsStatistic.variance, 2) : '-' }}</td>
</tr>
<tr>
<td>{{ tt('Standard Deviation') }}</td>
<td class="text-end">{{ formatNumberToLocalizedNumerals(filteredTransactionsStatistic.standardDeviation, 2) }}</td>
<td class="text-end">{{ isDefined(filteredTransactionsStatistic.standardDeviation) ? formatNumberToLocalizedNumerals(filteredTransactionsStatistic.standardDeviation, 2) : '-' }}</td>
</tr>
</tbody>
</v-table>
@@ -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,