From 8f01469a419d594e9c248a9b890cfa6c57dff3e4 Mon Sep 17 00:00:00 2001 From: MaysWind Date: Thu, 16 Apr 2026 01:24:25 +0800 Subject: [PATCH] add active transaction days and transactions per active day to value metric in insights explorer --- src/core/explorer.ts | 4 ++++ src/locales/de.json | 2 ++ src/locales/en.json | 2 ++ src/locales/es.json | 2 ++ src/locales/fr.json | 2 ++ src/locales/it.json | 2 ++ src/locales/ja.json | 2 ++ src/locales/kn.json | 2 ++ src/locales/ko.json | 2 ++ src/locales/nl.json | 2 ++ src/locales/pt_BR.json | 2 ++ src/locales/ru.json | 2 ++ src/locales/sl.json | 2 ++ src/locales/ta.json | 2 ++ src/locales/th.json | 2 ++ src/locales/tr.json | 2 ++ src/locales/uk.json | 2 ++ src/locales/vi.json | 2 ++ src/locales/zh_Hans.json | 2 ++ src/locales/zh_Hant.json | 2 ++ src/stores/explorer.ts | 29 +++++++++++++++++++++++++++++ 21 files changed, 71 insertions(+) diff --git a/src/core/explorer.ts b/src/core/explorer.ts index f3652b78..02bd83ac 100644 --- a/src/core/explorer.ts +++ b/src/core/explorer.ts @@ -301,6 +301,8 @@ export class TransactionExplorerDataDimension implements NameValue { export enum TransactionExplorerValueMetricType { TransactionCount = 'transactionCount', + ActiveTransactionDays = 'activeTransactionDays', + TransactionsPerActiveDay = 'transactionsPerActiveDay', SourceIncomeAmountSum = 'sourceIncomeAmountSum', SourceExpenseAmountSum = 'sourceExpenseAmountSum', SourceNetIncomeAmountSum = 'sourceNetIncomeAmountSum', @@ -334,6 +336,8 @@ export class TransactionExplorerValueMetric implements NameValue { private static readonly allInstancesByValue: Record = {}; public static readonly TransactionCount = new TransactionExplorerValueMetric('Transaction Count', TransactionExplorerValueMetricType.TransactionCount, false, false, true); + public static readonly ActiveTransactionDays = new TransactionExplorerValueMetric('Active Transaction Days', TransactionExplorerValueMetricType.ActiveTransactionDays, false, false, true); + public static readonly TransactionsPerDay = new TransactionExplorerValueMetric('Transactions per Active Day', TransactionExplorerValueMetricType.TransactionsPerActiveDay, false, false, true); public static readonly SourceIncomeAmountSum = new TransactionExplorerValueMetric('Total Income', TransactionExplorerValueMetricType.SourceIncomeAmountSum, true, false, true); public static readonly SourceExpenseAmountSum = new TransactionExplorerValueMetric('Total Expense', TransactionExplorerValueMetricType.SourceExpenseAmountSum, true, false, true); public static readonly SourceNetIncomeAmountSum = new TransactionExplorerValueMetric('Net Income', TransactionExplorerValueMetricType.SourceNetIncomeAmountSum, true, false, true); diff --git a/src/locales/de.json b/src/locales/de.json index bbe7e96e..b1104e76 100644 --- a/src/locales/de.json +++ b/src/locales/de.json @@ -1806,6 +1806,8 @@ "Destination Account Currency": "Zielkonto-Währung", "Value Metric": "Wertmetrik", "Transaction Count": "Transaktionsanzahl", + "Active Transaction Days": "Active Transaction Days", + "Transactions per Active Day": "Transactions per Active Day", "Expense / Income Ratio": "Expense / Income Ratio", "Savings Rate": "Savings Rate", "Average Amount": "Durchschnittsbetrag", diff --git a/src/locales/en.json b/src/locales/en.json index 54cb0520..15731b8e 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1806,6 +1806,8 @@ "Destination Account Currency": "Destination Account Currency", "Value Metric": "Value Metric", "Transaction Count": "Transaction Count", + "Active Transaction Days": "Active Transaction Days", + "Transactions per Active Day": "Transactions per Active Day", "Expense / Income Ratio": "Expense / Income Ratio", "Savings Rate": "Savings Rate", "Average Amount": "Average Amount", diff --git a/src/locales/es.json b/src/locales/es.json index 3d1c0560..6dd9ea56 100644 --- a/src/locales/es.json +++ b/src/locales/es.json @@ -1806,6 +1806,8 @@ "Destination Account Currency": "Moneda de la cuenta de destino", "Value Metric": "Métrica de valor", "Transaction Count": "Recuento de transacciones", + "Active Transaction Days": "Active Transaction Days", + "Transactions per Active Day": "Transactions per Active Day", "Expense / Income Ratio": "Expense / Income Ratio", "Savings Rate": "Savings Rate", "Average Amount": "Importe Medio", diff --git a/src/locales/fr.json b/src/locales/fr.json index 25e22870..32f5c3ef 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -1806,6 +1806,8 @@ "Destination Account Currency": "Destination Account Currency", "Value Metric": "Value Metric", "Transaction Count": "Transaction Count", + "Active Transaction Days": "Active Transaction Days", + "Transactions per Active Day": "Transactions per Active Day", "Expense / Income Ratio": "Expense / Income Ratio", "Savings Rate": "Savings Rate", "Average Amount": "Average Amount", diff --git a/src/locales/it.json b/src/locales/it.json index 1aedc89e..29b0de5a 100644 --- a/src/locales/it.json +++ b/src/locales/it.json @@ -1806,6 +1806,8 @@ "Destination Account Currency": "Destination Account Currency", "Value Metric": "Value Metric", "Transaction Count": "Transaction Count", + "Active Transaction Days": "Active Transaction Days", + "Transactions per Active Day": "Transactions per Active Day", "Expense / Income Ratio": "Expense / Income Ratio", "Savings Rate": "Savings Rate", "Average Amount": "Average Amount", diff --git a/src/locales/ja.json b/src/locales/ja.json index 8eb15f0d..72fd811f 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -1806,6 +1806,8 @@ "Destination Account Currency": "Destination Account Currency", "Value Metric": "Value Metric", "Transaction Count": "Transaction Count", + "Active Transaction Days": "Active Transaction Days", + "Transactions per Active Day": "Transactions per Active Day", "Expense / Income Ratio": "Expense / Income Ratio", "Savings Rate": "Savings Rate", "Average Amount": "Average Amount", diff --git a/src/locales/kn.json b/src/locales/kn.json index b3dec4ba..ac39f242 100644 --- a/src/locales/kn.json +++ b/src/locales/kn.json @@ -1806,6 +1806,8 @@ "Destination Account Currency": "Destination Account Currency", "Value Metric": "Value Metric", "Transaction Count": "Transaction Count", + "Active Transaction Days": "Active Transaction Days", + "Transactions per Active Day": "Transactions per Active Day", "Expense / Income Ratio": "Expense / Income Ratio", "Savings Rate": "Savings Rate", "Average Amount": "Average Amount", diff --git a/src/locales/ko.json b/src/locales/ko.json index 7de59665..04dbfc0f 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -1806,6 +1806,8 @@ "Destination Account Currency": "목적지 계좌 통화", "Value Metric": "값 메트릭", "Transaction Count": "거래 수", + "Active Transaction Days": "Active Transaction Days", + "Transactions per Active Day": "Transactions per Active Day", "Expense / Income Ratio": "Expense / Income Ratio", "Savings Rate": "Savings Rate", "Average Amount": "평균 금액", diff --git a/src/locales/nl.json b/src/locales/nl.json index c86e2c0f..23e65070 100644 --- a/src/locales/nl.json +++ b/src/locales/nl.json @@ -1806,6 +1806,8 @@ "Destination Account Currency": "Destination Account Currency", "Value Metric": "Value Metric", "Transaction Count": "Transaction Count", + "Active Transaction Days": "Active Transaction Days", + "Transactions per Active Day": "Transactions per Active Day", "Expense / Income Ratio": "Expense / Income Ratio", "Savings Rate": "Savings Rate", "Average Amount": "Average Amount", diff --git a/src/locales/pt_BR.json b/src/locales/pt_BR.json index 10c1cc3e..39558efa 100644 --- a/src/locales/pt_BR.json +++ b/src/locales/pt_BR.json @@ -1806,6 +1806,8 @@ "Destination Account Currency": "Moeda da Conta de Destino", "Value Metric": "Métrica de Valor", "Transaction Count": "Quantidade de Transações", + "Active Transaction Days": "Active Transaction Days", + "Transactions per Active Day": "Transactions per Active Day", "Expense / Income Ratio": "Expense / Income Ratio", "Savings Rate": "Savings Rate", "Average Amount": "Valor Médio", diff --git a/src/locales/ru.json b/src/locales/ru.json index 3a485c69..a2c0a627 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -1806,6 +1806,8 @@ "Destination Account Currency": "Валюта целевого счёта", "Value Metric": "Метрика значения", "Transaction Count": "Количество транзакций", + "Active Transaction Days": "Active Transaction Days", + "Transactions per Active Day": "Transactions per Active Day", "Expense / Income Ratio": "Expense / Income Ratio", "Savings Rate": "Savings Rate", "Average Amount": "Средняя сумма", diff --git a/src/locales/sl.json b/src/locales/sl.json index 44a50f11..652c9d18 100644 --- a/src/locales/sl.json +++ b/src/locales/sl.json @@ -1806,6 +1806,8 @@ "Destination Account Currency": "Valuta ciljnega računa", "Value Metric": "Metrika vrednosti", "Transaction Count": "Število transakcij", + "Active Transaction Days": "Active Transaction Days", + "Transactions per Active Day": "Transactions per Active Day", "Expense / Income Ratio": "Expense / Income Ratio", "Savings Rate": "Savings Rate", "Average Amount": "Povprečni znesek", diff --git a/src/locales/ta.json b/src/locales/ta.json index c5e300b1..0a691941 100644 --- a/src/locales/ta.json +++ b/src/locales/ta.json @@ -1806,6 +1806,8 @@ "Destination Account Currency": "இலக்கு கணக்கு நாணயம்", "Value Metric": "மதிப்பு அளவீடு", "Transaction Count": "பரிவர்த்தனை எண்ணிக்கை", + "Active Transaction Days": "Active Transaction Days", + "Transactions per Active Day": "Transactions per Active Day", "Expense / Income Ratio": "Expense / Income Ratio", "Savings Rate": "Savings Rate", "Average Amount": "சராசரி தொகை", diff --git a/src/locales/th.json b/src/locales/th.json index ba8cfcd0..06f79de0 100644 --- a/src/locales/th.json +++ b/src/locales/th.json @@ -1806,6 +1806,8 @@ "Destination Account Currency": "Destination Account Currency", "Value Metric": "Value Metric", "Transaction Count": "Transaction Count", + "Active Transaction Days": "Active Transaction Days", + "Transactions per Active Day": "Transactions per Active Day", "Expense / Income Ratio": "Expense / Income Ratio", "Savings Rate": "Savings Rate", "Average Amount": "Average Amount", diff --git a/src/locales/tr.json b/src/locales/tr.json index 0c14b32a..3cad6d3d 100644 --- a/src/locales/tr.json +++ b/src/locales/tr.json @@ -1806,6 +1806,8 @@ "Destination Account Currency": "Destination Account Currency", "Value Metric": "Value Metric", "Transaction Count": "Transaction Count", + "Active Transaction Days": "Active Transaction Days", + "Transactions per Active Day": "Transactions per Active Day", "Expense / Income Ratio": "Expense / Income Ratio", "Savings Rate": "Savings Rate", "Average Amount": "Average Amount", diff --git a/src/locales/uk.json b/src/locales/uk.json index 5a48e6be..000b4f8e 100644 --- a/src/locales/uk.json +++ b/src/locales/uk.json @@ -1806,6 +1806,8 @@ "Destination Account Currency": "Destination Account Currency", "Value Metric": "Value Metric", "Transaction Count": "Transaction Count", + "Active Transaction Days": "Active Transaction Days", + "Transactions per Active Day": "Transactions per Active Day", "Expense / Income Ratio": "Expense / Income Ratio", "Savings Rate": "Savings Rate", "Average Amount": "Average Amount", diff --git a/src/locales/vi.json b/src/locales/vi.json index 96651347..04891c32 100644 --- a/src/locales/vi.json +++ b/src/locales/vi.json @@ -1806,6 +1806,8 @@ "Destination Account Currency": "Destination Account Currency", "Value Metric": "Value Metric", "Transaction Count": "Transaction Count", + "Active Transaction Days": "Active Transaction Days", + "Transactions per Active Day": "Transactions per Active Day", "Expense / Income Ratio": "Expense / Income Ratio", "Savings Rate": "Savings Rate", "Average Amount": "Average Amount", diff --git a/src/locales/zh_Hans.json b/src/locales/zh_Hans.json index b3a980bd..c7d0e8c1 100644 --- a/src/locales/zh_Hans.json +++ b/src/locales/zh_Hans.json @@ -1806,6 +1806,8 @@ "Destination Account Currency": "目标账户货币", "Value Metric": "值类型", "Transaction Count": "交易数量", + "Active Transaction Days": "活跃交易日", + "Transactions per Active Day": "每活跃日交易数量", "Expense / Income Ratio": "支出/收入比", "Savings Rate": "储蓄率", "Average Amount": "平均金额", diff --git a/src/locales/zh_Hant.json b/src/locales/zh_Hant.json index aa2adbcf..b0d8bdbc 100644 --- a/src/locales/zh_Hant.json +++ b/src/locales/zh_Hant.json @@ -1806,6 +1806,8 @@ "Destination Account Currency": "目標帳戶貨幣", "Value Metric": "值類型", "Transaction Count": "交易數量", + "Active Transaction Days": "活躍交易日數", + "Transactions per Active Day": "每活躍日交易數", "Expense / Income Ratio": "支出/收入比率", "Savings Rate": "儲蓄率", "Average Amount": "平均金額", diff --git a/src/stores/explorer.ts b/src/stores/explorer.ts index 4fc3668d..f167a89c 100644 --- a/src/stores/explorer.ts +++ b/src/stores/explorer.ts @@ -43,6 +43,7 @@ import { isNumber, isInteger, isEquals, + getObjectOwnFieldCount } from '@/lib/common.ts'; import { median, @@ -800,6 +801,11 @@ export const useExplorersStore = defineStore('explorers', () => { const defaultCurrency = userStore.currentUserDefaultCurrency; const result: CategoriedTransactionExplorerData[] = []; const categoriedDataMap = categoriedTransactions.value; + let needCalculateDailyTransactionCount: boolean = false; + + if (valueMetric === TransactionExplorerValueMetric.ActiveTransactionDays || valueMetric === TransactionExplorerValueMetric.TransactionsPerDay) { + needCalculateDailyTransactionCount = true; + } for (const categoriedTransactions of values(categoriedDataMap)) { const dataItems: CategoriedTransactionExplorerDataItem[] = []; @@ -824,6 +830,7 @@ export const useExplorersStore = defineStore('explorers', () => { } for (const seriesTransactions of values(allSeriesTransactions)) { + const transactionDateMapCount: Record = {}; const allSourceAmountsInDefaultCurrency: number[] = []; let totalSourceAmountSumInDefaultCurrency: number = 0; let totalSourceIncomeAmountSumInDefaultCurrency: number = 0; @@ -844,6 +851,23 @@ export const useExplorersStore = defineStore('explorers', () => { } } + if (needCalculateDailyTransactionCount) { + let transactionTimeUtfOffset: number | undefined = undefined; + + if (currentInsightsExplorer.value.timezoneUsedForDateRange === TimezoneTypeForStatistics.TransactionTimezone.type) { + transactionTimeUtfOffset = transaction.utcOffset; + } + + const transactionDateTime: DateTime = isDefined(transactionTimeUtfOffset) ? parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.time, transactionTimeUtfOffset) : parseDateTimeFromUnixTime(transaction.time); + const transactionYearMonthDay: string = transactionDateTime.getGregorianCalendarYearDashMonthDashDay(); + + if (transactionDateMapCount[transactionYearMonthDay]) { + transactionDateMapCount[transactionYearMonthDay]++; + } else { + transactionDateMapCount[transactionYearMonthDay] = 1; + } + } + allSourceAmountsInDefaultCurrency.push(amountInDefaultCurrency); totalSourceAmountSumInDefaultCurrency += amountInDefaultCurrency; @@ -866,6 +890,11 @@ export const useExplorersStore = defineStore('explorers', () => { if (valueMetric === TransactionExplorerValueMetric.TransactionCount) { value = allSourceAmountsInDefaultCurrency.length; + } else if (valueMetric === TransactionExplorerValueMetric.ActiveTransactionDays) { + value = getObjectOwnFieldCount(transactionDateMapCount); + } else if (valueMetric === TransactionExplorerValueMetric.TransactionsPerDay) { + const activeDays = getObjectOwnFieldCount(transactionDateMapCount); + value = activeDays > 0 ? allSourceAmountsInDefaultCurrency.length / activeDays : 0; } else if (valueMetric === TransactionExplorerValueMetric.SourceIncomeAmountSum) { value = totalSourceIncomeAmountSumInDefaultCurrency; } else if (valueMetric === TransactionExplorerValueMetric.SourceExpenseAmountSum) {