fixessome

This commit is contained in:
Vladimir Voronin
2024-11-08 09:59:46 +03:00
parent b7cccecaec
commit c33af74342
21 changed files with 453 additions and 343 deletions

View File

@@ -0,0 +1,225 @@
<script setup lang="ts">
import LoadingView from "@/components/LoadingView.vue";
import {computed, onMounted, ref} from "vue";
import {getTransactionCategoriesSums} from "@/services/transactionService";
import Chart from "primevue/chart";
import MultiSelect from "primevue/multiselect";
import {format} from "date-fns";
import {generateRandomColors} from "@/utils/utils";
import {Category} from "@/models/Category";
import {getCategories} from "@/services/categoryService";
import {Chart as ChartJS} from "chart.js/auto";
import ChartDataLabels from "chartjs-plugin-datalabels";
ChartJS.register(ChartDataLabels);
const loading = ref(false);
const categoriesSums = ref([])
const fetchCategoriesSums = async () => {
loading.value = true
try {
categoriesSums.value = await getTransactionCategoriesSums()
// console.log(categoriesSums.value)
} catch (error) {
console.error('Error fetching categories sums:', error);
}
loading.value = false
}
const categories = ref<Category[]>([])
const selectedCategories = ref([])
const fetchCategories = async () => {
loading.value = true
try {
const response = await getCategories('EXPENSE');
categories.value = response.data
console.log(categories.value.filter(i => i.id==30))
selectedCategories.value.push(categories.value.filter(i => i.id==30)[0])
} catch (error) {
console.error('Error fetching categories:', error);
}
loading.value = false
}
const chartData = computed(() => {
return {
labels: chartLabels.value[0],
datasets: chartLabels.value[1]
};
})
const chartOptions = computed(() => {
return {
maintainAspectRatio: false,
aspectRatio: 0.6,
plugins: {
legend: {
labels: {
color: 'rgba(0, 0, 0, 1)',
font: {
weight: 'bold',
}
}
}
},
scales: {
x: {
ticks: {
color: 'rgba(0, 0, 0, 0.5)',
},
grid: {
color: 'rgba(255, 0, 0, 0.5)',
}
},
y: {
ticks: {
color: 'rgba(0, 0, 0, 0.5)',
},
grid: {
color: 'rgba(0, 0, 0, 0.5)',
}
}
}
};
})
const chartLabels = computed(() => {
let dates = new Array<Date>()
categoriesSums.value.filter(i => i[0].id == 30).forEach((item) => {
dates.push(format(new Date(item[1]), 'MM.yy'))
})
let datasets = []
categoriesSums.value.forEach((item) => {
// Проверка, есть ли категория в массиве выбранных категорий `selectedCategories`
const isSelected = selectedCategories.value.some((category) => category.id == item[0].id);
if (!isSelected) {
return; // Пропускаем категории, которых нет в `selectedCategories`
}
// Проверка, есть ли уже категория с таким названием в `datasets`
const existingDataset = datasets.find((v) => v.label === item[0].name);
let color = generateRandomColors();
if (!existingDataset) {
// Создаем новый объект `dataset` для новой категории
let dataset = {
label: item[0].name,
data: categoriesSums.value
.filter((i) => i[0].id === item[0].id)
.map((value) => value[2]), // Собираем массив значений для категории
fill: true,
borderColor: `rgba(${color[0]}, ${color[1]}, ${color[2]}, 1)`,
backgroundColor: `rgba(${color[0]}, ${color[1]}, ${color[2]}, 0.2)`,
tension: 0.4,
};
// Добавляем созданный объект `dataset` в массив `datasets`
datasets.push(dataset);
}
});
return [dates, datasets];
})
// const categories = computed(() => {
// let categoriesIds = new Array<number>()
// categoriesSums.value.forEach((i) => {
// categoriesIds.push(i[0].id)
// })
// return categoriesIds
// })
const setChartData = () => {
console.log(chartLabels.value[1])
return {
labels: chartLabels.value[0],
datasets: chartLabels.value[1]
};
}
const setChartOptions = () => {
// const documentStyle = getComputedStyle(document.documentElement);
// const textColor = documentStyle.getPropertyValue('--p-text-color');
// const textColorSecondary = documentStyle.getPropertyValue('--p-text-muted-color');
// const surfaceBorder = documentStyle.getPropertyValue('--p-content-border-color');
return {
maintainAspectRatio: false,
aspectRatio: 0.6,
plugins: {
legend: {
labels: {
color: 'rgba(0, 0, 0, 1)',
font: {
weight: 'bold'
}
}
},
datalabels: {
color: 'rgba(0, 0, 0, 1)', // Цвет текста
anchor: 'end', // Привязка метки
align: 'top', // Выравнивание над точкой
offset: 8, // Отступ от точки
labels: {
font: {
weight: 'bold'
}
}
}
},
scales: {
x: {
ticks: {
color: 'rgba(0, 0, 0, 0.5)',
},
grid: {
color: 'rgba(255, 0, 0, 0.5)',
}
},
y: {
ticks: {
color: 'rgba(0, 0, 0, 0.5)',
},
grid: {
color: 'rgba(0, 0, 0, 0.5)',
}
}
}
};
}
onMounted(async () => {
loading.value = true;
await Promise.all([fetchCategoriesSums(), fetchCategories()])
loading.value = false
})
</script>
<template>
<LoadingView v-if="loading"/>
<div v-else class="px-4 bg-gray-100 h-full flex flex-col gap-4 ">
<MultiSelect v-model="selectedCategories" :options="categories" optionLabel="name" filter
placeholder="Выберите категории"
:maxSelectedLabels="3" class="w-full md:w-80"/>
<Chart v-if="selectedCategories.length > 0" type="line" :data="chartData" :options="chartOptions" class="h-[30rem]"/>
<!-- {{categories}}-->
<!-- {{// chartData}}-->
</div>
</template>
<style scoped>
</style>