add chart type and chart data type settings for trend analysis

This commit is contained in:
MaysWind
2024-05-26 23:58:07 +08:00
parent a9e3b79eb1
commit 5eca777891
12 changed files with 367 additions and 116 deletions
+65 -8
View File
@@ -1,5 +1,10 @@
import datetime from './datetime.js';
const allAnalysisTypes = {
CategoricalAnalysis: 0,
TrendAnalysis: 1
};
const allCategoricalChartTypes = {
Pie: 0,
Bar: 1
@@ -18,38 +23,86 @@ const allCategoricalChartTypesArray = [
const defaultCategoricalChartType = allCategoricalChartTypes.Pie;
const allTrendChartTypes = {
Area: 0,
Column: 1
};
const allTrendChartTypesArray = [
{
name: 'Area Chart',
type: allTrendChartTypes.Area
},
{
name: 'Column Chart',
type: allTrendChartTypes.Column
}
];
const defaultTrendChartType = allTrendChartTypes.Area;
const allChartDataTypes = {
ExpenseByAccount: {
type: 0,
name: 'Expense By Account'
name: 'Expense By Account',
availableAnalysisTypes: {
[allAnalysisTypes.CategoricalAnalysis]: true,
[allAnalysisTypes.TrendAnalysis]: true,
}
},
ExpenseByPrimaryCategory: {
type: 1,
name: 'Expense By Primary Category'
name: 'Expense By Primary Category',
availableAnalysisTypes: {
[allAnalysisTypes.CategoricalAnalysis]: true,
[allAnalysisTypes.TrendAnalysis]: true,
}
},
ExpenseBySecondaryCategory: {
type: 2,
name: 'Expense By Secondary Category'
name: 'Expense By Secondary Category',
availableAnalysisTypes: {
[allAnalysisTypes.CategoricalAnalysis]: true,
[allAnalysisTypes.TrendAnalysis]: true,
}
},
IncomeByAccount: {
type: 3,
name: 'Income By Account'
name: 'Income By Account',
availableAnalysisTypes: {
[allAnalysisTypes.CategoricalAnalysis]: true,
[allAnalysisTypes.TrendAnalysis]: true,
}
},
IncomeByPrimaryCategory: {
type: 4,
name: 'Income By Primary Category'
name: 'Income By Primary Category',
availableAnalysisTypes: {
[allAnalysisTypes.CategoricalAnalysis]: true,
[allAnalysisTypes.TrendAnalysis]: true,
}
},
IncomeBySecondaryCategory: {
type: 5,
name: 'Income By Secondary Category'
name: 'Income By Secondary Category',
availableAnalysisTypes: {
[allAnalysisTypes.CategoricalAnalysis]: true,
[allAnalysisTypes.TrendAnalysis]: true,
}
},
AccountTotalAssets: {
type: 6,
name: 'Account Total Assets'
name: 'Account Total Assets',
availableAnalysisTypes: {
[allAnalysisTypes.CategoricalAnalysis]: true
}
},
AccountTotalLiabilities: {
type: 7,
name: 'Account Total Liabilities'
name: 'Account Total Liabilities',
availableAnalysisTypes: {
[allAnalysisTypes.CategoricalAnalysis]: true
}
}
};
@@ -82,9 +135,13 @@ const allSortingTypesArray = [
const defaultSortingType = allSortingTypes.Amount.type;
export default {
allAnalysisTypes: allAnalysisTypes,
allCategoricalChartTypes: allCategoricalChartTypes,
allCategoricalChartTypesArray: allCategoricalChartTypesArray,
defaultCategoricalChartType: defaultCategoricalChartType,
allTrendChartTypes: allTrendChartTypes,
allTrendChartTypesArray: allTrendChartTypesArray,
defaultTrendChartType: defaultTrendChartType,
allChartDataTypes: allChartDataTypes,
defaultChartDataType: defaultChartDataType,
defaultDataRangeType: datetime.allDateRanges.ThisMonth.type,
+18 -1
View File
@@ -823,6 +823,21 @@ function getAllCategoricalChartTypes(translateFn) {
return allChartTypes;
}
function getAllTrendChartTypes(translateFn) {
const allChartTypes = [];
for (let i = 0; i < statistics.allTrendChartTypesArray.length; i++) {
const chartType = statistics.allTrendChartTypesArray[i];
allChartTypes.push({
type: chartType.type,
displayName: translateFn(chartType.name)
});
}
return allChartTypes;
}
function getAllStatisticsChartDataTypes(translateFn) {
const allChartDataTypes = [];
@@ -835,7 +850,8 @@ function getAllStatisticsChartDataTypes(translateFn) {
allChartDataTypes.push({
type: chartDataType.type,
displayName: translateFn(chartDataType.name)
displayName: translateFn(chartDataType.name),
availableAnalysisTypes: chartDataType.availableAnalysisTypes
});
}
@@ -1367,6 +1383,7 @@ export function i18nFunctions(i18nGlobal) {
getAllAccountCategories: () => getAllAccountCategories(i18nGlobal.t),
getAllAccountTypes: () => getAllAccountTypes(i18nGlobal.t),
getAllCategoricalChartTypes: () => getAllCategoricalChartTypes(i18nGlobal.t),
getAllTrendChartTypes: () => getAllTrendChartTypes(i18nGlobal.t),
getAllStatisticsChartDataTypes: () => getAllStatisticsChartDataTypes(i18nGlobal.t),
getAllStatisticsSortingTypes: () => getAllStatisticsSortingTypes(i18nGlobal.t),
getAllTransactionEditScopeTypes: () => getAllTransactionEditScopeTypes(i18nGlobal.t),
+19 -10
View File
@@ -21,13 +21,14 @@ const defaultSettings = {
showTotalAmountInTransactionListPage: true,
showAccountBalance: true,
statistics: {
defaultChartType: statisticsConstants.defaultCategoricalChartType,
defaultChartDataType: statisticsConstants.defaultChartDataType,
defaultDataRangeType: statisticsConstants.defaultDataRangeType,
defaultTimezoneType: timezoneConstants.defaultTimezoneTypesUsedForStatistics,
defaultAccountFilter: {},
defaultTransactionCategoryFilter: {},
defaultSortingType: statisticsConstants.defaultSortingType
defaultSortingType: statisticsConstants.defaultSortingType,
defaultCategoricalChartType: statisticsConstants.defaultCategoricalChartType,
defaultTrendChartType: statisticsConstants.defaultTrendChartType,
},
animate: true
};
@@ -221,14 +222,6 @@ export function setShowAccountBalance(value) {
setOption('showAccountBalance', value);
}
export function getStatisticsDefaultChartType() {
return getSubOption('statistics', 'defaultChartType');
}
export function setStatisticsDefaultChartType(value) {
setSubOption('statistics', 'defaultChartType', value);
}
export function getStatisticsDefaultChartDataType() {
return getSubOption('statistics', 'defaultChartDataType');
}
@@ -277,6 +270,22 @@ export function setStatisticsSortingType(value) {
setSubOption('statistics', 'defaultSortingType', value);
}
export function getStatisticsDefaultCategoricalChartType() {
return getSubOption('statistics', 'defaultCategoricalChartType');
}
export function setStatisticsDefaultCategoricalChartType(value) {
setSubOption('statistics', 'defaultCategoricalChartType', value);
}
export function getStatisticsDefaultTrendChartType() {
return getSubOption('statistics', 'defaultTrendChartType');
}
export function setStatisticsDefaultTrendChartType(value) {
setSubOption('statistics', 'defaultTrendChartType', value);
}
export function isEnableAnimate() {
return getOption('animate');
}
+19
View File
@@ -0,0 +1,19 @@
import statisticsConstants from '@/consts/statistics.js';
export function isChartDataTypeAvailableForAnalysisType(chartDataType, analysisType) {
for (const dataTypeField in statisticsConstants.allChartDataTypes) {
if (!Object.prototype.hasOwnProperty.call(statisticsConstants.allChartDataTypes, dataTypeField)) {
continue;
}
const dataTypeItem = statisticsConstants.allChartDataTypes[dataTypeField];
if (dataTypeItem.type !== chartDataType) {
continue;
}
return !!dataTypeItem.availableAnalysisTypes[analysisType];
}
return false;
}
+6
View File
@@ -768,6 +768,8 @@ export default {
'Custom': 'Custom',
'Pie Chart': 'Pie Chart',
'Bar Chart': 'Bar Chart',
'Area Chart': 'Area Chart',
'Column Chart': 'Column Chart',
'Sort by': 'Sort by',
'User': 'User',
'Application': 'Application',
@@ -995,6 +997,7 @@ export default {
'Unable to delete this transaction': 'Unable to delete this transaction',
'Unable to retrieve transaction statistics': 'Unable to retrieve transaction statistics',
'Categorical Analysis': 'Categorical Analysis',
'Trend Analysis': 'Trend Analysis',
'Total Amount': 'Total Amount',
'Total Assets': 'Total Assets',
'Total Liabilities': 'Total Liabilities',
@@ -1009,6 +1012,9 @@ export default {
'Account Total Assets': 'Account Total Assets',
'Account Total Liabilities': 'Account Total Liabilities',
'Statistics Settings': 'Statistics Settings',
'Common Settings': 'Common Settings',
'Categorical Analysis Settings': 'Categorical Analysis Settings',
'Trend Analysis Settings': 'Trend Analysis Settings',
'Chart Type': 'Chart Type',
'Default Chart Type': 'Default Chart Type',
'Chart Data Type': 'Chart Data Type',
+6
View File
@@ -768,6 +768,8 @@ export default {
'Custom': '自定义',
'Pie Chart': '饼图',
'Bar Chart': '条形图',
'Area Chart': '面积图',
'Column Chart': '柱状图',
'Sort by': '排序方式',
'User': '用户',
'Application': '应用',
@@ -995,6 +997,7 @@ export default {
'Unable to delete this transaction': '无法删除该交易',
'Unable to retrieve transaction statistics': '无法获取交易统计数据',
'Categorical Analysis': '分类分析',
'Trend Analysis': '趋势分析',
'Total Amount': '总金额',
'Total Assets': '总资产',
'Total Liabilities': '总负债',
@@ -1009,6 +1012,9 @@ export default {
'Account Total Assets': '账户总资产',
'Account Total Liabilities': '账户总负债',
'Statistics Settings': '统计设置',
'Common Settings': '通用设置',
'Categorical Analysis Settings': '分类分析设置',
'Trend Analysis Settings': '趋势分析设置',
'Chart Type': '图表类型',
'Default Chart Type': '默认图表类型',
'Chart Data Type': '图表数据类型',
+11 -6
View File
@@ -22,13 +22,14 @@ export const useSettingsStore = defineStore('settings', {
showTotalAmountInTransactionListPage: settings.isShowTotalAmountInTransactionListPage(),
showAccountBalance: settings.isShowAccountBalance(),
statistics: {
defaultChartType: settings.getStatisticsDefaultChartType(),
defaultChartDataType: settings.getStatisticsDefaultChartDataType(),
defaultDataRangeType: settings.getStatisticsDefaultDateRange(),
defaultTimezoneType: settings.getStatisticsDefaultTimezoneType(),
defaultAccountFilter: settings.getStatisticsDefaultAccountFilter(),
defaultTransactionCategoryFilter: settings.getStatisticsDefaultTransactionCategoryFilter(),
defaultSortingType: settings.getStatisticsSortingType()
defaultSortingType: settings.getStatisticsSortingType(),
defaultCategoricalChartType: settings.getStatisticsDefaultCategoricalChartType(),
defaultTrendChartType: settings.getStatisticsDefaultTrendChartType(),
},
animate: settings.isEnableAnimate()
},
@@ -94,10 +95,6 @@ export const useSettingsStore = defineStore('settings', {
settings.setShowAccountBalance(value);
this.appSettings.showAccountBalance = value;
},
setStatisticsDefaultChartType(value) {
settings.setStatisticsDefaultChartType(value);
this.appSettings.statistics.defaultChartType = value;
},
setStatisticsDefaultChartDataType(value) {
settings.setStatisticsDefaultChartDataType(value);
this.appSettings.statistics.defaultChartDataType = value;
@@ -122,6 +119,14 @@ export const useSettingsStore = defineStore('settings', {
settings.setStatisticsSortingType(value);
this.appSettings.statistics.defaultSortingType = value;
},
setStatisticsDefaultCategoricalChartType(value) {
settings.setStatisticsDefaultCategoricalChartType(value);
this.appSettings.statistics.defaultCategoricalChartType = value;
},
setStatisticsDefaultTrendChartType(value) {
settings.setStatisticsDefaultTrendChartType(value);
this.appSettings.statistics.defaultTrendChartType = value;
},
setEnableAnimate(value) {
settings.setEnableAnimate(value);
this.appSettings.animate = value;
+36 -14
View File
@@ -28,8 +28,9 @@ export const useStatisticsStore = defineStore('statistics', {
dateType: statisticsConstants.defaultDataRangeType,
startTime: 0,
endTime: 0,
chartType: statisticsConstants.defaultCategoricalChartType,
chartDataType: statisticsConstants.defaultChartDataType,
categoricalChartType: statisticsConstants.defaultCategoricalChartType,
trendChartType: statisticsConstants.defaultTrendChartType,
filterAccountIds: {},
filterCategoryIds: {}
},
@@ -410,8 +411,9 @@ export const useStatisticsStore = defineStore('statistics', {
this.transactionStatisticsFilter.dateType = statisticsConstants.defaultDataRangeType;
this.transactionStatisticsFilter.startTime = 0;
this.transactionStatisticsFilter.endTime = 0;
this.transactionStatisticsFilter.chartType = statisticsConstants.defaultCategoricalChartType;
this.transactionStatisticsFilter.chartDataType = statisticsConstants.defaultChartDataType;
this.transactionStatisticsFilter.categoricalChartType = statisticsConstants.defaultCategoricalChartType;
this.transactionStatisticsFilter.trendChartType = statisticsConstants.defaultTrendChartType;
this.transactionStatisticsFilter.filterAccountIds = {};
this.transactionStatisticsFilter.filterCategoryIds = {};
this.transactionCategoryStatisticsData = {};
@@ -422,12 +424,6 @@ export const useStatisticsStore = defineStore('statistics', {
const settingsStore = useSettingsStore();
const userStore = useUserStore();
let defaultChartType = settingsStore.appSettings.statistics.defaultChartType;
if (defaultChartType !== statisticsConstants.allCategoricalChartTypes.Pie && defaultChartType !== statisticsConstants.allCategoricalChartTypes.Bar) {
defaultChartType = statisticsConstants.defaultCategoricalChartType;
}
let defaultChartDataType = settingsStore.appSettings.statistics.defaultChartDataType;
if (defaultChartDataType < statisticsConstants.allChartDataTypes.ExpenseByAccount.type || defaultChartDataType > statisticsConstants.allChartDataTypes.AccountTotalLiabilities.type) {
@@ -440,6 +436,18 @@ export const useStatisticsStore = defineStore('statistics', {
defaultDateRange = statisticsConstants.defaultDataRangeType;
}
let defaultCategoricalChartType = settingsStore.appSettings.statistics.defaultCategoricalChartType;
if (defaultCategoricalChartType !== statisticsConstants.allCategoricalChartTypes.Pie && defaultCategoricalChartType !== statisticsConstants.allCategoricalChartTypes.Bar) {
defaultCategoricalChartType = statisticsConstants.defaultCategoricalChartType;
}
let defaultTrendChartType = settingsStore.appSettings.statistics.defaultTrendChartType;
if (defaultTrendChartType !== statisticsConstants.allTrendChartTypes.Area && defaultTrendChartType !== statisticsConstants.allTrendChartTypes.Column) {
defaultTrendChartType = statisticsConstants.defaultTrendChartType;
}
let defaultSortType = settingsStore.appSettings.statistics.defaultSortingType;
if (defaultSortType < statisticsConstants.allSortingTypes.Amount.type || defaultSortType > statisticsConstants.allSortingTypes.Name.type) {
@@ -452,7 +460,8 @@ export const useStatisticsStore = defineStore('statistics', {
dateType: dateRange ? dateRange.dateType : undefined,
startTime: dateRange ? dateRange.minTime : undefined,
endTime: dateRange ? dateRange.maxTime : undefined,
chartType: defaultChartType,
categoricalChartType: defaultCategoricalChartType,
trendChartType: defaultTrendChartType,
chartDataType: defaultChartDataType,
filterAccountIds: settingsStore.appSettings.statistics.defaultAccountFilter || {},
filterCategoryIds: settingsStore.appSettings.statistics.defaultTransactionCategoryFilter || {},
@@ -478,10 +487,16 @@ export const useStatisticsStore = defineStore('statistics', {
this.transactionStatisticsFilter.endTime = 0;
}
if (filter && isNumber(filter.chartType)) {
this.transactionStatisticsFilter.chartType = filter.chartType;
if (filter && isNumber(filter.categoricalChartType)) {
this.transactionStatisticsFilter.categoricalChartType = filter.categoricalChartType;
} else {
this.transactionStatisticsFilter.chartType = statisticsConstants.defaultCategoricalChartType;
this.transactionStatisticsFilter.categoricalChartType = statisticsConstants.defaultCategoricalChartType;
}
if (filter && isNumber(filter.trendChartType)) {
this.transactionStatisticsFilter.trendChartType = filter.trendChartType;
} else {
this.transactionStatisticsFilter.trendChartType = statisticsConstants.defaultTrendChartType;
}
if (filter && isNumber(filter.chartDataType)) {
@@ -521,8 +536,12 @@ export const useStatisticsStore = defineStore('statistics', {
this.transactionStatisticsFilter.endTime = filter.endTime;
}
if (filter && isNumber(filter.chartType)) {
this.transactionStatisticsFilter.chartType = filter.chartType;
if (filter && isNumber(filter.categoricalChartType)) {
this.transactionStatisticsFilter.categoricalChartType = filter.categoricalChartType;
}
if (filter && isNumber(filter.trendChartType)) {
this.transactionStatisticsFilter.trendChartType = filter.trendChartType;
}
if (filter && isNumber(filter.chartDataType)) {
@@ -620,5 +639,8 @@ export const useStatisticsStore = defineStore('statistics', {
});
});
},
loadTrendAnalysis({ force }) {
return Promise.resolve(true);
},
}
});
@@ -5,18 +5,6 @@
<v-form>
<v-card-text>
<v-row>
<v-col cols="12" md="6">
<v-select
item-title="displayName"
item-value="type"
persistent-placeholder
:label="$t('Default Chart Type')"
:placeholder="$t('Default Chart Type')"
:items="allCategoricalChartTypes"
v-model="defaultChartType"
/>
</v-col>
<v-col cols="12" md="6">
<v-select
item-title="displayName"
@@ -70,6 +58,50 @@
</v-card>
</v-col>
<v-col cols="12">
<v-card :title="$t('Categorical Analysis Settings')">
<v-form>
<v-card-text>
<v-row>
<v-col cols="12" md="6">
<v-select
item-title="displayName"
item-value="type"
persistent-placeholder
:label="$t('Default Chart Type')"
:placeholder="$t('Default Chart Type')"
:items="allCategoricalChartTypes"
v-model="defaultCategoricalChartType"
/>
</v-col>
</v-row>
</v-card-text>
</v-form>
</v-card>
</v-col>
<v-col cols="12">
<v-card :title="$t('Trend Analysis Settings')">
<v-form>
<v-card-text>
<v-row>
<v-col cols="12" md="6">
<v-select
item-title="displayName"
item-value="type"
persistent-placeholder
:label="$t('Default Chart Type')"
:placeholder="$t('Default Chart Type')"
:items="allTrendChartTypes"
v-model="defaultTrendChartType"
/>
</v-col>
</v-row>
</v-card-text>
</v-form>
</v-card>
</v-col>
<v-col cols="12">
<account-filter-settings-card :auto-save="true" :modify-default="true" />
</v-col>
@@ -96,29 +128,24 @@ export default {
},
computed: {
...mapStores(useSettingsStore),
allCategoricalChartTypes() {
return this.$locale.getAllCategoricalChartTypes();
},
allChartDataTypes() {
return this.$locale.getAllStatisticsChartDataTypes();
},
allSortingTypes() {
return this.$locale.getAllStatisticsSortingTypes();
},
allCategoricalChartTypes() {
return this.$locale.getAllCategoricalChartTypes();
},
allTrendChartTypes() {
return this.$locale.getAllTrendChartTypes();
},
allDateRanges() {
return this.$locale.getAllDateRanges(false);
},
allTimezoneTypesUsedForStatistics() {
return this.$locale.getAllTimezoneTypesUsedForStatistics();
},
defaultChartType: {
get: function () {
return this.settingsStore.appSettings.statistics.defaultChartType;
},
set: function (value) {
this.settingsStore.setStatisticsDefaultChartType(value);
}
},
defaultChartDataType: {
get: function () {
return this.settingsStore.appSettings.statistics.defaultChartDataType;
@@ -150,6 +177,22 @@ export default {
set: function (value) {
this.settingsStore.setStatisticsSortingType(value);
}
},
defaultCategoricalChartType: {
get: function () {
return this.settingsStore.appSettings.statistics.defaultCategoricalChartType;
},
set: function (value) {
this.settingsStore.setStatisticsDefaultCategoricalChartType(value);
}
},
defaultTrendChartType: {
get: function () {
return this.settingsStore.appSettings.statistics.defaultTrendChartType;
},
set: function (value) {
this.settingsStore.setStatisticsDefaultTrendChartType(value);
}
}
}
};
@@ -6,11 +6,12 @@
<v-navigation-drawer :permanent="alwaysShowNav" v-model="showNav">
<div class="mx-6 my-4">
<btn-vertical-group :disabled="loading" :buttons="[
{ name: $t('Categorical Analysis'), value: 'categoricalAnalysis' },
]" v-model="activeTab" />
{ name: $t('Categorical Analysis'), value: allAnalysisTypes.CategoricalAnalysis },
{ name: $t('Trend Analysis'), value: allAnalysisTypes.TrendAnalysis }
]" v-model="analysisType" />
</div>
<v-divider />
<div class="mx-6 mt-4" v-if="activeTab === 'categoricalAnalysis'">
<div class="mx-6 mt-4">
<span class="text-subtitle-2">{{ $t('Chart Type') }}</span>
<v-select
item-title="displayName"
@@ -22,7 +23,7 @@
v-model="queryChartType"
/>
</div>
<div class="mx-6 mt-4" v-if="activeTab === 'categoricalAnalysis'">
<div class="mx-6 mt-4">
<span class="text-subtitle-2">{{ $t('Sort Order') }}</span>
<v-select
item-title="displayName"
@@ -35,10 +36,9 @@
/>
</div>
<v-tabs show-arrows class="my-4" direction="vertical"
:disabled="loading" v-model="query.chartDataType"
v-if="activeTab === 'categoricalAnalysis'">
:disabled="loading" v-model="query.chartDataType">
<v-tab class="tab-text-truncate" :key="dataType.type" :value="dataType.type"
v-for="dataType in allChartDataTypes">
v-for="dataType in allChartDataTypes" v-show="dataType.availableAnalysisTypes[analysisType]">
<span class="text-truncate">{{ $t(dataType.name) }}</span>
<v-tooltip activator="parent" location="right">{{ $t(dataType.name) }}</v-tooltip>
</v-tab>
@@ -46,7 +46,7 @@
</v-navigation-drawer>
<v-main>
<v-window class="d-flex flex-grow-1 disable-tab-transition w-100-window-container" v-model="activeTab">
<v-window-item value="categoricalAnalysis">
<v-window-item value="statisticsPage">
<v-card variant="flat" min-height="680">
<template #title>
<div class="title-and-toolbar d-flex align-center">
@@ -55,7 +55,8 @@
<v-icon :icon="icons.menu" size="24" />
</v-btn>
<span>{{ $t('Statistics & Analysis') }}</span>
<v-btn-group class="ml-4" color="default" density="comfortable" variant="outlined" divided>
<v-btn-group class="ml-4" color="default" density="comfortable" variant="outlined" divided
v-if="analysisType === allAnalysisTypes.CategoricalAnalysis">
<v-btn :icon="icons.left"
:disabled="loading || query.dateType === allDateRanges.All.type || query.chartDataType === allChartDataTypes.AccountTotalAssets.type || query.chartDataType === allChartDataTypes.AccountTotalLiabilities.type"
@click="shiftDateRange(query.startTime, query.endTime, -1)"/>
@@ -118,7 +119,7 @@
</template>
<v-card-text class="statistics-overview-title pt-0" :class="{ 'disabled': loading }"
v-if="initing || (categoricalAnalysisData && categoricalAnalysisData.items && categoricalAnalysisData.items.length)">
v-if="initing || (analysisType === allAnalysisTypes.CategoricalAnalysis && categoricalAnalysisData && categoricalAnalysisData.items && categoricalAnalysisData.items.length)">
<span class="statistics-subtitle">{{ totalAmountName }}</span>
<span class="statistics-overview-amount ml-3"
:class="statisticsTextColor"
@@ -131,11 +132,11 @@
</v-card-text>
<v-card-text class="statistics-overview-title pt-0"
v-else-if="!initing && (!categoricalAnalysisData || !categoricalAnalysisData.items || !categoricalAnalysisData.items.length)">
v-else-if="!initing && (analysisType === allAnalysisTypes.CategoricalAnalysis && !categoricalAnalysisData || !categoricalAnalysisData.items || !categoricalAnalysisData.items.length)">
<span class="statistics-subtitle statistics-overview-empty-tip">{{ $t('No transaction data') }}</span>
</v-card-text>
<v-card-text :class="{ 'readonly': loading }" v-if="query.chartType === allCategoricalChartTypes.Pie">
<v-card-text :class="{ 'readonly': loading }" v-if="analysisType === allAnalysisTypes.CategoricalAnalysis && query.categoricalChartType === allCategoricalChartTypes.Pie">
<pie-chart
:items="[
{id: '1', name: '---', value: 60, color: '7c7c7f'},
@@ -166,7 +167,7 @@
/>
</v-card-text>
<v-card-text :class="{ 'readonly': loading }" v-if="query.chartType === allCategoricalChartTypes.Bar">
<v-card-text :class="{ 'readonly': loading }" v-if="analysisType === allAnalysisTypes.CategoricalAnalysis && query.categoricalChartType === allCategoricalChartTypes.Bar">
<v-list rounded lines="two" v-if="initing">
<template :key="itemIdx" v-for="itemIdx in [ 1, 2, 3 ]">
<v-list-item class="pl-0">
@@ -262,11 +263,12 @@ import { useStatisticsStore } from '@/stores/statistics.js';
import datetimeConstants from '@/consts/datetime.js';
import statisticsConstants from '@/consts/statistics.js';
import { limitText, formatPercent } from '@/lib/common.js'
import { isArray, limitText, formatPercent } from '@/lib/common.js'
import {
getShiftedDateRangeAndDateType,
getDateRangeByDateType
} from '@/lib/datetime.js';
import { isChartDataTypeAvailableForAnalysisType } from '@/lib/statistics.js';
import {
mdiCheck,
@@ -294,11 +296,12 @@ export default {
const { mdAndUp } = useDisplay();
return {
activeTab: 'categoricalAnalysis',
activeTab: 'statisticsPage',
initing: true,
loading: true,
alwaysShowNav: mdAndUp.value,
showNav: mdAndUp.value,
analysisType: statisticsConstants.allAnalysisTypes.CategoricalAnalysis,
showCustomDateRangeDialog: false,
showFilterAccountDialog: false,
showFilterCategoryDialog: false,
@@ -336,7 +339,13 @@ export default {
},
queryChartType: {
get: function () {
return this.query.chartType;
if (this.analysisType === statisticsConstants.allAnalysisTypes.CategoricalAnalysis) {
return this.query.categoricalChartType;
} else if (this.analysisType === statisticsConstants.allAnalysisTypes.TrendAnalysis) {
return this.query.trendChartType;
} else {
return null;
}
},
set: function(value) {
this.setChartType(value);
@@ -356,8 +365,17 @@ export default {
queryEndTime() {
return this.$locale.formatUnixTimeToLongDateTime(this.userStore, this.query.endTime);
},
allAnalysisTypes() {
return statisticsConstants.allAnalysisTypes;
},
allChartTypes() {
return this.$locale.getAllCategoricalChartTypes();
if (this.analysisType === statisticsConstants.allAnalysisTypes.CategoricalAnalysis) {
return this.$locale.getAllCategoricalChartTypes();
} else if (this.analysisType === statisticsConstants.allAnalysisTypes.TrendAnalysis) {
return this.$locale.getAllTrendChartTypes();
} else {
return [];
}
},
allCategoricalChartTypes() {
return statisticsConstants.allCategoricalChartTypes;
@@ -420,6 +438,11 @@ export default {
}
},
watch: {
'analysisType': function (newValue) {
if (!isChartDataTypeAvailableForAnalysisType(this.query.chartDataType, newValue)) {
this.query.chartDataType = statisticsConstants.defaultChartDataType;
}
},
'query.chartDataType': function (newValue) {
this.statisticsStore.updateTransactionStatisticsFilter({
chartDataType: newValue
@@ -442,9 +465,15 @@ export default {
self.accountsStore.loadAllAccounts({ force: false }),
self.transactionCategoriesStore.loadAllCategories({ force: false })
]).then(() => {
return self.statisticsStore.loadCategoricalAnalysis({
force: false
});
if (self.analysisType === statisticsConstants.allAnalysisTypes.CategoricalAnalysis) {
return self.statisticsStore.loadCategoricalAnalysis({
force: false
});
} else if (self.analysisType === statisticsConstants.allAnalysisTypes.TrendAnalysis) {
return self.statisticsStore.loadTrendAnalysis({
force: false
});
}
}).then(() => {
self.loading = false;
self.initing = false;
@@ -479,9 +508,15 @@ export default {
self.query.chartDataType === self.allChartDataTypes.IncomeByAccount.type ||
self.query.chartDataType === self.allChartDataTypes.IncomeByPrimaryCategory.type ||
self.query.chartDataType === self.allChartDataTypes.IncomeBySecondaryCategory.type) {
dispatchPromise = self.statisticsStore.loadCategoricalAnalysis({
force: force
});
if (this.analysisType === statisticsConstants.allAnalysisTypes.CategoricalAnalysis) {
dispatchPromise = self.statisticsStore.loadCategoricalAnalysis({
force: force
});
} else if (this.analysisType === statisticsConstants.allAnalysisTypes.TrendAnalysis) {
dispatchPromise = self.statisticsStore.loadTrendAnalysis({
force: force
});
}
} else if (self.query.chartDataType === self.allChartDataTypes.AccountTotalAssets.type ||
self.query.chartDataType === self.allChartDataTypes.AccountTotalLiabilities.type) {
dispatchPromise = self.accountsStore.loadAllAccounts({
@@ -506,9 +541,15 @@ export default {
}
},
setChartType(chartType) {
this.statisticsStore.updateTransactionStatisticsFilter({
chartType: chartType
});
if (this.analysisType === statisticsConstants.allAnalysisTypes.CategoricalAnalysis) {
this.statisticsStore.updateTransactionStatisticsFilter({
categoricalChartType: chartType
});
} else if (this.analysisType === statisticsConstants.allAnalysisTypes.TrendAnalysis) {
this.statisticsStore.updateTransactionStatisticsFilter({
trendChartType: chartType
});
}
},
setSortingType(sortingType) {
if (sortingType < this.allSortingTypes.Amount.type || sortingType > this.allSortingTypes.Name.type) {
+50 -24
View File
@@ -2,17 +2,8 @@
<f7-page>
<f7-navbar :title="$t('Statistics Settings')" :back-link="$t('Back')"></f7-navbar>
<f7-list strong inset dividers class="margin-top">
<f7-list-item
:title="$t('Default Chart Type')"
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Chart Type'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), popupCloseLinkText: $t('Done') }">
<select v-model="defaultChartType">
<option :value="chartType.type"
:key="chartType.type"
v-for="chartType in allCategoricalChartTypes">{{ chartType.displayName }}</option>
</select>
</f7-list-item>
<f7-block-title class="margin-top">{{ $t('Common Settings') }}</f7-block-title>
<f7-list strong inset dividers>
<f7-list-item
:title="$t('Default Chart Data Type')"
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Chart Data Type'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), popupCloseLinkText: $t('Done') }">
@@ -57,6 +48,32 @@
</select>
</f7-list-item>
</f7-list>
<f7-block-title>{{ $t('Categorical Analysis Settings') }}</f7-block-title>
<f7-list strong inset dividers>
<f7-list-item
:title="$t('Default Chart Type')"
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Chart Type'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), popupCloseLinkText: $t('Done') }">
<select v-model="defaultCategoricalChartType">
<option :value="chartType.type"
:key="chartType.type"
v-for="chartType in allCategoricalChartTypes">{{ chartType.displayName }}</option>
</select>
</f7-list-item>
</f7-list>
<f7-block-title>{{ $t('Trend Analysis Settings') }}</f7-block-title>
<f7-list strong inset dividers>
<f7-list-item
:title="$t('Default Chart Type')"
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Chart Type'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), popupCloseLinkText: $t('Done') }">
<select v-model="defaultTrendChartType">
<option :value="chartType.type"
:key="chartType.type"
v-for="chartType in allTrendChartTypes">{{ chartType.displayName }}</option>
</select>
</f7-list-item>
</f7-list>
</f7-page>
</template>
@@ -64,34 +81,27 @@
import { mapStores } from 'pinia';
import { useSettingsStore } from '@/stores/setting.js';
import statisticsConstants from '@/consts/statistics.js';
export default {
computed: {
...mapStores(useSettingsStore),
allCategoricalChartTypes() {
return this.$locale.getAllCategoricalChartTypes();
},
allChartDataTypes() {
return this.$locale.getAllStatisticsChartDataTypes();
},
allSortingTypes() {
return this.$locale.getAllStatisticsSortingTypes();
},
allCategoricalChartTypes() {
return this.$locale.getAllCategoricalChartTypes();
},
allTrendChartTypes() {
return this.$locale.getAllTrendChartTypes();
},
allDateRanges() {
return this.$locale.getAllDateRanges(false);
},
allTimezoneTypesUsedForStatistics() {
return this.$locale.getAllTimezoneTypesUsedForStatistics();
},
defaultChartType: {
get: function () {
return this.settingsStore.appSettings.statistics.defaultChartType;
},
set: function (value) {
this.settingsStore.setStatisticsDefaultChartType(value);
}
},
defaultChartDataType: {
get: function () {
return this.settingsStore.appSettings.statistics.defaultChartDataType;
@@ -123,6 +133,22 @@ export default {
set: function (value) {
this.settingsStore.setStatisticsSortingType(value);
}
},
defaultCategoricalChartType: {
get: function () {
return this.settingsStore.appSettings.statistics.defaultCategoricalChartType;
},
set: function (value) {
this.settingsStore.setStatisticsDefaultCategoricalChartType(value);
}
},
defaultTrendChartType: {
get: function () {
return this.settingsStore.appSettings.statistics.defaultTrendChartType;
},
set: function (value) {
this.settingsStore.setStatisticsDefaultTrendChartType(value);
}
}
}
};
@@ -28,7 +28,7 @@
</f7-list>
</f7-popover>
<f7-card v-if="query.chartType === allCategoricalChartTypes.Pie">
<f7-card v-if="query.categoricalChartType === allCategoricalChartTypes.Pie">
<f7-card-header class="no-border display-block">
<div class="statistics-chart-header full-line text-align-right">
<span style="margin-right: 4px;">{{ $t('Sort by') }}</span>
@@ -77,7 +77,7 @@
</f7-card-content>
</f7-card>
<f7-card v-else-if="query.chartType === allCategoricalChartTypes.Bar">
<f7-card v-else-if="query.categoricalChartType === allCategoricalChartTypes.Bar">
<f7-card-header class="no-border display-block">
<div class="statistics-chart-header display-flex full-line justify-content-space-between">
<div>
@@ -198,7 +198,7 @@
</f7-link>
<f7-link class="tabbar-text-with-ellipsis" :key="chartType.type"
v-for="chartType in allChartTypes" @click="setChartType(chartType.type)">
<span :class="{ 'tabbar-item-changed': query.chartType === chartType.type }">{{ chartType.displayName }}</span>
<span :class="{ 'tabbar-item-changed': query.categoricalChartType === chartType.type }">{{ chartType.displayName }}</span>
</f7-link>
</f7-toolbar>
@@ -438,7 +438,7 @@ export default {
},
setChartType(chartType) {
this.statisticsStore.updateTransactionStatisticsFilter({
chartType: chartType
categoricalChartType: chartType
});
},
setChartDataType(chartDataType) {