mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-14 06:57:35 +08:00
add chart type and chart data type settings for trend analysis
This commit is contained in:
@@ -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
@@ -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
@@ -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');
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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',
|
||||
|
||||
@@ -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
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user