no data placeholder

This commit is contained in:
nquidox 2025-10-01 11:02:31 +03:00
parent c4383ac408
commit 60e1abc941

View file

@ -27,8 +27,9 @@ ChartJS.register(
const props = defineProps({ const props = defineProps({
chartsData: { chartsData: {
type: Object, type: [Object, null],
required: true, required: true,
default: null,
}, },
}) })
@ -41,6 +42,49 @@ const chartData = ref({
datasets: [], datasets: [],
}) })
const showPlaceholder = ref(false)
const placeholderMessage = ref('')
function transformToChartJSSeries(payload) {
const datasets = []
for (const origin of payload.origins) {
if (!origin.Prices || origin.Prices.length === 0) continue
const data = origin.Prices.filter((p) => p.value != null)
.map((p) => {
let y = p.value
if (typeof y === 'string') {
y = parseFloat(y)
}
const x =
typeof p.created_at === 'number' ? p.created_at * 1000 : new Date(p.created_at).getTime()
return {
x,
y: typeof y === 'number' && !isNaN(y) ? y : null,
}
})
.filter((p) => p.y !== null)
.sort((a, b) => a.x - b.x)
if (data.length === 0) continue
const color = originColors[origin.origin] || '#000000'
datasets.push({
label: origin.origin,
data,
borderColor: color,
backgroundColor: color + '20',
fill: false,
pointRadius: 4,
pointHoverRadius: 6,
type: 'line',
})
}
return datasets
}
const chartOptions = { const chartOptions = {
responsive: true, responsive: true,
maintainAspectRatio: false, maintainAspectRatio: false,
@ -90,64 +134,72 @@ const chartOptions = {
}, },
} }
function transformToChartJSSeries(payload) {
const datasets = []
for (const origin of payload.origins) {
if (!origin.Prices || origin.Prices.length === 0) continue
const data = origin.Prices.filter((p) => p.value != null)
.map((p) => {
let y = p.value
if (typeof y === 'string') {
y = parseFloat(y)
}
const x =
typeof p.created_at === 'number' ? p.created_at * 1000 : new Date(p.created_at).getTime()
return {
x,
y: typeof y === 'number' && !isNaN(y) ? y : null,
}
})
.filter((p) => p.y !== null)
.sort((a, b) => a.x - b.x)
if (data.length === 0) continue
const color = originColors[origin.origin] || '#000000'
datasets.push({
label: origin.origin,
data,
borderColor: color,
backgroundColor: color + '20', // прозрачность
fill: false,
pointRadius: 4,
pointHoverRadius: 6,
type: 'line',
})
}
return datasets
}
watch( watch(
() => props.chartsData, () => props.chartsData,
(newData) => { (newData) => {
if (newData?.origins) { // Сброс состояния
const datasets = transformToChartJSSeries(newData) showPlaceholder.value = false
placeholderMessage.value = ''
// Случай 1: null или undefined
if (newData === null || newData === undefined) {
showPlaceholder.value = true
placeholderMessage.value = 'No prices found'
chartData.value = { datasets: [] }
return
}
// Случай 2: явная ошибка в объекте
if (typeof newData === 'object' && newData.error) {
showPlaceholder.value = true
placeholderMessage.value = newData.error
chartData.value = { datasets: [] }
return
}
// Случай 3: нормальный объект пробуем преобразовать
let datasets = []
if (newData.origins && Array.isArray(newData.origins)) {
datasets = transformToChartJSSeries(newData)
}
// 🔥 Ключевое изменение: проверяем, есть ли хоть один датасет
if (datasets.length === 0) {
showPlaceholder.value = true
placeholderMessage.value = 'No prices found'
chartData.value = { datasets: [] }
} else {
showPlaceholder.value = false
chartData.value = { datasets } chartData.value = { datasets }
} }
}, },
{ immediate: true }, { immediate: true }
) )
</script> </script>
<template> <template>
<Line :data="chartData" :options="chartOptions" style="height: 100%; width: 100%" /> <div class="chart-container" style="height: 100%; width: 100%">
<div v-if="showPlaceholder" class="error-placeholder">
{{ placeholderMessage }}
</div>
<Line v-else :data="chartData" :options="chartOptions" style="height: 100%; width: 100%" />
</div>
</template> </template>
<style scoped> <style scoped>
.charts-card { .chart-container {
position: relative;
min-width: 80%; min-width: 80%;
} }
.error-placeholder {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
width: 100%;
color: #666;
font-size: 1.2rem;
text-align: center;
}
</style> </style>