91 lines
2.4 KiB
Vue
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>
|