trend analysis supports aggregating amounts by month / quarter / year

This commit is contained in:
MaysWind
2024-11-06 01:35:42 +08:00
parent c3a880e5f5
commit fe35cbae49
9 changed files with 311 additions and 53 deletions
+95 -28
View File
@@ -11,11 +11,17 @@ import { useSettingsStore } from '@/stores/setting.js';
import { useUserStore } from '@/stores/user.js';
import colorConstants from '@/consts/color.js';
import datetimeConstants from '@/consts/datetime.js';
import statisticsConstants from '@/consts/statistics.js';
import { isNumber } from '@/lib/common.js';
import {
getYearMonthStringFromObject,
getAllYearMonthUnixTimesBetweenStartYearMonthAndEndYearMonth
isArray,
isNumber
} from '@/lib/common.js';
import {
getAllYearsStartAndEndUnixTimes,
getAllQuartersStartAndEndUnixTimes,
getAllMonthsStartAndEndUnixTimes,
getDateTypeByDateRange
} from '@/lib/datetime.js';
import {
sortStatisticsItems
@@ -29,6 +35,7 @@ export default {
'startYearMonth',
'endYearMonth',
'sortingType',
'dateAggregationType',
'idField',
'nameField',
'valueField',
@@ -67,15 +74,21 @@ export default {
id = this.getItemName(item[this.nameField]);
}
map[id] = item;
map[id] = {
[this.idField || 'id']: id,
[this.nameField || 'name']: item[this.nameField],
[this.hiddenField || 'hidden']: item[this.hiddenField],
[this.displayOrdersField || 'displayOrders']: item[this.displayOrdersField]
};
}
return map;
},
allYearMonthTimes: function () {
if (this.startYearMonth && this.endYearMonth) {
return getAllYearMonthUnixTimesBetweenStartYearMonthAndEndYearMonth(this.startYearMonth, this.endYearMonth);
} else if (this.items && this.items.length) {
allDateRanges: function () {
let startYearMonth = this.startYearMonth;
let endYearMonth = this.endYearMonth;
if ((!this.startYearMonth || !this.endYearMonth) && this.items && this.items.length) {
let minYear = Number.MAX_SAFE_INTEGER, minMonth = Number.MAX_SAFE_INTEGER, maxYear = 0, maxMonth = 0;
for (let i = 0; i < this.items.length; i++) {
@@ -96,20 +109,37 @@ export default {
}
}
return getAllYearMonthUnixTimesBetweenStartYearMonthAndEndYearMonth(`${minYear}-${minMonth}`, `${maxYear}-${maxMonth}`);
startYearMonth = `${minYear}-${minMonth}`;
endYearMonth = `${maxYear}-${maxMonth}`;
}
return [];
if (!startYearMonth || !endYearMonth) {
return [];
}
if (this.dateAggregationType === statisticsConstants.allDateAggregationTypes.Year.type) {
return getAllYearsStartAndEndUnixTimes(startYearMonth, endYearMonth);
} else if (this.dateAggregationType === statisticsConstants.allDateAggregationTypes.Quarter.type) {
return getAllQuartersStartAndEndUnixTimes(startYearMonth, endYearMonth);
} else { // if (this.dateAggregationType === statisticsConstants.allDateAggregationTypes.Month.type) {
return getAllMonthsStartAndEndUnixTimes(startYearMonth, endYearMonth);
}
},
allDisplayMonths: function () {
const allDisplayMonths = [];
allDisplayDateRanges: function () {
const allDisplayDateRanges = [];
for (let i = 0; i < this.allYearMonthTimes.length; i++) {
const yearMonthTime = this.allYearMonthTimes[i];
allDisplayMonths.push(this.$locale.formatUnixTimeToShortYearMonth(this.userStore, yearMonthTime.minUnixTime));
for (let i = 0; i < this.allDateRanges.length; i++) {
const dateRange = this.allDateRanges[i];
if (this.dateAggregationType === statisticsConstants.allDateAggregationTypes.Year.type) {
allDisplayDateRanges.push(this.$locale.formatUnixTimeToShortYear(this.userStore, dateRange.minUnixTime));
} else if (this.dateAggregationType === statisticsConstants.allDateAggregationTypes.Quarter.type) {
allDisplayDateRanges.push(this.$locale.formatYearQuarter(dateRange.year, dateRange.quarter));
} else { // if (this.dateAggregationType === statisticsConstants.allDateAggregationTypes.Month.type) {
allDisplayDateRanges.push(this.$locale.formatUnixTimeToShortYearMonth(this.userStore, dateRange.minUnixTime));
}
}
return allDisplayMonths;
return allDisplayDateRanges;
},
allSeries: function () {
const allSeries = [];
@@ -122,20 +152,49 @@ export default {
}
const allAmounts = [];
const yearMonthDataMap = {};
const dateRangeAmountMap = {};
for (let j = 0; j < item.items.length; j++) {
const dataItem = item.items[j];
yearMonthDataMap[`${dataItem.year}-${dataItem.month}`] = dataItem;
let dateRangeKey = '';
if (this.dateAggregationType === statisticsConstants.allDateAggregationTypes.Year.type) {
dateRangeKey = dataItem.year;
} else if (this.dateAggregationType === statisticsConstants.allDateAggregationTypes.Quarter.type) {
dateRangeKey = `${dataItem.year}-${Math.floor((dataItem.month - 1) / 3) + 1}`;
} else { // if (this.dateAggregationType === statisticsConstants.allDateAggregationTypes.Month.type) {
dateRangeKey = `${dataItem.year}-${dataItem.month}`;
}
const dataItems = dateRangeAmountMap[dateRangeKey] || [];
dataItems.push(dataItem);
dateRangeAmountMap[dateRangeKey] = dataItems;
}
for (let j = 0; j < this.allYearMonthTimes.length; j++) {
const yearMonth = getYearMonthStringFromObject(this.allYearMonthTimes[j]);
const dataItem = yearMonthDataMap[yearMonth];
let amount = 0;
for (let j = 0; j < this.allDateRanges.length; j++) {
const dateRange = this.allDateRanges[j];
let dateRangeKey = '';
if (dataItem && isNumber(dataItem[this.valueField])) {
amount = dataItem[this.valueField];
if (this.dateAggregationType === statisticsConstants.allDateAggregationTypes.Year.type) {
dateRangeKey = dateRange.year;
} else if (this.dateAggregationType === statisticsConstants.allDateAggregationTypes.Quarter.type) {
dateRangeKey = `${dateRange.year}-${dateRange.quarter}`;
} else { // if (this.dateAggregationType === statisticsConstants.allDateAggregationTypes.Month.type) {
dateRangeKey = `${dateRange.year}-${dateRange.month + 1}`;
}
let amount = 0;
const dataItems = dateRangeAmountMap[dateRangeKey];
if (isArray(dataItems)) {
for (let i = 0; i < dataItems.length; i++) {
const dataItem = dataItems[i];
if (isNumber(dataItem[this.valueField])) {
amount += dataItem[this.valueField];
}
}
}
allAmounts.push(amount);
@@ -293,7 +352,7 @@ export default {
xAxis: [
{
type: 'category',
data: self.allDisplayMonths
data: self.allDisplayDateRanges
}
],
yAxis: [
@@ -332,11 +391,19 @@ export default {
const id = e.seriesId;
const item = this.itemsMap[id];
const yearMonthTime = this.allYearMonthTimes[e.dataIndex];
const itemId = this.idField ? item[this.idField] : '';
const dateRange = this.allDateRanges[e.dataIndex];
const minUnixTime = dateRange.minUnixTime;
const maxUnixTime = dateRange.maxUnixTime;
const dateRangeType = getDateTypeByDateRange(minUnixTime, maxUnixTime, this.userStore.currentUserFirstDayOfWeek, datetimeConstants.allDateRangeScenes.Normal);
this.$emit('click', {
yearMonth: getYearMonthStringFromObject(yearMonthTime),
item: item
itemId: itemId,
dateRange: {
minTime: minUnixTime,
maxTime: maxUnixTime,
type: dateRangeType
}
});
},
getColor: function (color) {
+26
View File
@@ -169,6 +169,29 @@ const allSortingTypesArray = [
const defaultSortingType = allSortingTypes.Amount.type;
const allDateAggregationTypes = {
Month: {
type: 0,
name: 'Aggregate by Month'
},
Quarter: {
type: 1,
name: 'Aggregate by Quarter'
},
Year: {
type: 2,
name: 'Aggregate by Year'
}
};
const allDateAggregationTypesArray = [
allDateAggregationTypes.Month,
allDateAggregationTypes.Quarter,
allDateAggregationTypes.Year
]
const defaultDateAggregationType = allDateAggregationTypes.Month.type;
export default {
allAnalysisTypes: allAnalysisTypes,
allCategoricalChartTypes: allCategoricalChartTypes,
@@ -185,4 +208,7 @@ export default {
allSortingTypes: allSortingTypes,
allSortingTypesArray: allSortingTypesArray,
defaultSortingType: defaultSortingType,
allDateAggregationTypes: allDateAggregationTypes,
allDateAggregationTypesArray: allDateAggregationTypesArray,
defaultDateAggregationType: defaultDateAggregationType,
};
+79 -1
View File
@@ -283,6 +283,22 @@ export function getSpecifiedDayFirstUnixTime(unixTime) {
return moment.unix(unixTime).set({ hour: 0, minute: 0, second: 0, millisecond: 0 }).unix();
}
export function getYearFirstUnixTime(year) {
return moment().set({ year: year, month: 0, date: 1, hour: 0, minute: 0, second: 0, millisecond: 0 }).unix();
}
export function getYearLastUnixTime(year) {
return moment.unix(getYearFirstUnixTime(year)).add(1, 'years').subtract(1, 'seconds').unix();
}
export function getQuarterFirstUnixTime(yearQuarter) {
return moment().set({ year: yearQuarter.year, month: (yearQuarter.quarter - 1) * 3, date: 1, hour: 0, minute: 0, second: 0, millisecond: 0 }).unix();
}
export function getQuarterLastUnixTime(yearQuarter) {
return moment.unix(getQuarterFirstUnixTime(yearQuarter)).add(3, 'months').subtract(1, 'seconds').unix();
}
export function getYearMonthFirstUnixTime(yearMonth) {
if (isString(yearMonth)) {
yearMonth = getYearMonthObjectFromString(yearMonth);
@@ -301,7 +317,69 @@ export function getYearMonthLastUnixTime(yearMonth) {
return moment.unix(getYearMonthFirstUnixTime(yearMonth)).add(1, 'months').subtract(1, 'seconds').unix();
}
export function getAllYearMonthUnixTimesBetweenStartYearMonthAndEndYearMonth(startYearMonth, endYearMonth) {
export function getAllYearsStartAndEndUnixTimes(startYearMonth, endYearMonth) {
if (isString(startYearMonth)) {
startYearMonth = getYearMonthObjectFromString(startYearMonth);
}
if (isString(endYearMonth)) {
endYearMonth = getYearMonthObjectFromString(endYearMonth);
}
const allYearTimes = [];
for (let year = startYearMonth.year; year <= endYearMonth.year; year++) {
const yearTime = {
year: year
};
yearTime.minUnixTime = getYearFirstUnixTime(year);
yearTime.maxUnixTime = getYearLastUnixTime(year);
allYearTimes.push(yearTime);
}
return allYearTimes;
}
export function getAllQuartersStartAndEndUnixTimes(startYearMonth, endYearMonth) {
if (isString(startYearMonth)) {
startYearMonth = getYearMonthObjectFromString(startYearMonth);
}
if (isString(endYearMonth)) {
endYearMonth = getYearMonthObjectFromString(endYearMonth);
}
const allYearQuarterTimes = [];
for (let year = startYearMonth.year, month = startYearMonth.month; year < endYearMonth.year || (year === endYearMonth.year && ((month / 3) <= (endYearMonth.month / 3))); ) {
const yearQuarterTime = {
year: year,
quarter: Math.floor((month / 3)) + 1
};
yearQuarterTime.minUnixTime = getQuarterFirstUnixTime(yearQuarterTime);
yearQuarterTime.maxUnixTime = getQuarterLastUnixTime(yearQuarterTime);
allYearQuarterTimes.push(yearQuarterTime);
if (year === endYearMonth.year && month >= endYearMonth.month) {
break;
}
if (month >= 9) {
year++;
month = 0;
} else {
month += 3;
}
}
return allYearQuarterTimes;
}
export function getAllMonthsStartAndEndUnixTimes(startYearMonth, endYearMonth) {
if (isString(startYearMonth)) {
startYearMonth = getYearMonthObjectFromString(startYearMonth);
}
+32
View File
@@ -451,6 +451,17 @@ function getI18nShortTimeFormat(translateFn, formatTypeValue) {
return getDateTimeFormat(translateFn, datetimeConstants.allShortTimeFormat, datetimeConstants.allShortTimeFormatArray, 'format.shortTime', defaultShortTimeFormatTypeName, datetimeConstants.defaultShortTimeFormat, formatTypeValue);
}
function formatYearQuarter(translateFn, year, quarter) {
if (1 <= quarter && quarter <= 4) {
return translateFn('format.yearQuarter.q' + quarter, {
year: year,
quarter: quarter
});
} else {
return '';
}
}
function isLongTime24HourFormat(translateFn, formatTypeValue) {
const defaultLongTimeFormatTypeName = translateFn('default.longTimeFormat');
const type = getDateTimeFormatType(datetimeConstants.allLongTimeFormat, datetimeConstants.allLongTimeFormatArray, defaultLongTimeFormatTypeName, datetimeConstants.defaultLongTimeFormat, formatTypeValue);
@@ -1142,6 +1153,25 @@ function getAllStatisticsSortingTypes(translateFn) {
return allSortingTypes;
}
function getAllStatisticsDateAggregationTypes(translateFn) {
const aggregationTypes = [];
for (const aggregationTypeField in statisticsConstants.allDateAggregationTypes) {
if (!Object.prototype.hasOwnProperty.call(statisticsConstants.allDateAggregationTypes, aggregationTypeField)) {
continue;
}
const aggregationType = statisticsConstants.allDateAggregationTypes[aggregationTypeField];
aggregationTypes.push({
type: aggregationType.type,
displayName: translateFn(aggregationType.name)
});
}
return aggregationTypes;
}
function getAllTransactionEditScopeTypes(translateFn) {
const allEditScopeTypes = [];
@@ -1632,6 +1662,7 @@ export function i18nFunctions(i18nGlobal) {
formatUnixTimeToShortMonthDay: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nShortMonthDayFormat(i18nGlobal.t, userStore.currentUserShortDateFormat), utcOffset, currentUtcOffset),
formatUnixTimeToLongTime: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nLongTimeFormat(i18nGlobal.t, userStore.currentUserLongTimeFormat), utcOffset, currentUtcOffset),
formatUnixTimeToShortTime: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nShortTimeFormat(i18nGlobal.t, userStore.currentUserShortTimeFormat), utcOffset, currentUtcOffset),
formatYearQuarter: (year, quarter) => formatYearQuarter(i18nGlobal.t, year, quarter),
isLongDateMonthAfterYear: (userStore) => isLongDateMonthAfterYear(i18nGlobal.t, userStore.currentUserLongDateFormat),
isShortDateMonthAfterYear: (userStore) => isShortDateMonthAfterYear(i18nGlobal.t, userStore.currentUserShortDateFormat),
isLongTime24HourFormat: (userStore) => isLongTime24HourFormat(i18nGlobal.t, userStore.currentUserLongTimeFormat),
@@ -1668,6 +1699,7 @@ export function i18nFunctions(i18nGlobal) {
getAllTrendChartTypes: () => getAllTrendChartTypes(i18nGlobal.t),
getAllStatisticsChartDataTypes: (analysisType) => getAllStatisticsChartDataTypes(i18nGlobal.t, analysisType),
getAllStatisticsSortingTypes: () => getAllStatisticsSortingTypes(i18nGlobal.t),
getAllStatisticsDateAggregationTypes: () => getAllStatisticsDateAggregationTypes(i18nGlobal.t),
getAllTransactionEditScopeTypes: () => getAllTransactionEditScopeTypes(i18nGlobal.t),
getAllTransactionScheduledFrequencyTypes: () => getAllTransactionScheduledFrequencyTypes(i18nGlobal.t),
getAllTransactionDefaultCategories: (categoryType, locale) => getAllTransactionDefaultCategories(categoryType, locale, i18nGlobal.t),
+9
View File
@@ -71,6 +71,12 @@
"a_hh_mm": "A hh:mm",
"hh_mm_a": "hh:mm A"
},
"yearQuarter": {
"q1": "{year}Q1",
"q2": "{year}Q2",
"q3": "{year}Q3",
"q4": "{year}Q4"
},
"misc": {
"multiTextJoinSeparator": ", ",
"hoursBehindDefaultTimezone": "{hours} hour(s) behind default timezone",
@@ -1632,6 +1638,9 @@
"Sort by Amount": "Sort by Amount",
"Sort by Display Order": "Sort by Display Order",
"Sort by Name": "Sort by Name",
"Aggregate by Month": "Aggregate by Month",
"Aggregate by Quarter": "Aggregate by Quarter",
"Aggregate by Year": "Aggregate by Year",
"Filter Accounts": "Filter Accounts",
"Filter Transaction Categories": "Filter Transaction Categories",
"Filter Transaction Tags": "Filter Transaction Tags",
+9
View File
@@ -71,6 +71,12 @@
"a_hh_mm": "A hh:mm",
"hh_mm_a": "hh:mm A"
},
"yearQuarter": {
"q1": "{year}Q1",
"q2": "{year}Q2",
"q3": "{year}Q3",
"q4": "{year}Q4"
},
"misc": {
"multiTextJoinSeparator": "、",
"hoursBehindDefaultTimezone": "比默认时区晚{hours}小时",
@@ -1632,6 +1638,9 @@
"Sort by Amount": "按金额排序",
"Sort by Display Order": "按显示顺序排序",
"Sort by Name": "按名称排序",
"Aggregate by Month": "按月聚合",
"Aggregate by Quarter": "按季度聚合",
"Aggregate by Year": "按年聚合",
"Filter Accounts": "过滤账户",
"Filter Transaction Categories": "过滤交易类型",
"Filter Transaction Tags": "过滤交易标签",
+2 -1
View File
@@ -121,7 +121,8 @@ const router = createRouter({
initEndTime: route.query.endTime,
initFilterAccountIds: route.query.filterAccountIds,
initFilterCategoryIds: route.query.filterCategoryIds,
initSortingType: route.query.sortingType
initSortingType: route.query.sortingType,
initTrendDateAggregationType: route.query.trendDateAggregationType
})
},
{
+8 -4
View File
@@ -754,7 +754,7 @@ export const useStatisticsStore = defineStore('statistics', {
return changed;
},
getTransactionStatisticsPageParams(analysisType) {
getTransactionStatisticsPageParams(analysisType, trendDateAggregationType) {
const querys = [];
querys.push('analysisType=' + analysisType);
@@ -776,6 +776,10 @@ export const useStatisticsStore = defineStore('statistics', {
querys.push('startTime=' + this.transactionStatisticsFilter.trendChartStartYearMonth);
querys.push('endTime=' + this.transactionStatisticsFilter.trendChartEndYearMonth);
}
if (trendDateAggregationType !== statisticsConstants.allDateAggregationTypes.Month.type) {
querys.push('trendDateAggregationType=' + trendDateAggregationType);
}
}
if (this.transactionStatisticsFilter.filterAccountIds) {
@@ -798,7 +802,7 @@ export const useStatisticsStore = defineStore('statistics', {
return querys.join('&');
},
getTransactionListPageParams(analysisType, item, dateRange) {
getTransactionListPageParams(analysisType, itemId, dateRange) {
const accountsStore = useAccountsStore();
const transactionCategoriesStore = useTransactionCategoriesStore();
const querys = [];
@@ -819,7 +823,7 @@ export const useStatisticsStore = defineStore('statistics', {
|| this.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.ExpenseByAccount.type
|| this.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.AccountTotalAssets.type
|| this.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.AccountTotalLiabilities.type) {
querys.push('accountIds=' + item.id);
querys.push('accountIds=' + itemId);
if (!isObjectEmpty(this.transactionStatisticsFilter.filterCategoryIds)) {
querys.push('categoryIds=' + getFinalCategoryIdsByFilteredCategoryIds(transactionCategoriesStore.allTransactionCategoriesMap, this.transactionStatisticsFilter.filterCategoryIds));
@@ -828,7 +832,7 @@ export const useStatisticsStore = defineStore('statistics', {
|| this.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.IncomeBySecondaryCategory.type
|| this.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.ExpenseByPrimaryCategory.type
|| this.transactionStatisticsFilter.chartDataType === statisticsConstants.allChartDataTypes.ExpenseBySecondaryCategory.type) {
querys.push('categoryIds=' + item.id);
querys.push('categoryIds=' + itemId);
if (!isObjectEmpty(this.transactionStatisticsFilter.filterAccountIds)) {
querys.push('accountIds=' + getFinalAccountIdsByFilteredAccountIds(accountsStore.allAccountsMap, this.transactionStatisticsFilter.filterAccountIds));
@@ -87,6 +87,22 @@
@click="shiftDateRange(1)"/>
</v-btn-group>
<v-menu location="bottom">
<template #activator="{ props }">
<v-btn class="ml-3" color="default" variant="outlined"
:prepend-icon="icons.dateAggregation" :disabled="loading"
v-bind="props">{{ queryTrendDateAggregationTypeName }}</v-btn>
</template>
<v-list>
<v-list-item class="cursor-pointer" :key="aggregationType.type" :value="aggregationType.type"
:append-icon="(trendDateAggregationType === aggregationType.type ? icons.check : null)"
:title="aggregationType.displayName"
v-for="aggregationType in allDateAggregationTypesArray"
@click="setTrendDateAggregationType(aggregationType.type)">
</v-list-item>
</v-list>
</v-menu>
<v-btn density="compact" color="default" variant="text" size="24"
class="ml-2" :icon="true" :loading="loading" @click="reload">
<template #loader>
@@ -193,13 +209,13 @@
v-for="(item, idx) in categoricalAnalysisData.items">
<v-list-item class="pl-0" v-if="!item.hidden">
<template #prepend>
<router-link class="statistics-list-item" :to="getTransactionItemLinkUrl(item)">
<router-link class="statistics-list-item" :to="getTransactionItemLinkUrl(item.id)">
<ItemIcon :icon-type="queryChartDataCategory" size="34px"
:icon-id="item.icon"
:color="item.color"></ItemIcon>
</router-link>
</template>
<router-link class="statistics-list-item" :to="getTransactionItemLinkUrl(item)">
<router-link class="statistics-list-item" :to="getTransactionItemLinkUrl(item.id)">
<div class="d-flex flex-column ml-2">
<div class="d-flex">
<span>{{ item.name }}</span>
@@ -239,6 +255,7 @@
:start-year-month="query.trendChartStartYearMonth"
:end-year-month="query.trendChartEndYearMonth"
:sorting-type="querySortingType"
:date-aggregation-type="trendDateAggregationType"
:items="trendsAnalysisData && trendsAnalysisData.items && trendsAnalysisData.items.length ? trendsAnalysisData.items : []"
:translate-name="translateNameInTrendsChart"
:show-value="showAmountInChart"
@@ -303,6 +320,7 @@ import statisticsConstants from '@/consts/statistics.js';
import {
isDefined,
limitText,
getNameByKeyValue,
arrayItemToObjectField
} from '@/lib/common.js'
import { formatPercent } from '@/lib/numeral.js';
@@ -320,7 +338,7 @@ import {
mdiCheck,
mdiArrowLeft,
mdiArrowRight,
mdiSort,
mdiCalendarRangeOutline,
mdiRefresh,
mdiSquareRounded,
mdiMenu,
@@ -347,7 +365,8 @@ export default {
'initEndTime',
'initFilterAccountIds',
'initFilterCategoryIds',
'initSortingType'
'initSortingType',
'initTrendDateAggregationType'
],
data() {
const { mdAndUp } = useDisplay();
@@ -359,6 +378,7 @@ export default {
alwaysShowNav: mdAndUp.value,
showNav: mdAndUp.value,
analysisType: statisticsConstants.allAnalysisTypes.CategoricalAnalysis,
trendDateAggregationType: statisticsConstants.allDateAggregationTypes.Month.type,
showCustomDateRangeDialog: false,
showCustomMonthRangeDialog: false,
showFilterAccountDialog: false,
@@ -367,7 +387,7 @@ export default {
check: mdiCheck,
left: mdiArrowLeft,
right: mdiArrowRight,
sort: mdiSort,
dateAggregation: mdiCalendarRangeOutline,
refresh: mdiRefresh,
square: mdiSquareRounded,
menu: mdiMenu,
@@ -442,6 +462,9 @@ export default {
return null;
}
},
queryTrendDateAggregationTypeName() {
return getNameByKeyValue(this.allDateAggregationTypesArray, this.trendDateAggregationType, 'type', 'displayName', '');
},
queryStartTime() {
if (this.queryAnalysisType === statisticsConstants.allAnalysisTypes.CategoricalAnalysis) {
return this.$locale.formatUnixTimeToLongDateTime(this.userStore, this.query.categoricalChartStartTime);
@@ -484,6 +507,9 @@ export default {
allSortingTypesArray() {
return this.$locale.getAllStatisticsSortingTypes();
},
allDateAggregationTypesArray() {
return this.$locale.getAllStatisticsDateAggregationTypes();
},
allDateRanges() {
return datetimeConstants.allDateRanges;
},
@@ -574,6 +600,7 @@ export default {
filterAccountIds: this.initFilterAccountIds,
filterCategoryIds: this.initFilterCategoryIds,
sortingType: this.initSortingType,
trendDateAggregationType: this.initTrendDateAggregationType,
});
},
setup() {
@@ -596,7 +623,8 @@ export default {
endTime: to.query.endTime,
filterAccountIds: to.query.filterAccountIds,
filterCategoryIds: to.query.filterCategoryIds,
sortingType: to.query.sortingType
sortingType: to.query.sortingType,
trendDateAggregationType: to.query.trendDateAggregationType
});
} else {
this.init({});
@@ -652,6 +680,10 @@ export default {
self.analysisType = statisticsConstants.allAnalysisTypes.TrendAnalysis;
needReload = true;
}
if (query.trendDateAggregationType) {
self.trendDateAggregationType = parseInt(query.trendDateAggregationType);
}
}
if (!isDefined(query.analysisType)) {
@@ -796,6 +828,14 @@ export default {
this.$router.push(this.getFilterLinkUrl());
}
},
setTrendDateAggregationType(aggregationType) {
const changed = this.trendDateAggregationType !== aggregationType;
this.trendDateAggregationType = aggregationType;
if (changed) {
this.$router.push(this.getFilterLinkUrl());
}
},
setDateFilter(dateType) {
if (this.queryAnalysisType === statisticsConstants.allAnalysisTypes.CategoricalAnalysis) {
if (dateType === this.allDateRanges.Custom.type) { // Custom
@@ -962,18 +1002,10 @@ export default {
}
},
clickPieChartItem(item) {
this.$router.push(this.getTransactionItemLinkUrl(item));
this.$router.push(this.getTransactionItemLinkUrl(item.id));
},
clickTrendChartItem(item) {
const minUnixTime = getYearMonthFirstUnixTime(item.yearMonth);
const maxUnixTime = getYearMonthLastUnixTime(item.yearMonth);
const dateRangeType = getDateTypeByDateRange(minUnixTime, maxUnixTime, this.firstDayOfWeek, datetimeConstants.allDateRangeScenes.Normal);
this.$router.push(this.getTransactionItemLinkUrl(item.item, {
minTime: minUnixTime,
maxTime: maxUnixTime,
type: dateRangeType,
}));
this.$router.push(this.getTransactionItemLinkUrl(item.itemId, item.dateRange));
},
getDisplayAmount(amount, currency, textLimit) {
amount = this.getDisplayCurrency(amount, currency);
@@ -998,10 +1030,10 @@ export default {
return formatPercent(value, precision, lowPrecisionValue);
},
getFilterLinkUrl() {
return `/statistics/transaction?${this.statisticsStore.getTransactionStatisticsPageParams(this.queryAnalysisType)}`;
return `/statistics/transaction?${this.statisticsStore.getTransactionStatisticsPageParams(this.queryAnalysisType, this.trendDateAggregationType)}`;
},
getTransactionItemLinkUrl(item, dateRange) {
return `/transaction/list?${this.statisticsStore.getTransactionListPageParams(this.queryAnalysisType, item, dateRange)}`;
getTransactionItemLinkUrl(itemId, dateRange) {
return `/transaction/list?${this.statisticsStore.getTransactionListPageParams(this.queryAnalysisType, itemId, dateRange)}`;
}
}
}