feat(chart): add chart implementation

This commit is contained in:
2021-12-23 00:29:13 +01:00
parent 566e75f99a
commit 2556908042
13 changed files with 261 additions and 17 deletions

134
package-lock.json generated
View File

@@ -12,11 +12,14 @@
"axios": "^0.21.1",
"bootstrap": "^4.5.3",
"bootstrap-vue": "^2.21.2",
"chart.js": "^2.9.4",
"core-js": "^3.6.5",
"npm": "^8.1.0",
"portal-vue": "^2.1.7",
"vue": "^2.6.14",
"vue-axios": "^3.2.4",
"vue-chartjs": "^3.5.1",
"vue-moment": "^4.1.0",
"vue-router": "^3.5.1",
"vuex": "^3.6.2"
},
@@ -1828,6 +1831,14 @@
"@types/node": "*"
}
},
"node_modules/@types/chart.js": {
"version": "2.9.34",
"resolved": "https://registry.npmjs.org/@types/chart.js/-/chart.js-2.9.34.tgz",
"integrity": "sha512-CtZVk+kh1IN67dv+fB0CWmCLCRrDJgqOj15qPic2B1VCMovNO6B7Vhf/TgPpNscjhAL1j+qUntDMWb9A4ZmPTg==",
"dependencies": {
"moment": "^2.10.2"
}
},
"node_modules/@types/connect": {
"version": "3.4.35",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
@@ -3903,6 +3914,32 @@
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
"dev": true
},
"node_modules/chart.js": {
"version": "2.9.4",
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.4.tgz",
"integrity": "sha512-B07aAzxcrikjAPyV+01j7BmOpxtQETxTSlQ26BEYJ+3iUkbNKaOJ/nDbT6JjyqYxseM0ON12COHYdU2cTIjC7A==",
"dependencies": {
"chartjs-color": "^2.1.0",
"moment": "^2.10.2"
}
},
"node_modules/chartjs-color": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz",
"integrity": "sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==",
"dependencies": {
"chartjs-color-string": "^0.6.0",
"color-convert": "^1.9.3"
}
},
"node_modules/chartjs-color-string": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz",
"integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==",
"dependencies": {
"color-name": "^1.0.0"
}
},
"node_modules/check-types": {
"version": "8.0.3",
"resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz",
@@ -4386,7 +4423,6 @@
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"dependencies": {
"color-name": "1.1.3"
}
@@ -4394,8 +4430,7 @@
"node_modules/color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"node_modules/color-string": {
"version": "1.6.0",
@@ -9370,6 +9405,14 @@
"mkdirp": "bin/cmd.js"
}
},
"node_modules/moment": {
"version": "2.29.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==",
"engines": {
"node": "*"
}
},
"node_modules/move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
@@ -16348,6 +16391,21 @@
"vue": "^3.0.0 || ^2.0.0"
}
},
"node_modules/vue-chartjs": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/vue-chartjs/-/vue-chartjs-3.5.1.tgz",
"integrity": "sha512-foocQbJ7FtveICxb4EV5QuVpo6d8CmZFmAopBppDIGKY+esJV8IJgwmEW0RexQhxqXaL/E1xNURsgFFYyKzS/g==",
"dependencies": {
"@types/chart.js": "^2.7.55"
},
"engines": {
"node": ">=6.9.0",
"npm": ">= 3.0.0"
},
"peerDependencies": {
"chart.js": ">= 2.5"
}
},
"node_modules/vue-eslint-parser": {
"version": "7.11.0",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.11.0.tgz",
@@ -16521,6 +16579,17 @@
"integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=",
"dev": true
},
"node_modules/vue-moment": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/vue-moment/-/vue-moment-4.1.0.tgz",
"integrity": "sha512-Gzisqpg82ItlrUyiD9d0Kfru+JorW2o4mQOH06lEDZNgxci0tv/fua1Hl0bo4DozDV2JK1r52Atn/8QVCu8qQw==",
"dependencies": {
"moment": "^2.19.2"
},
"peerDependencies": {
"vue": ">=1.x.x"
}
},
"node_modules/vue-router": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.2.tgz",
@@ -19027,6 +19096,14 @@
"@types/node": "*"
}
},
"@types/chart.js": {
"version": "2.9.34",
"resolved": "https://registry.npmjs.org/@types/chart.js/-/chart.js-2.9.34.tgz",
"integrity": "sha512-CtZVk+kh1IN67dv+fB0CWmCLCRrDJgqOj15qPic2B1VCMovNO6B7Vhf/TgPpNscjhAL1j+qUntDMWb9A4ZmPTg==",
"requires": {
"moment": "^2.10.2"
}
},
"@types/connect": {
"version": "3.4.35",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
@@ -20766,6 +20843,32 @@
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
"dev": true
},
"chart.js": {
"version": "2.9.4",
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.4.tgz",
"integrity": "sha512-B07aAzxcrikjAPyV+01j7BmOpxtQETxTSlQ26BEYJ+3iUkbNKaOJ/nDbT6JjyqYxseM0ON12COHYdU2cTIjC7A==",
"requires": {
"chartjs-color": "^2.1.0",
"moment": "^2.10.2"
}
},
"chartjs-color": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz",
"integrity": "sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==",
"requires": {
"chartjs-color-string": "^0.6.0",
"color-convert": "^1.9.3"
}
},
"chartjs-color-string": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz",
"integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==",
"requires": {
"color-name": "^1.0.0"
}
},
"check-types": {
"version": "8.0.3",
"resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz",
@@ -21146,7 +21249,6 @@
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"requires": {
"color-name": "1.1.3"
}
@@ -21154,8 +21256,7 @@
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"color-string": {
"version": "1.6.0",
@@ -25082,6 +25183,11 @@
"minimist": "^1.2.5"
}
},
"moment": {
"version": "2.29.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
},
"move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
@@ -30541,6 +30647,14 @@
"integrity": "sha512-SmNFJIkM5YF4eWfaWfmCmORy52ZP5b8ml9PCTi7C0VsuQK4vwZON6ToNWuyFGCL6U/Fp/pzfIgdLLh/O/qKzYQ==",
"requires": {}
},
"vue-chartjs": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/vue-chartjs/-/vue-chartjs-3.5.1.tgz",
"integrity": "sha512-foocQbJ7FtveICxb4EV5QuVpo6d8CmZFmAopBppDIGKY+esJV8IJgwmEW0RexQhxqXaL/E1xNURsgFFYyKzS/g==",
"requires": {
"@types/chart.js": "^2.7.55"
}
},
"vue-eslint-parser": {
"version": "7.11.0",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.11.0.tgz",
@@ -30669,6 +30783,14 @@
}
}
},
"vue-moment": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/vue-moment/-/vue-moment-4.1.0.tgz",
"integrity": "sha512-Gzisqpg82ItlrUyiD9d0Kfru+JorW2o4mQOH06lEDZNgxci0tv/fua1Hl0bo4DozDV2JK1r52Atn/8QVCu8qQw==",
"requires": {
"moment": "^2.19.2"
}
},
"vue-router": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.2.tgz",

