diff --git a/src/consts/statistics.js b/src/consts/statistics.js index f6664e1c..36a9ab40 100644 --- a/src/consts/statistics.js +++ b/src/consts/statistics.js @@ -14,7 +14,7 @@ const allChartDataTypes = { IncomeBySecondaryCategory: 5 }; -const defaultChartDataType = allChartDataTypes.ExpenseBySecondaryCategory; +const defaultChartDataType = allChartDataTypes.ExpenseByPrimaryCategory; export default { allChartTypes: allChartTypes, diff --git a/src/store/index.js b/src/store/index.js index 0895d932..51fc07fc 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -771,8 +771,18 @@ const stores = { item.category = state.allTransactionCategoriesMap[item.categoryId]; } + if (item.category && item.category.parentId !== '0') { + item.primaryCategory = state.allTransactionCategoriesMap[item.category.parentId]; + } else { + item.primaryCategory = item.category; + } + if (item.account && item.account.currency !== defaultCurrency) { - item.amountInDefaultCurrency = getExchangedAmount(state)(item.amount, item.account.currency, defaultCurrency); + const amount = getExchangedAmount(state)(item.amount, item.account.currency, defaultCurrency); + + if (utils.isNumber(amount)) { + item.amountInDefaultCurrency = Math.floor(amount); + } } else if (item.account && item.account.currency === defaultCurrency) { item.amountInDefaultCurrency = item.amount; } else { diff --git a/src/views/mobile/statistics/Transaction.vue b/src/views/mobile/statistics/Transaction.vue index 1b776aa8..6cca5af3 100644 --- a/src/views/mobile/statistics/Transaction.vue +++ b/src/views/mobile/statistics/Transaction.vue @@ -2,12 +2,25 @@ - - - - + + + {{ query.chartDataType | chartDataTypeName(allChartDataTypes) | localized }} + + + + + + + + + + + @@ -31,22 +44,6 @@ {{ $t('Bar Chart') }} - - - - {{ $t('Expense Chart') }} - {{ $t('Expense By Account') }} - {{ $t('Expense By Secondary Category') }} - - - {{ $t('Income Chart') }} - {{ $t('Income By Account') }} - {{ $t('Income By Secondary Category') }} - - - {{ $t('Cancel') }} - - @@ -55,7 +52,7 @@ export default { data() { return { loading: true, - showMoreActionSheet: false + showChartDataTypePopover: false }; }, computed: { @@ -73,22 +70,44 @@ export default { query() { return this.$store.state.transactionStatisticsFilter; }, - chartData() { + allChartDataTypes() { + return [ + { + type: this.$constants.statistics.allChartDataTypes.ExpenseByAccount, + name: 'Expense By Account' + }, + { + type: this.$constants.statistics.allChartDataTypes.ExpenseByPrimaryCategory, + name: 'Expense By Primary Category' + }, + { + type: this.$constants.statistics.allChartDataTypes.ExpenseBySecondaryCategory, + name: 'Expense By Secondary Category' + }, + { + type: this.$constants.statistics.allChartDataTypes.IncomeByAccount, + name: 'Income By Account' + }, + { + type: this.$constants.statistics.allChartDataTypes.IncomeByPrimaryCategory, + name: 'Income By Primary Category' + }, + { + type: this.$constants.statistics.allChartDataTypes.IncomeBySecondaryCategory, + name: 'Income By Secondary Category' + }, + ]; + }, + statisticsData() { const self = this; - - if (!self.$store.state.transactionStatistics || - !self.$store.state.transactionStatistics.items || - !self.$store.state.transactionStatistics.items.length) { - return self.skeletonChart(); - } - const combinedData = {}; - const allData = []; + + let allAmount = 0; for (let i = 0; i < self.$store.state.transactionStatistics.items.length; i++) { const item = self.$store.state.transactionStatistics.items[i]; - if (!item.account || !item.category) { + if (!item.account || !item.primaryCategory || !item.category) { continue; } @@ -111,59 +130,102 @@ export default { if (self.query.chartDataType === self.$constants.statistics.allChartDataTypes.ExpenseByAccount || self.query.chartDataType === self.$constants.statistics.allChartDataTypes.IncomeByAccount) { if (self.$utilities.isNumber(item.amountInDefaultCurrency)) { - let data = combinedData[item.account.name]; + let data = combinedData[item.account.id]; if (data) { data.totalAmount += item.amountInDefaultCurrency; } else { data = { - totalAmount: item.amountInDefaultCurrency, - color: item.account.color || self.$constants.colors.defaultAccountColor + name: item.account.name, + icon: item.account.icon || self.$constants.icons.defaultAccountIcon.icon, + color: item.account.color || self.$constants.colors.defaultAccountColor, + totalAmount: item.amountInDefaultCurrency } } - combinedData[item.account.name] = data; + allAmount += item.amountInDefaultCurrency; + combinedData[item.account.id] = data; + } + } else if (self.query.chartDataType === self.$constants.statistics.allChartDataTypes.ExpenseByPrimaryCategory || + self.query.chartDataType === self.$constants.statistics.allChartDataTypes.IncomeByPrimaryCategory) { + if (self.$utilities.isNumber(item.amountInDefaultCurrency)) { + let data = combinedData[item.primaryCategory.id]; + + if (data) { + data.totalAmount += item.amountInDefaultCurrency; + } else { + data = { + name: item.primaryCategory.name, + icon: item.account.icon || self.$constants.icons.defaultCategoryIcon.icon, + color: item.primaryCategory.color || self.$constants.colors.defaultCategoryColor, + totalAmount: item.amountInDefaultCurrency + } + } + + allAmount += item.amountInDefaultCurrency; + combinedData[item.primaryCategory.id] = data; } } else if (self.query.chartDataType === self.$constants.statistics.allChartDataTypes.ExpenseBySecondaryCategory || self.query.chartDataType === self.$constants.statistics.allChartDataTypes.IncomeBySecondaryCategory) { if (self.$utilities.isNumber(item.amountInDefaultCurrency)) { - let data = combinedData[item.category.name]; + let data = combinedData[item.category.id]; if (data) { data.totalAmount += item.amountInDefaultCurrency; } else { data = { - totalAmount: item.amountInDefaultCurrency, - color: item.category.color || self.$constants.colors.defaultCategoryColor + name: item.category.name, + icon: item.account.icon || self.$constants.icons.defaultCategoryIcon.icon, + color: item.category.color || self.$constants.colors.defaultCategoryColor, + totalAmount: item.amountInDefaultCurrency } } - combinedData[item.category.name] = data; + allAmount += item.amountInDefaultCurrency; + combinedData[item.category.id] = data; } } } - for (let legendName in combinedData) { - if (!Object.prototype.hasOwnProperty.call(combinedData, legendName)) { + const allStatisticsData = []; + + for (let id in combinedData) { + if (!Object.prototype.hasOwnProperty.call(combinedData, id)) { continue; } - const totalAmount = Math.floor(combinedData[legendName].totalAmount) / 100; + const data = combinedData[id]; + data.percent = data.totalAmount * 100 / allAmount; - const data = { - name: legendName, - value: totalAmount, - itemStyle: { - color: `#${combinedData[legendName].color}` - } - }; - - allData.push(data); + allStatisticsData.push(data); } - if (self.query.chartType === self.$constants.statistics.allChartTypes.Bar) { - allData.sort(function (data1, data2) { - return data1.value - data2.value; + allStatisticsData.sort(function (data1, data2) { + return data1.totalAmount - data2.totalAmount; + }); + + return allStatisticsData; + }, + chartData() { + const self = this; + + if (!self.$store.state.transactionStatistics || + !self.$store.state.transactionStatistics.items || + !self.$store.state.transactionStatistics.items.length) { + return self.skeletonChart(); + } + + const allData = []; + + for (let i = 0; i < this.statisticsData.length; i++) { + const data = this.statisticsData[i]; + + allData.push({ + name: data.name, + value: data.totalAmount / 100, + itemStyle: { + color: `#${data.color}` + } }); } @@ -296,6 +358,7 @@ export default { this.$store.dispatch('updateTransactionStatisticsFilter', { chartDataType: chartDataType }); + this.showChartDataTypePopover = false; }, skeletonChart() { const skeletonChartData = { @@ -357,6 +420,15 @@ export default { } }, filters: { + chartDataTypeName(dataType, allChartDataTypes) { + for (let i = 0; i < allChartDataTypes.length; i++) { + if (allChartDataTypes[i].type === dataType) { + return allChartDataTypes[i].name; + } + } + + return 'Statistics'; + }, dateRange() { return 'Date'; }