budget-go/frontend/js/components/dashboard/Distribution.vue

128 lines
3.2 KiB
Vue

<template>
<div class="stats">
<h5 class="mb-2 text-center">Répartion des dépenses</h5>
<div class="row mt-3 mb-5">
<div
v-for="(item, key) in categories"
:key="key"
class="col-auto checkbox"
:class="{'checkbox--unchecked': !selectedCategories[item.label]}"
>
<BFormCheckbox v-model="selectedCategories[item.label]">
<span
class="cursor"
v-html="renderCategory(item)"
></span>
</BFormCheckbox>
</div>
<div class="col-auto">
<span
class="cursor fw-bold"
@click="selectAllCategories()"
>Toutes</span
>
-
<span
class="cursor fw-bold"
@click="unSelectAllCategories()"
>Aucune</span
>
-
<span
class="cursor fw-bold"
@click="inverseCategories()"
>Inverser</span
>
</div>
</div>
<div class="row">
<div class="col-12 col-lg-4">
<Doughnut
:data="computeDoughnut(data, dateFrom, dateTo, selectedCategories)"
:options="fixedOptions({plugins: {legend: {display: false}}})"
:style="chartStyle(380)"
/>
</div>
<div class="col-12 col-lg-8">
<div class="d-flex justify-content-between">
<BFormCheckbox v-model="isStacked"> En pourcentage </BFormCheckbox>
</div>
<div>
<Bar
:data="
computeBar(data, isStacked, dateFrom, dateTo, selectedCategories)
"
:options="stackOptions({plugins: {legend: {display: false}}})"
:style="chartStyle(380)"
/>
</div>
</div>
</div>
</div>
</template>
<script setup>
import {ref, toRefs, watch, defineProps, onMounted} from 'vue'
import {getStorage, saveStorage} from '../../lib/storage'
import {computeDoughnut, computeBar} from '../../chart/distribution'
import {renderCategory} from '../../lib/renderers'
import {Doughnut, Bar} from 'vue-chartjs'
import {BFormCheckbox} from 'bootstrap-vue-next'
import {chartStyle} from '../../lib/chartStyle'
const props = defineProps(['data', 'categories', 'dateFrom', 'dateTo'])
const isStacked = ref(getStorage('dashboard:distribution:isStacked'))
const selectedCategories = ref({})
const {categories} = toRefs(props)
watch(isStacked, (v) => saveStorage('dashboard:distribution:isStacked', v))
const fixedOptions = (opts) => {
let value = opts || {}
return {
...value,
responsive: false,
maintainAspectRatio: true,
}
}
const stackOptions = (opts) => {
let options = {...fixedOptions(opts)}
options.scales = {
y: {stacked: true, ticks: {beginAtZero: true}},
x: {stacked: true},
}
return options
}
const inverseCategories = () => {
for (let i in selectedCategories.value) {
selectedCategories.value[i] = !selectedCategories.value[i]
}
}
const selectAllCategories = () => {
for (let i in selectedCategories.value) {
selectedCategories.value[i] = true
}
}
const unSelectAllCategories = () => {
for (let i in selectedCategories.value) {
selectedCategories.value[i] = false
}
}
onMounted(() => {
for (let item of categories.value) {
selectedCategories.value[item.label] = true
}
})
</script>