View File

@@ -16,11 +16,14 @@
"axios": "^0.21.1",
"bootstrap": "^4.5.3",
"bootstrap-vue": "^2.21.2",
"chart.js": "^2.9.4",
"core-js": "^3.6.5",
"npm": "^8.1.0",
"portal-vue": "^2.1.7",
"vue": "^2.6.14",
"vue-axios": "^3.2.4",
"vue-chartjs": "^3.5.1",
"vue-moment": "^4.1.0",
"vue-router": "^3.5.1",
"vuex": "^3.6.2"
},

View File

@@ -2,7 +2,14 @@
<div class="account-tab">
<b-card no-body>
<b-tabs card>
<b-tab :title=account.name >
<b-tab title="Vue Global">
<scatter-chart
v-if="loaded"
:chartdata="chartData"
/>
</b-tab>
<b-tab title="Vue detaillé" >
<div>
<div class="expense-button-div float-left">
<b-button variant="success">Ajouter une dépense</b-button>
@@ -22,7 +29,7 @@
<!-- Styled -->
<b-form-file
v-model="file"
:state="Boolean(file1)"
:state="Boolean(file)"
placeholder="Choose a file or drop it here..."
drop-placeholder="Drop file here..."
></b-form-file>
@@ -42,8 +49,10 @@
</template>
<script>
import {BCard, BTabs , BTab, BTable, BFormFile} from "bootstrap-vue";
import {getAnAccount, getExpenses, sendCSVImportExpenses} from "@/config/noscomptes";
import {BCard, BTabs , BTab, BTable, BFormFile, BModal, BButton} from "bootstrap-vue";
import {getAnAccount, getExpenses, sendCSVImportExpenses} from "@/service/noscomptes";
import {formatExpenses} from "@/service/expenses";
import ScatterChart from './charts/BarChart.vue';
export default {
name: 'account',
data: function () {
@@ -72,7 +81,9 @@ export default {
expenseDate: "Today",
libelle:"Test",
value: 10
}]
}],
chartData:{} ,
loaded: false,
}
},
beforeCreate() {
@@ -82,7 +93,10 @@ export default {
})
getExpenses(loggedUser.oauth_token, loggedUser.nosComptesId, this.$route.params.accountId).then(data => {
this.expenses = data
this.chartData = formatExpenses(data)
this.loaded= true
})
},
mounted () {
},
@@ -99,16 +113,30 @@ export default {
validateFormImportExpenses() {
let loggedUser = this.$store.state.loggedUser
sendCSVImportExpenses(loggedUser.oauth_token, loggedUser.nosComptesId, this.$route.params.accountId, this.file)
.then(()=>{
this.loaded = false
getExpenses(loggedUser.oauth_token, loggedUser.nosComptesId, this.$route.params.accountId).then(data => {
this.expenses = data
this.chartData = formatExpenses(data)
this.loaded = true
})
this.$refs['import-expense'].hide()
})
}
},
components: {
ScatterChart,
BCard,
BTabs,
BTab,
BTable,
BFormFile
BFormFile,
BModal,
BButton
}
}
</script>

