diff --git a/client/src/components/Widgets/ExplosionEvents.jsx b/client/src/components/Widgets/ExplosionEvents.jsx
index e5b14af..ddd8044 100644
--- a/client/src/components/Widgets/ExplosionEvents.jsx
+++ b/client/src/components/Widgets/ExplosionEvents.jsx
@@ -1,12 +1,16 @@
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 }) {
- console.log("3. Chart received settings:", settings);
// Plotly expects 'linear' for normal axes
- const plotYAxisType = settings?.yAxisScale === 'symlog' ? 'symlog' : 'linear';
+ 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');
@@ -23,16 +27,17 @@ export default function ExplosionEvents({ settings }) {
'hexagon', 'octagon', 'cross', 'x'
];
- // Sort data descending by flight level (matching Observable behavior)
- const sortedData = [...apiData].sort((a, b) => b.obs_fl - a.obs_fl);
+ // 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.volc_name || 'Unknown';
+ const name = curr.volcano_name || 'Unknown';
if (!acc[name]) acc[name] = { x: [], y: [] };
- acc[name].x.push(new Date(curr.obs_va_epoch));
- acc[name].y.push(curr.obs_fl);
+ // Map the explosion-specific keys
+ acc[name].x.push(new Date(curr.ts_epoch));
+ acc[name].y.push(curr.number_events);
return acc;
}, {});
@@ -47,11 +52,11 @@ export default function ExplosionEvents({ settings }) {
line: { width: .5, color: 'rgba(255, 255, 255, 0.7)' },
symbol: Symbolway[index % Symbolway.length],
},
- // Replicating the clean Observable tooltip
+ // Replicating the clean D3/Observable tooltip
hovertemplate:
`${volcanoName}
` +
- 'Date: %{x|%b %d %Y %H:%M}
' +
- 'Flight Level: %{y}'
+ 'Date (UTC): %{x|%b %d %Y %H:%M}
' +
+ 'Number of Explosions: %{y}'
}));
}, [apiData]);
@@ -75,14 +80,14 @@ export default function ExplosionEvents({ settings }) {
font: { color: 'white', size: 12 }
},
type: 'date',
- tickformat: '%b %d
%Y %H:%M', // Multiline ticks from Observable
+ tickformat: '%b %d
%Y', // D3 requested %b %d \n %Y formatting
gridcolor: '#4b5563',
zerolinecolor: '#4b5563',
automargin: true,
},
yaxis: {
title: {
- text: 'Flight Level',
+ text: 'Number of Explosions',
font: { color: 'white', size: 12 }
},
type: plotYAxisType,
@@ -126,12 +131,12 @@ export default function ExplosionEvents({ settings }) {
if (plotTraces.length === 0) return (
- No flight level data available.
+ No data available for current filter.
);
return (
-
+
state.updateWidgetSettings);
// 1. Convert the saved string into a boolean for the toggle UI
- const isSymlog = currentSettings?.yAxisScale === 'symlog';
+ const isSymlog = currentSettings?.yAxisScale === 'log';
const handleToggle = (details) => {
// 2. Chakra v3 passes { checked: boolean } in the details object.
// Convert it back to the string Plotly expects.
console.log("1. Toggle Clicked! Raw details from Chakra:", details);
- const newScale = details.checked ? 'symlog' : 'normal';
+ const newScale = details.checked ? 'log' : 'normal';
updateSettings(widgetId, { yAxisScale: newScale });
};
@@ -30,7 +30,7 @@ export default function ExplosionEventsSettings({ widgetId, currentSettings }) {
- Use Symlog Scale
+ Use Log Scale
);
diff --git a/client/src/components/Widgets/AlertLevelWidget.jsx b/client/src/components/deprecated/AlertLevelWidget.jsx
similarity index 100%
rename from client/src/components/Widgets/AlertLevelWidget.jsx
rename to client/src/components/deprecated/AlertLevelWidget.jsx
diff --git a/client/src/components/deprecated/FirstWidgetButton.jsx b/client/src/components/deprecated/FirstWidgetButton.jsx
index 6ec7295..5c19f03 100644
--- a/client/src/components/deprecated/FirstWidgetButton.jsx
+++ b/client/src/components/deprecated/FirstWidgetButton.jsx
@@ -1,5 +1,5 @@
import { Box, Menu, Portal } from '@chakra-ui/react'
-import AlertLevel from "@/components/Widgets/AlertLevelWidget.jsx";
+import AlertLevel from "@/components/deprecated/AlertLevelWidget.jsx";
export default function FirstWidgetButton({ appendWidget }) {
const triggerItem = (
diff --git a/client/src/components/Widgets/Widget.jsx b/client/src/components/deprecated/Widget.jsx
similarity index 100%
rename from client/src/components/Widgets/Widget.jsx
rename to client/src/components/deprecated/Widget.jsx
diff --git a/client/src/components/deprecated/WidgetMenu.jsx b/client/src/components/deprecated/WidgetMenu.jsx
index e834a47..140af76 100644
--- a/client/src/components/deprecated/WidgetMenu.jsx
+++ b/client/src/components/deprecated/WidgetMenu.jsx
@@ -1,5 +1,5 @@
import { Menu, Portal } from "@chakra-ui/react";
-import AlertLevel from "../Widgets/AlertLevelWidget.jsx";
+import AlertLevel from "./AlertLevelWidget.jsx";
export default function WidgetMenu({appendWidget, triggerItem, positioning}) {
return (
diff --git a/client/src/constants/widgetRegistry.jsx b/client/src/constants/widgetRegistry.jsx
index 7da17e0..3e763da 100644
--- a/client/src/constants/widgetRegistry.jsx
+++ b/client/src/constants/widgetRegistry.jsx
@@ -83,5 +83,6 @@ export const WIDGET_REGISTRY = {
allowedSizes: {
medium: { w: 6, h: 12 }
}
- }
+ },
+
};
\ No newline at end of file
diff --git a/client/src/pages/home/tabs/MyDashboard.jsx b/client/src/pages/home/tabs/MyDashboard.jsx
index b7b3398..05f2c24 100644
--- a/client/src/pages/home/tabs/MyDashboard.jsx
+++ b/client/src/pages/home/tabs/MyDashboard.jsx
@@ -3,7 +3,7 @@ import { X, MoreVertical } from "lucide-react";
import { Responsive, WidthProvider } from "react-grid-layout";
import { useDashboardStore } from "@/store/useDashboardStore.jsx";
import { Suspense, useEffect, useRef } from 'react';
-
+import { useColorModeValue } from "@/components/ui/color-mode";
// 1. Import database messenger
import useAuthStore from "@/store/authStore";
@@ -14,6 +14,12 @@ import { WIDGET_REGISTRY } from '@/constants/widgetRegistry.jsx';
const ResponsiveGridLayout = WidthProvider(Responsive);
export default function MyDashboard() {
+ // 🌗 Let's adjust for our light and dark mode
+ const frameBg = useColorModeValue("gray.100", "gray.800");
+ const titleColor = useColorModeValue("gray.800", "gray.100");
+ const iconColor = useColorModeValue("gray.600", "gray.400");
+ const iconHoverBg = useColorModeValue("gray.100", "gray.700");
+
// ☁️ Database Connection
const { user } = useAuthStore();
@@ -67,7 +73,7 @@ export default function MyDashboard() {
return (
// The "Frame" that holds both the Title and the Chart
-
+
{/* THE TITLE BAR */}
-
+
{registryEntry.name}
@@ -166,7 +172,7 @@ export default function MyDashboard() {
right={2}
size="xs"
bg="white"
- color="gray.400"
+ color={iconColor}
border="1px solid"
borderColor="gray.200"
_hover={{ bg: "red.50", color: "red.500", borderColor: "red.200" }}