Release 0.14.0-alpha #42
@@ -201,7 +201,7 @@ export default function Chart({
|
||||
|
||||
// ─── Data ──────────────────────────────────────────────────────────
|
||||
|
||||
const chartData = data.map((item) => {
|
||||
const chartData = useMemo(() => data.map((item) => {
|
||||
let formattedDate: string
|
||||
if (interval === 'minute') {
|
||||
formattedDate = new Date(item.date).toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' })
|
||||
@@ -223,7 +223,7 @@ export default function Chart({
|
||||
bounce_rate: item.bounce_rate,
|
||||
avg_duration: item.avg_duration,
|
||||
}
|
||||
})
|
||||
}), [data, interval])
|
||||
|
||||
const annotationMarkers = useMemo(() => {
|
||||
if (!annotations?.length) return []
|
||||
@@ -298,7 +298,7 @@ export default function Chart({
|
||||
|
||||
// ─── Metrics with trends ──────────────────────────────────────────
|
||||
|
||||
const metricsWithTrends = METRIC_CONFIGS.map((m) => {
|
||||
const metricsWithTrends = useMemo(() => METRIC_CONFIGS.map((m) => {
|
||||
const value = stats[m.key]
|
||||
const previousValue = prevStats?.[m.key]
|
||||
const change = previousValue != null && previousValue > 0
|
||||
@@ -313,7 +313,7 @@ export default function Chart({
|
||||
change,
|
||||
isPositive,
|
||||
}
|
||||
})
|
||||
}), [stats, prevStats])
|
||||
|
||||
const hasData = data.length > 0
|
||||
const hasAnyNonZero = hasData && chartData.some((d) => (d[metric] as number) > 0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { useEffect, useMemo, useRef } from 'react'
|
||||
import createGlobe from 'cobe'
|
||||
import { useTheme } from '@ciphera-net/ui'
|
||||
import { countryCentroids } from '@/lib/country-centroids'
|
||||
@@ -22,16 +22,19 @@ export default function Globe({ data, className }: GlobeProps) {
|
||||
// Update refs without causing effect re-runs
|
||||
isDarkRef.current = resolvedTheme === 'dark'
|
||||
|
||||
// Compute markers into ref
|
||||
const max = data.length ? Math.max(...data.map((d) => d.pageviews)) : 0
|
||||
markersRef.current = max > 0
|
||||
? data
|
||||
.filter((d) => d.country && d.country !== 'Unknown' && countryCentroids[d.country])
|
||||
.map((d) => ({
|
||||
location: [countryCentroids[d.country].lat, countryCentroids[d.country].lng] as [number, number],
|
||||
size: 0.03 + (d.pageviews / max) * 0.12,
|
||||
}))
|
||||
: []
|
||||
// Compute markers into ref (memoized to avoid recalculating on every render)
|
||||
const markers = useMemo(() => {
|
||||
const max = data.length ? Math.max(...data.map((d) => d.pageviews)) : 0
|
||||
return max > 0
|
||||
? data
|
||||
.filter((d) => d.country && d.country !== 'Unknown' && countryCentroids[d.country])
|
||||
.map((d) => ({
|
||||
location: [countryCentroids[d.country].lat, countryCentroids[d.country].lng] as [number, number],
|
||||
size: 0.03 + (d.pageviews / max) * 0.12,
|
||||
}))
|
||||
: []
|
||||
}, [data])
|
||||
markersRef.current = markers
|
||||
|
||||
useEffect(() => {
|
||||
if (!canvasRef.current) return
|
||||
|
||||
Reference in New Issue
Block a user