View File

@@ -86,7 +86,7 @@
<script>
import {BCard, BTabs, BButton, BTab, BCardText, BCardTitle, BIconPlusCircleFill, BModal, BFormGroup, BFormSelect, BFormInput} from "bootstrap-vue";
import {createAccount, getAccounts, deleteAnAccount} from "@/config/noscomptes";
import {createAccount, getAccounts, deleteAnAccount} from "@/service/noscomptes";
export default {
name: 'mes_comptes',
data: function () {

View File

@@ -9,7 +9,7 @@
<script>
import router from '@/router/router'
import {logWithGoogle, getAccounts, getSharedAccounts} from '@/config/noscomptes'
import {logWithGoogle, getAccounts, getSharedAccounts} from '@/service/noscomptes'
export default {
name: 'login_signup_social',
mounted () {

View File

@@ -0,0 +1,39 @@
<script>
import {Bar} from 'vue-chartjs'
export default {
name: 'ScatterChart',
extends: Bar,
props: {
chartdata: {
type: Object,
default: null
},
options: {
type: Object,
default: () =>{return {
scales: {
xAxes: [{
type: "time",
time: {
unit: 'day',
round: 'day',
displayFormats: {
day: 'MMM D'
}
}
}],
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}}
}
},
mounted() {
this.renderChart(this.chartdata, this.options)
}
}
</script>

View File

@@ -0,0 +1,21 @@
<script>
import {Line} from 'vue-chartjs'
export default {
name: 'LineChart',
extends: Line,
props: {
chartdata: {
type: Object,
default: null
},
options: {
type: Object,
default: () =>{return {responsive: true}}
}
},
mounted() {
this.renderChart(this.chartdata, this.options)
}
}
</script>

View File

@@ -7,7 +7,7 @@ import VueAxios from 'vue-axios'
import '@/assets/css/style.css'
import GoogleAuth from '@/config/google_oAuth.js'
import GoogleAuth from '@/service/google_oAuth.js'
import { BootstrapVue, IconsPlugin , BootstrapVueIcons, ModalPlugin, FormPlugin, FormFilePlugin} from 'bootstrap-vue'
// Import Bootstrap an BootstrapVue CSS files (order is important)
@@ -38,3 +38,8 @@ Vue.use(BootstrapVueIcons)
Vue.use(ModalPlugin)
Vue.use(FormPlugin)
Vue.use(FormFilePlugin)
Vue.use(require('vue-moment'));
import VueMoment from 'vue-moment'
Vue.use(VueMoment)

26
src/service/expenses.js Normal file
View File

@@ -0,0 +1,26 @@
export const formatExpenses = (expenses) => {
const formattedExpenses = []
const reduceExpenses = []
for (const expense of expenses) {
if (reduceExpenses[expense.expenseDate] === undefined) {
reduceExpenses[expense.expenseDate] = expense.value
} else {
reduceExpenses[expense.expenseDate] += expense.value
}
}
for (const date in reduceExpenses) {
formattedExpenses[formattedExpenses.length] = { x: date, y: reduceExpenses[date] }
}
console.log(reduceExpenses)
console.log(formattedExpenses)
return {
datasets: [{
label: 'My First Dataset',
data: formattedExpenses,
fill: false,
borderColor: 'rgb(75, 192, 192)',
tension: 0.1
}]
}
}

View File

@@ -1,7 +1,7 @@
import Vue from 'vue'
import Vuex from 'vuex'
import { setStore, getStore } from '@/config/utils'
import {removeItem} from "../config/utils";
import { setStore, getStore } from '@/service/utils'
import {removeItem} from "../service/utils";
Vue.use(Vuex)