|
|
@@ -65,9 +65,7 @@
|
|
|
});
|
|
|
|
|
|
const prices = data.map((item) => item.price);
|
|
|
-
|
|
|
- // Dynamic point visibility based on data density
|
|
|
- const shouldShowPoints = data.length <= 30; // Hide points if more than 30 data points
|
|
|
+ const shouldShowPoints = data.length <= 30;
|
|
|
const pointRadius = shouldShowPoints ? 5 : 0;
|
|
|
const pointHoverRadius = shouldShowPoints ? 7 : 5;
|
|
|
|
|
|
@@ -89,14 +87,14 @@
|
|
|
data: prices,
|
|
|
fill: true,
|
|
|
backgroundColor: gradientFill,
|
|
|
- borderColor: 'rgb(59, 130, 246)',
|
|
|
- borderWidth: 3,
|
|
|
- pointBackgroundColor: 'rgb(59, 130, 246)',
|
|
|
- pointBorderColor: 'white',
|
|
|
- pointBorderWidth: 2,
|
|
|
- pointRadius: pointRadius,
|
|
|
- pointHoverRadius: pointHoverRadius,
|
|
|
- tension: 0.4
|
|
|
+ borderColor: 'rgb(59, 130, 246)',
|
|
|
+ borderWidth: 3,
|
|
|
+ pointBackgroundColor: 'rgb(59, 130, 246)',
|
|
|
+ pointBorderColor: 'white',
|
|
|
+ pointBorderWidth: 2,
|
|
|
+ pointRadius: pointRadius,
|
|
|
+ pointHoverRadius: pointHoverRadius,
|
|
|
+ tension: 0.4
|
|
|
}
|
|
|
]
|
|
|
},
|
|
|
@@ -107,10 +105,9 @@
|
|
|
intersect: false,
|
|
|
mode: 'index'
|
|
|
},
|
|
|
- // Add decimation for performance with large datasets
|
|
|
datasets: {
|
|
|
line: {
|
|
|
- pointRadius: pointRadius, // Apply to all line datasets
|
|
|
+ pointRadius: pointRadius,
|
|
|
pointHoverRadius: pointHoverRadius
|
|
|
}
|
|
|
},
|
|
|
@@ -119,9 +116,8 @@
|
|
|
tension: 0.4
|
|
|
}
|
|
|
},
|
|
|
- // Performance optimization for large datasets
|
|
|
animation: {
|
|
|
- duration: data.length > 100 ? 0 : 750 // Disable animation for large datasets
|
|
|
+ duration: data.length > 100 ? 0 : 750
|
|
|
},
|
|
|
scales: {
|
|
|
x: {
|
|
|
@@ -139,9 +135,7 @@
|
|
|
},
|
|
|
ticks: {
|
|
|
color: 'rgb(107, 114, 128)',
|
|
|
- // Smart label skipping based on data length
|
|
|
maxTicksLimit: data.length > 50 ? 8 : data.length > 20 ? 12 : undefined,
|
|
|
- // Auto-skip for better readability
|
|
|
autoSkip: true,
|
|
|
maxRotation: 45,
|
|
|
minRotation: 0
|
|
|
@@ -162,7 +156,7 @@
|
|
|
},
|
|
|
ticks: {
|
|
|
color: 'rgb(107, 114, 128)',
|
|
|
- callback: function (value) {
|
|
|
+ callback: function(value) {
|
|
|
return value.toFixed(2);
|
|
|
}
|
|
|
}
|
|
|
@@ -201,11 +195,10 @@
|
|
|
datalabels: {
|
|
|
display: false
|
|
|
},
|
|
|
- // Add decimation for large datasets
|
|
|
decimation: {
|
|
|
enabled: data.length > 100,
|
|
|
- algorithm: 'lttb', // Largest Triangle Three Buckets algorithm
|
|
|
- samples: 100 // Reduce to max 100 samples for performance
|
|
|
+ algorithm: 'lttb',
|
|
|
+ samples: 100
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -281,13 +274,13 @@
|
|
|
{#if lastUpdated}
|
|
|
<p class="text-xs text-gray-500 dark:text-gray-600 mb-4">
|
|
|
Last updated: {lastUpdated.toLocaleString('en-GB', {
|
|
|
- day: '2-digit',
|
|
|
- month: '2-digit',
|
|
|
- year: 'numeric',
|
|
|
- hour: '2-digit',
|
|
|
- minute: '2-digit',
|
|
|
- hour12: true
|
|
|
- })}
|
|
|
+ day: '2-digit',
|
|
|
+ month: '2-digit',
|
|
|
+ year: 'numeric',
|
|
|
+ hour: '2-digit',
|
|
|
+ minute: '2-digit',
|
|
|
+ hour12: true
|
|
|
+ })}
|
|
|
</p>
|
|
|
{/if}
|
|
|
<div class="relative h-80">
|