128 lines
3.2 KiB
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>
|