no data placeholder
This commit is contained in:
parent
c4383ac408
commit
60e1abc941
1 changed files with 98 additions and 46 deletions
|
|
@ -27,8 +27,9 @@ ChartJS.register(
|
|||
|
||||
const props = defineProps({
|
||||
chartsData: {
|
||||
type: Object,
|
||||
type: [Object, null],
|
||||
required: true,
|
||||
default: null,
|
||||
},
|
||||
})
|
||||
|
||||
|
|
@ -41,6 +42,49 @@ const chartData = ref({
|
|||
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 = {
|
||||
responsive: true,
|
||||
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(
|
||||
() => props.chartsData,
|
||||
(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 }
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
{ immediate: true }
|
||||
)
|
||||
</script>
|
||||
|
||||
<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>
|
||||
|
||||
<style scoped>
|
||||
.charts-card {
|
||||
.chart-container {
|
||||
position: relative;
|
||||
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>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue