import { useMemo } from 'react'; import { Box, Flex, Spinner, Text } from '@chakra-ui/react'; import { useColorMode } from "@/components/ui/color-mode.jsx"; import Plot from 'react-plotly.js'; import VdapApi from '../../hooks/useVdapApi.js'; // Adjust path as needed export default function ExplosionEvents({ settings, widgetID }) { // Plotly expects 'linear' for normal axes const plotYAxisType = settings?.yAxisScale === 'log' ? 'log' : 'linear'; // 🎨 Let's check color mode so we can make people happy with light and dark const { colorMode } = useColorMode(); const isDark = colorMode === 'dark'; // Clean, single-line data fetching const { data: apiData, isLoading, error } = VdapApi('/api/v2/explosion_events?start_date=2025-05-01&end_date=2025-05-30'); // 1. Build the Traces (Data parsing) const plotTraces = useMemo(() => { if (!apiData || apiData.length === 0) return []; // Array of distinct Plotly shapes const Symbolway = [ 'circle', 'square', 'diamond', 'triangle-up', 'triangle-down', 'star', 'hexagram', 'pentagon', 'hexagon', 'octagon', 'cross', 'x' ]; // Sort data descending by number of events so smaller dots draw on top of larger ones const sortedData = [...apiData].sort((a, b) => b.number_events - a.number_events); // Efficiently group into Plotly traces by volcano const groupedData = sortedData.reduce((acc, curr) => { const name = curr.volcano_name || 'Unknown'; if (!acc[name]) acc[name] = { x: [], y: [] }; // Map the explosion-specific keys acc[name].x.push(new Date(curr.ts_epoch)); acc[name].y.push(curr.number_events); return acc; }, {}); return Object.keys(groupedData).map((volcanoName, index) => ({ name: volcanoName, x: groupedData[volcanoName].x, y: groupedData[volcanoName].y, type: 'scatter', mode: 'markers', marker: { size: 7, line: { width: .5, color: 'rgba(255, 255, 255, 0.7)' }, symbol: Symbolway[index % Symbolway.length], }, // Replicating the clean D3/Observable tooltip hovertemplate: `${volcanoName}
` + 'Date (UTC): %{x|%b %d %Y %H:%M}
' + 'Number of Explosions: %{y}' })); }, [apiData]); // 2. Build the Layout (Styling and Grid) const layout = useMemo(() => { return { autosize: true, paper_bgcolor: 'transparent', // Let Chakra UI background show through plot_bgcolor: 'transparent', font: { color: '#d1d5db' }, // gray.300 margin: { t: 40, r: 20, l: 20, b: 20 }, // title: { // text: '7 Day Consolidated Flight Levels', // font: { size: 16, color: 'white' }, // x: 0.05 // }, xaxis: { title: { text: 'Date (UTC)', font: { color: 'white', size: 12 } }, type: 'date', tickformat: '%b %d
%Y', // D3 requested %b %d \n %Y formatting gridcolor: '#4b5563', zerolinecolor: '#4b5563', automargin: true, }, yaxis: { title: { text: 'Number of Explosions', font: { color: 'white', size: 12 } }, type: plotYAxisType, gridcolor: '#4b5563', zerolinecolor: '#ffffff', automargin: true, }, // legend: { // orientation: 'h', // y: -0.2, // x: 0.5, // xanchor: 'center' // }, hovermode: 'closest', shapes: [ { type: 'line', x0: 0, x1: 1, xref: 'paper', // Spans entire chart width y0: 0, y1: 0, yref: 'y', line: { color: 'white', width: 1 } } ], }; }, [apiData, plotYAxisType]); if (isLoading) return ( ); if (error) return ( {error} ); if (plotTraces.length === 0) return ( No data available for current filter. ); return ( ); }