-
diff --git a/frontend/src/components/ObservationsTimeline.vue b/frontend/src/components/ObservationsTimeline.vue
index ecc41f8..39e90f7 100644
--- a/frontend/src/components/ObservationsTimeline.vue
+++ b/frontend/src/components/ObservationsTimeline.vue
@@ -10,10 +10,13 @@ import {
CHART_SCALE_X_OPTIONS,
resampleTimedData,
setChartDatetimeRange,
+ themeTextColor,
} from '@/utils/commonCharts.js'
+import { useThemeStore } from '@/stores/theme'
+
+const themeStore = useThemeStore()
ChartJS.register(...registerables, annotationPlugin)
-ChartJS.defaults.color = '#dee2e6'
ChartJS.defaults.borderColor = '#495057'
const props = defineProps({
@@ -55,6 +58,7 @@ const props = defineProps({
const chartOptions = computed(() => {
let scaleXOptions = { ...CHART_SCALE_X_OPTIONS }
+ scaleXOptions.ticks.color = themeTextColor(themeStore.isDark)
// Set the time range of the chart
setChartDatetimeRange(scaleXOptions, props.timePickerState.from, props.timePickerState.to)
@@ -69,6 +73,7 @@ const chartOptions = computed(() => {
offset: true,
ticks: {
display: true,
+ color: themeTextColor(themeStore.isDark),
},
grid: {
display: false,
diff --git a/frontend/src/components/ThemeToggle.vue b/frontend/src/components/ThemeToggle.vue
new file mode 100644
index 0000000..7b47d7b
--- /dev/null
+++ b/frontend/src/components/ThemeToggle.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/frontend/src/stores/theme.js b/frontend/src/stores/theme.js
new file mode 100644
index 0000000..844b8a5
--- /dev/null
+++ b/frontend/src/stores/theme.js
@@ -0,0 +1,33 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+/**
+ * Tracking of the current theme (dark or light).
+ */
+export const useThemeStore = defineStore('theme', () => {
+ const STORAGE_KEY = 'theme'
+ const theme = ref(initialTheme())
+
+ /**
+ * Determine the initial theme mode based on local storage or system preference.
+ */
+ function initialTheme() {
+ const saved = localStorage.getItem(STORAGE_KEY)
+ if (saved === 'dark' || saved === 'light') return saved
+ return window.matchMedia?.('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
+ }
+
+ /**
+ * Sets the current theme.
+ */
+ function setTheme(newTheme) {
+ theme.value = newTheme === 'dark' ? 'dark' : 'light'
+ localStorage.setItem(STORAGE_KEY, theme.value)
+ }
+
+ return {
+ theme: computed(() => theme.value),
+ isDark: computed(() => theme.value === 'dark'),
+ setTheme,
+ }
+})
diff --git a/frontend/src/utils/commonCharts.js b/frontend/src/utils/commonCharts.js
index 2653585..1286609 100644
--- a/frontend/src/utils/commonCharts.js
+++ b/frontend/src/utils/commonCharts.js
@@ -35,6 +35,13 @@ export const CHART_COMMON_OPTIONS = {
maintainAspectRatio: false,
}
+/**
+ * Gets text color based on current theme
+ */
+export function themeTextColor(isDark) {
+ return isDark ? '#DEE2E6' : '#212529'
+}
+
/**
* Sets chart datetime range if both `dtFrom` and `dtTo` are provided
* @param {Object} chartScaleXOptions Options for the X axis