import VdapApi from '../../hooks/useVdapApi.js'; import { useMemo } from 'react'; import Plot from 'react-plotly.js'; import {Box, Flex, Spinner, Text} from "@chakra-ui/react"; import useBuildUrl from "@/hooks/useBuildUrl.js"; export default function SeismicEvents({ settings, widgetID}) { // build url, defaults to 7 days past const url = useBuildUrl('/api/v2/seismic_events', settings?.startDate, settings?.endDate); // retrieve data from api const { data: apiData, isLoading, error } = VdapApi(url); 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 seismic events count 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 seismic-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 Seismic Events: %{y}' })); }, [apiData]); 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: '', // 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: 'Seismic Count', font: { color: 'white', size: 12 } }, type: 'linear', 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 } } ], }; }, []); if (isLoading) return ( ); if (error) return ( {error} ); if (plotTraces.length === 0) return ( No data available for current filter. ); return ( ); }