add skewness and kurtosis to value metric in insights explorer
This commit is contained in:
@@ -81,8 +81,9 @@ import {
|
|||||||
|
|
||||||
import { NumeralSystem, DecimalSeparator } from '@/core/numeral.ts';
|
import { NumeralSystem, DecimalSeparator } from '@/core/numeral.ts';
|
||||||
import type { CurrencyPrependAndAppendText } from '@/core/currency.ts';
|
import type { CurrencyPrependAndAppendText } from '@/core/currency.ts';
|
||||||
import { DEFAULT_DECIMAL_NUMBER_COUNT } from '@/consts/numeral.ts';
|
import { DEFAULT_DECIMAL_NUMBER_COUNT, AMOUNT_FACTOR } from '@/consts/numeral.ts';
|
||||||
import { TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT } from '@/consts/transaction.ts';
|
import { TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT } from '@/consts/transaction.ts';
|
||||||
|
|
||||||
import { isNumber, replaceAll } from '@/lib/common.ts';
|
import { isNumber, replaceAll } from '@/lib/common.ts';
|
||||||
import { evaluateExpressionToAmount } from '@/lib/evaluator.ts';
|
import { evaluateExpressionToAmount } from '@/lib/evaluator.ts';
|
||||||
import type { ComponentDensity, InputVariant } from '@/lib/ui/desktop.ts';
|
import type { ComponentDensity, InputVariant } from '@/lib/ui/desktop.ts';
|
||||||
@@ -297,7 +298,7 @@ function getFormattedValue(value: number): string {
|
|||||||
|
|
||||||
function getDisplayCurrencyPrependAndAppendText(): CurrencyPrependAndAppendText | null {
|
function getDisplayCurrencyPrependAndAppendText(): CurrencyPrependAndAppendText | null {
|
||||||
const numericCurrentValue = parseAmountFromLocalizedNumerals(currentValue.value);
|
const numericCurrentValue = parseAmountFromLocalizedNumerals(currentValue.value);
|
||||||
const isPlural = numericCurrentValue !== 100 && numericCurrentValue !== -100;
|
const isPlural = numericCurrentValue !== AMOUNT_FACTOR && numericCurrentValue !== -AMOUNT_FACTOR;
|
||||||
|
|
||||||
return getAmountPrependAndAppendText(props.currency, isPlural);
|
return getAmountPrependAndAppendText(props.currency, isPlural);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ import { useI18n } from '@/locales/helpers.ts';
|
|||||||
import { useI18nUIComponents, isiOS } from '@/lib/ui/mobile.ts';
|
import { useI18nUIComponents, isiOS } from '@/lib/ui/mobile.ts';
|
||||||
|
|
||||||
import { NumeralSystem } from '@/core/numeral.ts';
|
import { NumeralSystem } from '@/core/numeral.ts';
|
||||||
|
import { AMOUNT_FACTOR } from '@/consts/numeral.ts';
|
||||||
import { ALL_CURRENCIES } from '@/consts/currency.ts';
|
import { ALL_CURRENCIES } from '@/consts/currency.ts';
|
||||||
import { isNumber } from '@/lib/common.ts';
|
import { isNumber } from '@/lib/common.ts';
|
||||||
import logger from '@/lib/logger.ts';
|
import logger from '@/lib/logger.ts';
|
||||||
@@ -385,7 +386,7 @@ function confirm(): boolean {
|
|||||||
finalValue = previous - current;
|
finalValue = previous - current;
|
||||||
break;
|
break;
|
||||||
case '×':
|
case '×':
|
||||||
finalValue = Math.trunc(previous * current / 100);
|
finalValue = Math.trunc(previous * current / AMOUNT_FACTOR);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
finalValue = previous;
|
finalValue = previous;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import type { HiddenAmount } from '@/core/numeral.ts';
|
|||||||
|
|
||||||
export const DEFAULT_DECIMAL_NUMBER_COUNT: number = 2;
|
export const DEFAULT_DECIMAL_NUMBER_COUNT: number = 2;
|
||||||
export const MAX_SUPPORTED_DECIMAL_NUMBER_COUNT: number = 2;
|
export const MAX_SUPPORTED_DECIMAL_NUMBER_COUNT: number = 2;
|
||||||
|
export const AMOUNT_FACTOR: number = 10 ** MAX_SUPPORTED_DECIMAL_NUMBER_COUNT;
|
||||||
|
|
||||||
export const DISPLAY_HIDDEN_AMOUNT: HiddenAmount = '***';
|
export const DISPLAY_HIDDEN_AMOUNT: HiddenAmount = '***';
|
||||||
export const INCOMPLETE_AMOUNT_SUFFIX: string = '+';
|
export const INCOMPLETE_AMOUNT_SUFFIX: string = '+';
|
||||||
|
|||||||
@@ -324,7 +324,9 @@ export enum TransactionExplorerValueMetricType {
|
|||||||
SourceAmountInterquartileRange = 'sourceAmountInterquartileRange',
|
SourceAmountInterquartileRange = 'sourceAmountInterquartileRange',
|
||||||
SourceAmountVariance = 'sourceAmountVariance',
|
SourceAmountVariance = 'sourceAmountVariance',
|
||||||
SourceAmountStandardDeviation = 'sourceAmountStandardDeviation',
|
SourceAmountStandardDeviation = 'sourceAmountStandardDeviation',
|
||||||
SourceAmountCoefficientOfVariation = 'sourceAmountCoefficientOfVariation'
|
SourceAmountCoefficientOfVariation = 'sourceAmountCoefficientOfVariation',
|
||||||
|
SourceAmountSkewness = 'sourceAmountSkewness',
|
||||||
|
SourceAmountKurtosis = 'sourceAmountKurtosis'
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TransactionExplorerValueMetric implements NameValue {
|
export class TransactionExplorerValueMetric implements NameValue {
|
||||||
@@ -356,6 +358,8 @@ export class TransactionExplorerValueMetric implements NameValue {
|
|||||||
public static readonly SourceAmountVariance = new TransactionExplorerValueMetric('Variance', TransactionExplorerValueMetricType.SourceAmountVariance, false, false, false);
|
public static readonly SourceAmountVariance = new TransactionExplorerValueMetric('Variance', TransactionExplorerValueMetricType.SourceAmountVariance, false, false, false);
|
||||||
public static readonly SourceAmountStandardDeviation = new TransactionExplorerValueMetric('Standard Deviation', TransactionExplorerValueMetricType.SourceAmountStandardDeviation, false, false, false);
|
public static readonly SourceAmountStandardDeviation = new TransactionExplorerValueMetric('Standard Deviation', TransactionExplorerValueMetricType.SourceAmountStandardDeviation, false, false, false);
|
||||||
public static readonly SourceAmountCoefficientOfVariation = new TransactionExplorerValueMetric('Coefficient of Variation', TransactionExplorerValueMetricType.SourceAmountCoefficientOfVariation, false, false, false);
|
public static readonly SourceAmountCoefficientOfVariation = new TransactionExplorerValueMetric('Coefficient of Variation', TransactionExplorerValueMetricType.SourceAmountCoefficientOfVariation, false, false, false);
|
||||||
|
public static readonly SourceAmountSkewness = new TransactionExplorerValueMetric('Skewness', TransactionExplorerValueMetricType.SourceAmountSkewness, false, false, false);
|
||||||
|
public static readonly SourceAmountKurtosis = new TransactionExplorerValueMetric('Kurtosis', TransactionExplorerValueMetricType.SourceAmountKurtosis, false, false, false);
|
||||||
|
|
||||||
public static readonly Default = TransactionExplorerValueMetric.SourceAmountSum;
|
public static readonly Default = TransactionExplorerValueMetric.SourceAmountSum;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { AMOUNT_FACTOR } from '@/consts/numeral.ts';
|
||||||
import { TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT } from '../consts/transaction.ts';
|
import { TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT } from '../consts/transaction.ts';
|
||||||
|
|
||||||
import { replaceAll } from './common.ts';
|
import { replaceAll } from './common.ts';
|
||||||
@@ -10,7 +11,7 @@ type OperatorAndParenthesis = Operator | '(' | ')';
|
|||||||
const maxAllowedDecimalCount = 6;
|
const maxAllowedDecimalCount = 6;
|
||||||
const normalizeFactor: number = 1000000;
|
const normalizeFactor: number = 1000000;
|
||||||
const normalizedDecimalsMaxZeroString: string = '000000';
|
const normalizedDecimalsMaxZeroString: string = '000000';
|
||||||
const normalizedNumberToAmountFactor: number = 10000; // 1000000 / 100
|
const normalizedNumberToAmountFactor: number = normalizeFactor / AMOUNT_FACTOR;
|
||||||
|
|
||||||
const operatorPriority: Record<Operator, number> = {
|
const operatorPriority: Record<Operator, number> = {
|
||||||
'+': 1,
|
'+': 1,
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { reversed } from '@/core/base.ts';
|
||||||
|
|
||||||
export function mean<T>(values: T[], valueFn: (item: T) => number): number {
|
export function mean<T>(values: T[], valueFn: (item: T) => number): number {
|
||||||
if (values.length < 1) {
|
if (values.length < 1) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -59,3 +61,80 @@ export function sumMaxN<T>(sortedValues: T[], n: number, valueFn: (item: T) => n
|
|||||||
|
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function cumulativePercentage<T>(sortedValues: T[], percentageThreshold: number, totalValue: number, valueFn: (item: T) => number): number {
|
||||||
|
if (sortedValues.length < 1 || percentageThreshold < 0 || percentageThreshold > 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const thresholdValue: number = percentageThreshold * totalValue;
|
||||||
|
let cumulativeValue: number = 0;
|
||||||
|
let cumulativeCount: number = 0;
|
||||||
|
|
||||||
|
for (const item of reversed(sortedValues)) {
|
||||||
|
cumulativeValue += valueFn(item);
|
||||||
|
cumulativeCount++;
|
||||||
|
|
||||||
|
if (cumulativeValue >= thresholdValue) {
|
||||||
|
return 100.0 * cumulativeCount / sortedValues.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function varianceAndStandardDeviation<T>(values: T[], meanValue: number, valueFn: (item: T) => number): { variance: number; standardDeviation: number } {
|
||||||
|
if (values.length < 1) {
|
||||||
|
return { variance: 0, standardDeviation: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
let sumOfSquaredDifferences: number = 0;
|
||||||
|
|
||||||
|
for (const item of values) {
|
||||||
|
const difference: number = valueFn(item) - meanValue;
|
||||||
|
sumOfSquaredDifferences += difference * difference;
|
||||||
|
}
|
||||||
|
|
||||||
|
const variance: number = sumOfSquaredDifferences / values.length;
|
||||||
|
const standardDeviation: number = Math.sqrt(variance);
|
||||||
|
|
||||||
|
return { variance, standardDeviation };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function coefficientOfVariation(standardDeviation: number, meanValue: number): number | undefined {
|
||||||
|
if (meanValue === 0) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return standardDeviation / meanValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function skewness<T>(values: T[], meanValue: number, standardDeviation: number, valueFn: (item: T) => number): number {
|
||||||
|
if (values.length < 1 || standardDeviation === 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let sumOfCubedDifferences: number = 0;
|
||||||
|
|
||||||
|
for (const item of values) {
|
||||||
|
const difference: number = valueFn(item) - meanValue;
|
||||||
|
sumOfCubedDifferences += Math.pow(difference, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sumOfCubedDifferences / (values.length * Math.pow(standardDeviation, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function kurtosis<T>(values: T[], meanValue: number, variance: number, valueFn: (item: T) => number): number {
|
||||||
|
if (values.length < 1 || variance === 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let sumOfQuarticDifferences: number = 0;
|
||||||
|
|
||||||
|
for (const item of values) {
|
||||||
|
const difference: number = valueFn(item) - meanValue;
|
||||||
|
sumOfQuarticDifferences += Math.pow(difference, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sumOfQuarticDifferences / (values.length * Math.pow(variance, 2));
|
||||||
|
}
|
||||||
|
|||||||
+10
-7
@@ -6,6 +6,8 @@ import {
|
|||||||
DigitGroupingSymbol
|
DigitGroupingSymbol
|
||||||
} from '@/core/numeral.ts';
|
} from '@/core/numeral.ts';
|
||||||
|
|
||||||
|
import { AMOUNT_FACTOR } from '@/consts/numeral.ts';
|
||||||
|
|
||||||
import { DEFAULT_DECIMAL_NUMBER_COUNT, MAX_SUPPORTED_DECIMAL_NUMBER_COUNT, DISPLAY_HIDDEN_AMOUNT } from '@/consts/numeral.ts';
|
import { DEFAULT_DECIMAL_NUMBER_COUNT, MAX_SUPPORTED_DECIMAL_NUMBER_COUNT, DISPLAY_HIDDEN_AMOUNT } from '@/consts/numeral.ts';
|
||||||
|
|
||||||
import { isDefined, isString, isNumber, replaceAll, removeAll } from './common.ts';
|
import { isDefined, isString, isNumber, replaceAll, removeAll } from './common.ts';
|
||||||
@@ -115,7 +117,7 @@ export function parseAmount(str: string, options: NumberFormatOptions): number {
|
|||||||
let decimalSeparatorPos = str.indexOf(decimalSeparator);
|
let decimalSeparatorPos = str.indexOf(decimalSeparator);
|
||||||
|
|
||||||
if (decimalSeparatorPos < 0) {
|
if (decimalSeparatorPos < 0) {
|
||||||
return sign * numeralSystem.parseInt(str) * 100;
|
return sign * numeralSystem.parseInt(str) * AMOUNT_FACTOR;
|
||||||
} else if (decimalSeparatorPos === 0) {
|
} else if (decimalSeparatorPos === 0) {
|
||||||
str = numeralSystem.digitZero + str;
|
str = numeralSystem.digitZero + str;
|
||||||
decimalSeparatorPos++;
|
decimalSeparatorPos++;
|
||||||
@@ -125,13 +127,13 @@ export function parseAmount(str: string, options: NumberFormatOptions): number {
|
|||||||
const decimals = str.substring(decimalSeparatorPos + 1, str.length);
|
const decimals = str.substring(decimalSeparatorPos + 1, str.length);
|
||||||
|
|
||||||
if (decimals.length < 1) {
|
if (decimals.length < 1) {
|
||||||
return sign * numeralSystem.parseInt(integer) * 100;
|
return sign * numeralSystem.parseInt(integer) * AMOUNT_FACTOR;
|
||||||
} else if (decimals.length === 1) {
|
} else if (decimals.length === 1) {
|
||||||
return sign * numeralSystem.parseInt(integer) * 100 + sign * numeralSystem.parseInt(decimals) * 10;
|
return sign * numeralSystem.parseInt(integer) * AMOUNT_FACTOR + sign * numeralSystem.parseInt(decimals) * AMOUNT_FACTOR / 10;
|
||||||
} else if (decimals.length === 2) {
|
} else if (decimals.length === 2) {
|
||||||
return sign * numeralSystem.parseInt(integer) * 100 + sign * numeralSystem.parseInt(decimals);
|
return sign * numeralSystem.parseInt(integer) * AMOUNT_FACTOR + sign * numeralSystem.parseInt(decimals);
|
||||||
} else {
|
} else {
|
||||||
return sign * numeralSystem.parseInt(integer) * 100 + sign * numeralSystem.parseInt(decimals.substring(0, 2));
|
return sign * numeralSystem.parseInt(integer) * AMOUNT_FACTOR + sign * numeralSystem.parseInt(decimals.substring(0, 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,9 +254,10 @@ export function formatPercent(value: number, precision: number, lowPrecisionValu
|
|||||||
|
|
||||||
export function getAmountWithDecimalNumberCount(amount: number, decimalNumberCount: number): number {
|
export function getAmountWithDecimalNumberCount(amount: number, decimalNumberCount: number): number {
|
||||||
if (decimalNumberCount === 0) {
|
if (decimalNumberCount === 0) {
|
||||||
return Math.trunc(amount / 100) * 100;
|
return Math.trunc(amount / AMOUNT_FACTOR) * AMOUNT_FACTOR;
|
||||||
} else if (decimalNumberCount === 1) {
|
} else if (decimalNumberCount === 1) {
|
||||||
return Math.trunc(amount / 10) * 10;
|
const factor = AMOUNT_FACTOR / 10;
|
||||||
|
return Math.trunc(amount / factor) * factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
return amount;
|
return amount;
|
||||||
|
|||||||
@@ -1824,6 +1824,8 @@
|
|||||||
"Variance": "Varianz",
|
"Variance": "Varianz",
|
||||||
"Standard Deviation": "Standardabweichung",
|
"Standard Deviation": "Standardabweichung",
|
||||||
"Coefficient of Variation": "Variationskoeffizient",
|
"Coefficient of Variation": "Variationskoeffizient",
|
||||||
|
"Skewness": "Skewness",
|
||||||
|
"Kurtosis": "Kurtosis",
|
||||||
"Account List": "Kontoliste",
|
"Account List": "Kontoliste",
|
||||||
"This Week": "Diese Woche",
|
"This Week": "Diese Woche",
|
||||||
"This Month": "Dieser Monat",
|
"This Month": "Dieser Monat",
|
||||||
|
|||||||
@@ -1824,6 +1824,8 @@
|
|||||||
"Variance": "Variance",
|
"Variance": "Variance",
|
||||||
"Standard Deviation": "Standard Deviation",
|
"Standard Deviation": "Standard Deviation",
|
||||||
"Coefficient of Variation": "Coefficient of Variation",
|
"Coefficient of Variation": "Coefficient of Variation",
|
||||||
|
"Skewness": "Skewness",
|
||||||
|
"Kurtosis": "Kurtosis",
|
||||||
"Account List": "Account List",
|
"Account List": "Account List",
|
||||||
"This Week": "This Week",
|
"This Week": "This Week",
|
||||||
"This Month": "This Month",
|
"This Month": "This Month",
|
||||||
|
|||||||
@@ -1824,6 +1824,8 @@
|
|||||||
"Variance": "Variance",
|
"Variance": "Variance",
|
||||||
"Standard Deviation": "Standard Deviation",
|
"Standard Deviation": "Standard Deviation",
|
||||||
"Coefficient of Variation": "Coefficient of Variation",
|
"Coefficient of Variation": "Coefficient of Variation",
|
||||||
|
"Skewness": "Skewness",
|
||||||
|
"Kurtosis": "Kurtosis",
|
||||||
"Account List": "Lista de Cuentas",
|
"Account List": "Lista de Cuentas",
|
||||||
"This Week": "Esta Semana",
|
"This Week": "Esta Semana",
|
||||||
"This Month": "Este Mes",
|
"This Month": "Este Mes",
|
||||||
|
|||||||
@@ -1824,6 +1824,8 @@
|
|||||||
"Variance": "Variance",
|
"Variance": "Variance",
|
||||||
"Standard Deviation": "Standard Deviation",
|
"Standard Deviation": "Standard Deviation",
|
||||||
"Coefficient of Variation": "Coefficient of Variation",
|
"Coefficient of Variation": "Coefficient of Variation",
|
||||||
|
"Skewness": "Skewness",
|
||||||
|
"Kurtosis": "Kurtosis",
|
||||||
"Account List": "Liste des comptes",
|
"Account List": "Liste des comptes",
|
||||||
"This Week": "Cette semaine",
|
"This Week": "Cette semaine",
|
||||||
"This Month": "Ce mois",
|
"This Month": "Ce mois",
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ import {
|
|||||||
import type { LocaleDefaultSettings } from '@/core/setting.ts';
|
import type { LocaleDefaultSettings } from '@/core/setting.ts';
|
||||||
import type { ErrorResponse } from '@/core/api.ts';
|
import type { ErrorResponse } from '@/core/api.ts';
|
||||||
|
|
||||||
import { DISPLAY_HIDDEN_AMOUNT, INCOMPLETE_AMOUNT_SUFFIX } from '@/consts/numeral.ts';
|
import { AMOUNT_FACTOR, DISPLAY_HIDDEN_AMOUNT, INCOMPLETE_AMOUNT_SUFFIX } from '@/consts/numeral.ts';
|
||||||
import { UTC_TIMEZONE, ALL_TIMEZONES } from '@/consts/timezone.ts';
|
import { UTC_TIMEZONE, ALL_TIMEZONES } from '@/consts/timezone.ts';
|
||||||
import { ALL_CURRENCIES } from '@/consts/currency.ts';
|
import { ALL_CURRENCIES } from '@/consts/currency.ts';
|
||||||
import { DEFAULT_EXPENSE_CATEGORIES, DEFAULT_INCOME_CATEGORIES, DEFAULT_TRANSFER_CATEGORIES } from '@/consts/category.ts';
|
import { DEFAULT_EXPENSE_CATEGORIES, DEFAULT_INCOME_CATEGORIES, DEFAULT_TRANSFER_CATEGORIES } from '@/consts/category.ts';
|
||||||
@@ -2189,7 +2189,7 @@ export function useI18n() {
|
|||||||
const currencyName = getCurrencyName(finalCurrencyCode);
|
const currencyName = getCurrencyName(finalCurrencyCode);
|
||||||
|
|
||||||
if (isNumber(value)) {
|
if (isNumber(value)) {
|
||||||
const isPlural: boolean = value !== 100 && value !== -100;
|
const isPlural: boolean = value !== AMOUNT_FACTOR && value !== -AMOUNT_FACTOR;
|
||||||
const textualValue = formatAmount(value, numberFormatOptions);
|
const textualValue = formatAmount(value, numberFormatOptions);
|
||||||
|
|
||||||
if (!finalCurrencyCode) {
|
if (!finalCurrencyCode) {
|
||||||
|
|||||||
@@ -1824,6 +1824,8 @@
|
|||||||
"Variance": "Variance",
|
"Variance": "Variance",
|
||||||
"Standard Deviation": "Standard Deviation",
|
"Standard Deviation": "Standard Deviation",
|
||||||
"Coefficient of Variation": "Coefficient of Variation",
|
"Coefficient of Variation": "Coefficient of Variation",
|
||||||
|
"Skewness": "Skewness",
|
||||||
|
"Kurtosis": "Kurtosis",
|
||||||
"Account List": "Elenco account",
|
"Account List": "Elenco account",
|
||||||
"This Week": "Questa settimana",
|
"This Week": "Questa settimana",
|
||||||
"This Month": "Questo mese",
|
"This Month": "Questo mese",
|
||||||
|
|||||||
@@ -1824,6 +1824,8 @@
|
|||||||
"Variance": "Variance",
|
"Variance": "Variance",
|
||||||
"Standard Deviation": "Standard Deviation",
|
"Standard Deviation": "Standard Deviation",
|
||||||
"Coefficient of Variation": "Coefficient of Variation",
|
"Coefficient of Variation": "Coefficient of Variation",
|
||||||
|
"Skewness": "Skewness",
|
||||||
|
"Kurtosis": "Kurtosis",
|
||||||
"Account List": "口座リスト",
|
"Account List": "口座リスト",
|
||||||
"This Week": "今週",
|
"This Week": "今週",
|
||||||
"This Month": "今月",
|
"This Month": "今月",
|
||||||
|
|||||||
@@ -1824,6 +1824,8 @@
|
|||||||
"Variance": "Variance",
|
"Variance": "Variance",
|
||||||
"Standard Deviation": "Standard Deviation",
|
"Standard Deviation": "Standard Deviation",
|
||||||
"Coefficient of Variation": "Coefficient of Variation",
|
"Coefficient of Variation": "Coefficient of Variation",
|
||||||
|
"Skewness": "Skewness",
|
||||||
|
"Kurtosis": "Kurtosis",
|
||||||
"Account List": "ಖಾತೆಗಳ ಪಟ್ಟಿ",
|
"Account List": "ಖಾತೆಗಳ ಪಟ್ಟಿ",
|
||||||
"This Week": "ಈ ವಾರ",
|
"This Week": "ಈ ವಾರ",
|
||||||
"This Month": "ಈ ತಿಂಗಳು",
|
"This Month": "ಈ ತಿಂಗಳು",
|
||||||
|
|||||||
@@ -1824,6 +1824,8 @@
|
|||||||
"Variance": "Variance",
|
"Variance": "Variance",
|
||||||
"Standard Deviation": "Standard Deviation",
|
"Standard Deviation": "Standard Deviation",
|
||||||
"Coefficient of Variation": "Coefficient of Variation",
|
"Coefficient of Variation": "Coefficient of Variation",
|
||||||
|
"Skewness": "Skewness",
|
||||||
|
"Kurtosis": "Kurtosis",
|
||||||
"Account List": "계좌 목록",
|
"Account List": "계좌 목록",
|
||||||
"This Week": "이번 주",
|
"This Week": "이번 주",
|
||||||
"This Month": "이번 달",
|
"This Month": "이번 달",
|
||||||
|
|||||||
@@ -1824,6 +1824,8 @@
|
|||||||
"Variance": "Variance",
|
"Variance": "Variance",
|
||||||
"Standard Deviation": "Standard Deviation",
|
"Standard Deviation": "Standard Deviation",
|
||||||
"Coefficient of Variation": "Coefficient of Variation",
|
"Coefficient of Variation": "Coefficient of Variation",
|
||||||
|
"Skewness": "Skewness",
|
||||||
|
"Kurtosis": "Kurtosis",
|
||||||
"Account List": "Rekeningenlijst",
|
"Account List": "Rekeningenlijst",
|
||||||
"This Week": "Deze week",
|
"This Week": "Deze week",
|
||||||
"This Month": "Deze maand",
|
"This Month": "Deze maand",
|
||||||
|
|||||||
@@ -1824,6 +1824,8 @@
|
|||||||
"Variance": "Variância",
|
"Variance": "Variância",
|
||||||
"Standard Deviation": "Desvio Padrão",
|
"Standard Deviation": "Desvio Padrão",
|
||||||
"Coefficient of Variation": "Coeficiente de Variação",
|
"Coefficient of Variation": "Coeficiente de Variação",
|
||||||
|
"Skewness": "Skewness",
|
||||||
|
"Kurtosis": "Kurtosis",
|
||||||
"Account List": "Lista de Contas",
|
"Account List": "Lista de Contas",
|
||||||
"This Week": "Esta Semana",
|
"This Week": "Esta Semana",
|
||||||
"This Month": "Este Mês",
|
"This Month": "Este Mês",
|
||||||
|
|||||||
@@ -1824,6 +1824,8 @@
|
|||||||
"Variance": "Variance",
|
"Variance": "Variance",
|
||||||
"Standard Deviation": "Standard Deviation",
|
"Standard Deviation": "Standard Deviation",
|
||||||
"Coefficient of Variation": "Coefficient of Variation",
|
"Coefficient of Variation": "Coefficient of Variation",
|
||||||
|
"Skewness": "Skewness",
|
||||||
|
"Kurtosis": "Kurtosis",
|
||||||
"Account List": "Список счетов",
|
"Account List": "Список счетов",
|
||||||
"This Week": "На этой неделе",
|
"This Week": "На этой неделе",
|
||||||
"This Month": "В этом месяце",
|
"This Month": "В этом месяце",
|
||||||
|
|||||||
@@ -1824,6 +1824,8 @@
|
|||||||
"Variance": "Variance",
|
"Variance": "Variance",
|
||||||
"Standard Deviation": "Standard Deviation",
|
"Standard Deviation": "Standard Deviation",
|
||||||
"Coefficient of Variation": "Coefficient of Variation",
|
"Coefficient of Variation": "Coefficient of Variation",
|
||||||
|
"Skewness": "Skewness",
|
||||||
|
"Kurtosis": "Kurtosis",
|
||||||
"Account List": "Seznam računov",
|
"Account List": "Seznam računov",
|
||||||
"This Week": "Ta teden",
|
"This Week": "Ta teden",
|
||||||
"This Month": "Ta mesec",
|
"This Month": "Ta mesec",
|
||||||
|
|||||||
@@ -1824,6 +1824,8 @@
|
|||||||
"Variance": "Variance",
|
"Variance": "Variance",
|
||||||
"Standard Deviation": "Standard Deviation",
|
"Standard Deviation": "Standard Deviation",
|
||||||
"Coefficient of Variation": "Coefficient of Variation",
|
"Coefficient of Variation": "Coefficient of Variation",
|
||||||
|
"Skewness": "Skewness",
|
||||||
|
"Kurtosis": "Kurtosis",
|
||||||
"Account List": "கணக்குகளின் பட்டியல்",
|
"Account List": "கணக்குகளின் பட்டியல்",
|
||||||
"This Week": "இந்த வாரம்",
|
"This Week": "இந்த வாரம்",
|
||||||
"This Month": "இந்த மாதம்",
|
"This Month": "இந்த மாதம்",
|
||||||
|
|||||||
@@ -1824,6 +1824,8 @@
|
|||||||
"Variance": "Variance",
|
"Variance": "Variance",
|
||||||
"Standard Deviation": "Standard Deviation",
|
"Standard Deviation": "Standard Deviation",
|
||||||
"Coefficient of Variation": "Coefficient of Variation",
|
"Coefficient of Variation": "Coefficient of Variation",
|
||||||
|
"Skewness": "Skewness",
|
||||||
|
"Kurtosis": "Kurtosis",
|
||||||
"Account List": "รายการบัญชี",
|
"Account List": "รายการบัญชี",
|
||||||
"This Week": "สัปดาห์นี้",
|
"This Week": "สัปดาห์นี้",
|
||||||
"This Month": "เดือนนี้",
|
"This Month": "เดือนนี้",
|
||||||
|
|||||||
@@ -1824,6 +1824,8 @@
|
|||||||
"Variance": "Variance",
|
"Variance": "Variance",
|
||||||
"Standard Deviation": "Standard Deviation",
|
"Standard Deviation": "Standard Deviation",
|
||||||
"Coefficient of Variation": "Coefficient of Variation",
|
"Coefficient of Variation": "Coefficient of Variation",
|
||||||
|
"Skewness": "Skewness",
|
||||||
|
"Kurtosis": "Kurtosis",
|
||||||
"Account List": "Hesap Listesi",
|
"Account List": "Hesap Listesi",
|
||||||
"This Week": "Bu Hafta",
|
"This Week": "Bu Hafta",
|
||||||
"This Month": "Bu Ay",
|
"This Month": "Bu Ay",
|
||||||
|
|||||||
@@ -1824,6 +1824,8 @@
|
|||||||
"Variance": "Variance",
|
"Variance": "Variance",
|
||||||
"Standard Deviation": "Standard Deviation",
|
"Standard Deviation": "Standard Deviation",
|
||||||
"Coefficient of Variation": "Coefficient of Variation",
|
"Coefficient of Variation": "Coefficient of Variation",
|
||||||
|
"Skewness": "Skewness",
|
||||||
|
"Kurtosis": "Kurtosis",
|
||||||
"Account List": "Список рахунків",
|
"Account List": "Список рахунків",
|
||||||
"This Week": "Цього тижня",
|
"This Week": "Цього тижня",
|
||||||
"This Month": "Цього місяця",
|
"This Month": "Цього місяця",
|
||||||
|
|||||||
@@ -1824,6 +1824,8 @@
|
|||||||
"Variance": "Variance",
|
"Variance": "Variance",
|
||||||
"Standard Deviation": "Standard Deviation",
|
"Standard Deviation": "Standard Deviation",
|
||||||
"Coefficient of Variation": "Coefficient of Variation",
|
"Coefficient of Variation": "Coefficient of Variation",
|
||||||
|
"Skewness": "Skewness",
|
||||||
|
"Kurtosis": "Kurtosis",
|
||||||
"Account List": "Danh sách tài khoản",
|
"Account List": "Danh sách tài khoản",
|
||||||
"This Week": "Tuần này",
|
"This Week": "Tuần này",
|
||||||
"This Month": "Tháng này",
|
"This Month": "Tháng này",
|
||||||
|
|||||||
@@ -1824,6 +1824,8 @@
|
|||||||
"Variance": "方差",
|
"Variance": "方差",
|
||||||
"Standard Deviation": "标准差",
|
"Standard Deviation": "标准差",
|
||||||
"Coefficient of Variation": "变异系数",
|
"Coefficient of Variation": "变异系数",
|
||||||
|
"Skewness": "偏度",
|
||||||
|
"Kurtosis": "峰度",
|
||||||
"Account List": "账户列表",
|
"Account List": "账户列表",
|
||||||
"This Week": "本周",
|
"This Week": "本周",
|
||||||
"This Month": "本月",
|
"This Month": "本月",
|
||||||
|
|||||||
@@ -1824,6 +1824,8 @@
|
|||||||
"Variance": "變異數",
|
"Variance": "變異數",
|
||||||
"Standard Deviation": "標準差",
|
"Standard Deviation": "標準差",
|
||||||
"Coefficient of Variation": "變異係數",
|
"Coefficient of Variation": "變異係數",
|
||||||
|
"Skewness": "偏度",
|
||||||
|
"Kurtosis": "峰度",
|
||||||
"Account List": "帳戶清單",
|
"Account List": "帳戶清單",
|
||||||
"This Week": "本週",
|
"This Week": "本週",
|
||||||
"This Month": "本月",
|
"This Month": "本月",
|
||||||
|
|||||||
+35
-38
@@ -8,7 +8,7 @@ import { useTransactionCategoriesStore } from './transactionCategory.ts';
|
|||||||
import { useTransactionTagsStore } from './transactionTag.ts';
|
import { useTransactionTagsStore } from './transactionTag.ts';
|
||||||
import { useExchangeRatesStore } from './exchangeRates.ts';
|
import { useExchangeRatesStore } from './exchangeRates.ts';
|
||||||
|
|
||||||
import { type BeforeResolveFunction, itemAndIndex, reversed, keys, values } from '@/core/base.ts';
|
import { type BeforeResolveFunction, itemAndIndex, keys, values } from '@/core/base.ts';
|
||||||
import { NumeralSystem, AmountFilterType } from '@/core/numeral.ts';
|
import { NumeralSystem, AmountFilterType } from '@/core/numeral.ts';
|
||||||
import { type DateTime, DateRangeScene, DateRange } from '@/core/datetime.ts';
|
import { type DateTime, DateRangeScene, DateRange } from '@/core/datetime.ts';
|
||||||
import { TimezoneTypeForStatistics } from '@/core/timezone.ts';
|
import { TimezoneTypeForStatistics } from '@/core/timezone.ts';
|
||||||
@@ -20,6 +20,7 @@ import {
|
|||||||
TransactionExplorerValueMetric,
|
TransactionExplorerValueMetric,
|
||||||
DEFAULT_TRANSACTION_EXPLORER_DATE_RANGE
|
DEFAULT_TRANSACTION_EXPLORER_DATE_RANGE
|
||||||
} from '@/core/explorer.ts';
|
} from '@/core/explorer.ts';
|
||||||
|
import { AMOUNT_FACTOR } from '@/consts/numeral.ts';
|
||||||
import { ALL_CURRENCIES } from '@/consts/currency.ts';
|
import { ALL_CURRENCIES } from '@/consts/currency.ts';
|
||||||
|
|
||||||
import { type Account } from '@/models/account.ts';
|
import { type Account } from '@/models/account.ts';
|
||||||
@@ -46,7 +47,12 @@ import {
|
|||||||
import {
|
import {
|
||||||
median,
|
median,
|
||||||
percentile,
|
percentile,
|
||||||
sumMaxN
|
sumMaxN,
|
||||||
|
cumulativePercentage,
|
||||||
|
varianceAndStandardDeviation,
|
||||||
|
coefficientOfVariation,
|
||||||
|
skewness,
|
||||||
|
kurtosis
|
||||||
} from '@/lib/math.ts';
|
} from '@/lib/math.ts';
|
||||||
import {
|
import {
|
||||||
getUtcOffsetByUtcOffsetMinutes,
|
getUtcOffsetByUtcOffsetMinutes,
|
||||||
@@ -726,26 +732,15 @@ export const useExplorersStore = defineStore('explorers', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sourceAmounts.length > 0) {
|
if (sourceAmounts.length > 0) {
|
||||||
const eightyPercentAmountThreshold: number = 0.8 * statisticData.totalAmount;
|
statisticData.transactionsFor80PercentAmount = cumulativePercentage(sourceAmounts, 0.8, statisticData.totalAmount, item => item);
|
||||||
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 / sourceAmounts.length;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sourceAmounts.length > 0) {
|
if (sourceAmounts.length > 0) {
|
||||||
const averageAmountForVarianceCalculation: number = statisticData.totalAmount / sourceAmounts.length / 100.0;
|
const averageAmountForVarianceCalculation: number = statisticData.totalAmount / sourceAmounts.length / AMOUNT_FACTOR;
|
||||||
const sumOfSquaredDifferences: number = sourceAmounts.reduce((sum, amount) => sum + Math.pow(amount / 100.0 - averageAmountForVarianceCalculation, 2), 0);
|
const { variance, standardDeviation } = varianceAndStandardDeviation(sourceAmounts, averageAmountForVarianceCalculation, item => item / AMOUNT_FACTOR);
|
||||||
statisticData.variance = sumOfSquaredDifferences / sourceAmounts.length;
|
statisticData.variance = variance;
|
||||||
statisticData.standardDeviation = Math.sqrt(statisticData.variance);
|
statisticData.standardDeviation = standardDeviation;
|
||||||
statisticData.coefficientOfVariation = averageAmountForVarianceCalculation !== 0 ? statisticData.standardDeviation / averageAmountForVarianceCalculation : undefined;
|
statisticData.coefficientOfVariation = coefficientOfVariation(standardDeviation, averageAmountForVarianceCalculation);
|
||||||
}
|
}
|
||||||
|
|
||||||
return statisticData;
|
return statisticData;
|
||||||
@@ -892,7 +887,12 @@ export const useExplorersStore = defineStore('explorers', () => {
|
|||||||
} else {
|
} else {
|
||||||
value = 0;
|
value = 0;
|
||||||
}
|
}
|
||||||
} else if (valueMetric === TransactionExplorerValueMetric.SourceAmountQ1Amount || valueMetric === TransactionExplorerValueMetric.SourceAmountQ3Amount || valueMetric === TransactionExplorerValueMetric.SourceAmount10thPercentile || valueMetric === TransactionExplorerValueMetric.SourceAmount90thPercentile || valueMetric === TransactionExplorerValueMetric.SourceAmount95thPercentile || valueMetric === TransactionExplorerValueMetric.SourceAmount99thPercentile) {
|
} else if (valueMetric === TransactionExplorerValueMetric.SourceAmountQ1Amount
|
||||||
|
|| valueMetric === TransactionExplorerValueMetric.SourceAmountQ3Amount
|
||||||
|
|| valueMetric === TransactionExplorerValueMetric.SourceAmount10thPercentile
|
||||||
|
|| valueMetric === TransactionExplorerValueMetric.SourceAmount90thPercentile
|
||||||
|
|| valueMetric === TransactionExplorerValueMetric.SourceAmount95thPercentile
|
||||||
|
|| valueMetric === TransactionExplorerValueMetric.SourceAmount99thPercentile) {
|
||||||
if (allSourceAmountsInDefaultCurrency.length > 0) {
|
if (allSourceAmountsInDefaultCurrency.length > 0) {
|
||||||
allSourceAmountsInDefaultCurrency.sort((a, b) => a - b);
|
allSourceAmountsInDefaultCurrency.sort((a, b) => a - b);
|
||||||
|
|
||||||
@@ -932,18 +932,7 @@ export const useExplorersStore = defineStore('explorers', () => {
|
|||||||
} else if (valueMetric === TransactionExplorerValueMetric.TransactionsForEightyPercentOfSourceAmount) {
|
} else if (valueMetric === TransactionExplorerValueMetric.TransactionsForEightyPercentOfSourceAmount) {
|
||||||
if (allSourceAmountsInDefaultCurrency.length > 0) {
|
if (allSourceAmountsInDefaultCurrency.length > 0) {
|
||||||
allSourceAmountsInDefaultCurrency.sort((a, b) => a - b);
|
allSourceAmountsInDefaultCurrency.sort((a, b) => a - b);
|
||||||
const eightyPercentAmountThreshold: number = 0.8 * totalSourceAmountSumInDefaultCurrency;
|
value = cumulativePercentage(allSourceAmountsInDefaultCurrency, 0.8, totalSourceAmountSumInDefaultCurrency, item => item);
|
||||||
let cumulativeAmount: number = 0;
|
|
||||||
let cumulativeCount: number = 0;
|
|
||||||
for (const amount of reversed(allSourceAmountsInDefaultCurrency)) {
|
|
||||||
cumulativeAmount += amount;
|
|
||||||
cumulativeCount++;
|
|
||||||
|
|
||||||
if (cumulativeAmount >= eightyPercentAmountThreshold) {
|
|
||||||
value = 100.0 * cumulativeCount / allSourceAmountsInDefaultCurrency.length;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
value = 0;
|
value = 0;
|
||||||
}
|
}
|
||||||
@@ -962,17 +951,25 @@ export const useExplorersStore = defineStore('explorers', () => {
|
|||||||
} else {
|
} else {
|
||||||
value = 0;
|
value = 0;
|
||||||
}
|
}
|
||||||
} else if (valueMetric === TransactionExplorerValueMetric.SourceAmountVariance || valueMetric === TransactionExplorerValueMetric.SourceAmountStandardDeviation || valueMetric === TransactionExplorerValueMetric.SourceAmountCoefficientOfVariation) {
|
} else if (valueMetric === TransactionExplorerValueMetric.SourceAmountVariance
|
||||||
|
|| valueMetric === TransactionExplorerValueMetric.SourceAmountStandardDeviation
|
||||||
|
|| valueMetric === TransactionExplorerValueMetric.SourceAmountCoefficientOfVariation
|
||||||
|
|| valueMetric === TransactionExplorerValueMetric.SourceAmountSkewness
|
||||||
|
|| valueMetric === TransactionExplorerValueMetric.SourceAmountKurtosis) {
|
||||||
if (allSourceAmountsInDefaultCurrency.length > 0) {
|
if (allSourceAmountsInDefaultCurrency.length > 0) {
|
||||||
const averageSourceAmountInDefaultCurrency = totalSourceAmountSumInDefaultCurrency / allSourceAmountsInDefaultCurrency.length / 100.0;
|
const averageSourceAmountInDefaultCurrency = totalSourceAmountSumInDefaultCurrency / allSourceAmountsInDefaultCurrency.length / AMOUNT_FACTOR;
|
||||||
const sumOfSquaredDifferences = allSourceAmountsInDefaultCurrency.reduce((sum, amount) => sum + Math.pow(amount / 100.0 - averageSourceAmountInDefaultCurrency, 2), 0);
|
const { variance, standardDeviation } = varianceAndStandardDeviation(allSourceAmountsInDefaultCurrency, averageSourceAmountInDefaultCurrency, item => item / AMOUNT_FACTOR);
|
||||||
|
|
||||||
if (valueMetric === TransactionExplorerValueMetric.SourceAmountVariance) {
|
if (valueMetric === TransactionExplorerValueMetric.SourceAmountVariance) {
|
||||||
value = sumOfSquaredDifferences / allSourceAmountsInDefaultCurrency.length
|
value = variance;
|
||||||
} else if (valueMetric === TransactionExplorerValueMetric.SourceAmountStandardDeviation) {
|
} else if (valueMetric === TransactionExplorerValueMetric.SourceAmountStandardDeviation) {
|
||||||
value = Math.sqrt(sumOfSquaredDifferences / allSourceAmountsInDefaultCurrency.length);
|
value = standardDeviation;
|
||||||
} else if (valueMetric === TransactionExplorerValueMetric.SourceAmountCoefficientOfVariation) {
|
} else if (valueMetric === TransactionExplorerValueMetric.SourceAmountCoefficientOfVariation) {
|
||||||
value = averageSourceAmountInDefaultCurrency !== 0 ? Math.sqrt(sumOfSquaredDifferences / allSourceAmountsInDefaultCurrency.length) / averageSourceAmountInDefaultCurrency : 0;
|
value = coefficientOfVariation(standardDeviation, averageSourceAmountInDefaultCurrency) ?? 0;
|
||||||
|
} else if (valueMetric === TransactionExplorerValueMetric.SourceAmountSkewness) {
|
||||||
|
value = skewness(allSourceAmountsInDefaultCurrency, averageSourceAmountInDefaultCurrency, standardDeviation, item => item / AMOUNT_FACTOR);
|
||||||
|
} else if (valueMetric === TransactionExplorerValueMetric.SourceAmountKurtosis) {
|
||||||
|
value = kurtosis(allSourceAmountsInDefaultCurrency, averageSourceAmountInDefaultCurrency, variance, item => item / AMOUNT_FACTOR);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
value = 0;
|
value = 0;
|
||||||
|
|||||||
@@ -171,6 +171,7 @@ import { useExchangeRatesPageBase } from '@/views/base/ExchangeRatesPageBase.ts'
|
|||||||
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
|
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
|
||||||
|
|
||||||
import { NumeralSystem } from '@/core/numeral.ts';
|
import { NumeralSystem } from '@/core/numeral.ts';
|
||||||
|
import { AMOUNT_FACTOR } from '@/consts/numeral.ts';
|
||||||
|
|
||||||
import type { LocalizedLatestExchangeRate } from '@/models/exchange_rate.ts';
|
import type { LocalizedLatestExchangeRate } from '@/models/exchange_rate.ts';
|
||||||
|
|
||||||
@@ -302,7 +303,7 @@ function getFinalConvertedAmount(toExchangeRate: LocalizedLatestExchangeRate, di
|
|||||||
let exchangeRateAmount: number | '' | null = 0;
|
let exchangeRateAmount: number | '' | null = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
exchangeRateAmount = getConvertedAmount(baseAmount.value / 100, fromExchangeRate, toExchangeRate);
|
exchangeRateAmount = getConvertedAmount(baseAmount.value / AMOUNT_FACTOR, fromExchangeRate, toExchangeRate);
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
exchangeRateAmount = 0;
|
exchangeRateAmount = 0;
|
||||||
logger.warn('failed to convert amount by exchange rates, original base amount is ' + baseAmount.value, ex)
|
logger.warn('failed to convert amount by exchange rates, original base amount is ' + baseAmount.value, ex)
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
|
|||||||
|
|
||||||
import { TextDirection } from '@/core/text.ts';
|
import { TextDirection } from '@/core/text.ts';
|
||||||
import { NumeralSystem } from '@/core/numeral.ts';
|
import { NumeralSystem } from '@/core/numeral.ts';
|
||||||
|
import { AMOUNT_FACTOR } from '@/consts/numeral.ts';
|
||||||
import { TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT } from '@/consts/transaction.ts';
|
import { TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT } from '@/consts/transaction.ts';
|
||||||
|
|
||||||
import type { LocalizedLatestExchangeRate } from '@/models/exchange_rate.ts';
|
import type { LocalizedLatestExchangeRate } from '@/models/exchange_rate.ts';
|
||||||
@@ -277,7 +278,7 @@ function remove(customExchangeRate: LocalizedLatestExchangeRate | null, confirm:
|
|||||||
|
|
||||||
function getFinalConvertedAmount(toExchangeRate: LocalizedLatestExchangeRate, displayLocalizedDigits: boolean): string {
|
function getFinalConvertedAmount(toExchangeRate: LocalizedLatestExchangeRate, displayLocalizedDigits: boolean): string {
|
||||||
const fromExchangeRate = exchangeRatesStore.latestExchangeRateMap[baseCurrency.value];
|
const fromExchangeRate = exchangeRatesStore.latestExchangeRateMap[baseCurrency.value];
|
||||||
const exchangeRateAmount = getConvertedAmount(baseAmount.value / 100, fromExchangeRate, toExchangeRate);
|
const exchangeRateAmount = getConvertedAmount(baseAmount.value / AMOUNT_FACTOR, fromExchangeRate, toExchangeRate);
|
||||||
|
|
||||||
if (!exchangeRateAmount) {
|
if (!exchangeRateAmount) {
|
||||||
if (displayLocalizedDigits) {
|
if (displayLocalizedDigits) {
|
||||||
|
|||||||
Reference in New Issue
Block a user