Files
consumocuidado/components/TrendStats.vue
2025-08-22 16:09:27 +02:00

182 lines
3.4 KiB
Vue

<template>
<div v-if="values" :style="cssProps" class="trendChart">
<div class="data">
<div class="data-info">
<header>
<strong class="title">{{ name }}</strong>
</header>
<div v-if="info" class="period">
<span class="period-text">{{ info?.month }}</span>
<strong class="value">{{ info?.value }}</strong>
</div>
</div>
<div class="chart">
<ClientOnly>
<LineChart :chart-id="chartId" :line-chart-data="dataset" />
</ClientOnly>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
name: {
type: String,
default: '',
},
chartId: {
type: String,
default: '',
},
values: {
type: Array,
default: () => [],
},
color: {
type: String,
default: 'inherit',
required: false,
},
},
data() {
return {
currentInfo: null,
months: [
'Enero',
'Febrero',
'Marzo',
'Abril',
'Mayo',
'Junio',
'Julio',
'Agosto',
'Septiembre',
'Octubre',
'Noviembre',
'Diciembre',
],
abrevMonths: [
'Ene',
'Feb',
'Mar',
'Abr',
'May',
'Jun',
'Jul',
'Ago',
'Sep',
'Oct',
'Nov',
'Dic',
]
}
},
computed: {
dataset() {
return {
xAxis: {
type: 'category',
data: this.abrevMonths
},
yAxis: {
type: 'value'
},
series: [
{
data: this.yAxisValues,
type: 'line',
smooth: true,
color: this.color
}
]
}
},
cssProps() {
return {
'--color': this.color,
}
},
info() {
const actualMonth = new Date().getMonth();
const currentMonthInfo = this.values.sort((a, b) => a.month - b.month)[actualMonth];
const res = {
month: currentMonthInfo?.month ? this.months[actualMonth] : 'Este mes',
value: currentMonthInfo?.value ? currentMonthInfo?.value : 0,
};
return res;
},
yAxisValues(){
const ArrValues = [...this.values]
const res = [];
ArrValues.sort((a, b) => a.month - b.month)
ArrValues.forEach(item => {
res.push(item.value)
})
return res
},
},
methods: {
// onMouseMove(params) {
// if (params) {
// this.currentInfo = {
// month: this.months[params.data[0].month - 1],
// value: params.data[0].value,
// }
// } else {
// this.currentInfo = null
// }
// },
},
}
</script>
<style lang="scss">
.trendChart {
border-bottom: 2px solid rgba(var(--color), 0.2);
.title {
color: var(--color);
}
.data {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
.period {
display: flex;
flex-direction: column-reverse;
}
.value {
font-size: 30px;
}
.chart {
width: 40%;
}
}
.stroke {
stroke-width: 2;
stroke: var(--color);
}
.fill {
opacity: 0.2;
fill: var(--color);
}
.active-line {
stroke: rgba(0, 0, 0, 0.2);
}
.point {
display: none;
fill: var(--color);
stroke: var(--color);
}
.point.is-active {
display: block;
}
}
</style>