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

144 lines
3.5 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]">
<!-- eslint-disable vue/no-v-html -->
<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, 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: {
type: Array,
required: true,
},
categories: {
type: Array,
required: true,
},
dateFrom: {
type: [String, null],
required: true,
},
dateTo: {
type: [String, null],
required: true,
},
})
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>