Files
scrap/webui/src/components/PriceHistoryChart.vue
Gilles Soulier cf7c415e22 before claude
2026-01-17 13:40:26 +01:00

91 lines
2.4 KiB
Vue

<template>
<div class="price-history-chart panel p-3">
<div class="flex items-center justify-between mb-2">
<div class="section-title text-sm">Historique</div>
<div class="label text-xs">{{ deltaLabel }}</div>
</div>
<svg class="w-full h-20 mb-2" viewBox="0 0 120 50" preserveAspectRatio="none">
<polyline :points="polyPoints" class="sparkline" fill="none" />
<circle
v-for="(point, index) in svgPoints"
:key="`history-detail-point-${index}`"
:cx="point.cx"
:cy="point.cy"
r="1.3"
stroke="currentColor"
fill="currentColor"
/>
</svg>
<div class="grid grid-cols-2 gap-3 text-xs">
<div>Actuel<br /><strong>{{ formatPrice(currentPrice) }}</strong></div>
<div>Min<br /><strong>{{ formatPrice(minPrice) }}</strong></div>
<div>Max<br /><strong>{{ formatPrice(maxPrice) }}</strong></div>
<div>Delta<br /><strong>{{ deltaLabel }}</strong></div>
</div>
</div>
</template>
<script setup lang="ts">
import { computed } from "vue";
const props = defineProps({
history: {
type: Array as () => number[],
default: () => [],
},
currentPrice: {
type: Number,
default: 0,
},
minPrice: {
type: Number,
default: 0,
},
maxPrice: {
type: Number,
default: 0,
},
deltaLabel: {
type: String,
default: "—",
},
});
const polyPoints = computed(() => {
if (!props.history.length) {
return "0,40 30,30 60,35 90,25 120,28";
}
const max = Math.max(...props.history);
const min = Math.min(...props.history);
const range = max - min || 1;
return props.history
.map((value, index) => {
const x = (index / (props.history.length - 1 || 1)) * 120;
const y = 50 - ((value - min) / range) * 50;
return `${x.toFixed(1)},${y.toFixed(1)}`;
})
.join(" ");
});
const svgPoints = computed(() => {
if (!props.history.length) {
return [];
}
const max = Math.max(...props.history);
const min = Math.min(...props.history);
const range = max - min || 1;
return props.history.map((value, index) => {
const x = (index / (props.history.length - 1 || 1)) * 120;
const y = 50 - ((value - min) / range) * 50;
return { cx: x.toFixed(1), cy: y.toFixed(1) };
});
});
const formatPrice = (value: number) => {
if (!Number.isFinite(value)) {
return "n/a";
}
return `${value.toFixed(2)}`;
};
</script>