diff --git a/.env.example b/.env.example
index f35e5ba..67f7b08 100644
--- a/.env.example
+++ b/.env.example
@@ -1 +1 @@
-VITE_MOISTURE_DATA_URL=endpoint for moiture data json
+VITE_BACKEND_URL=endpoint for moiture data json
diff --git a/.env.production b/.env.production
index 86742ae..9af809e 100644
--- a/.env.production
+++ b/.env.production
@@ -1 +1 @@
-VITE_MOISTURE_DATA_URL=https://api.bodenfeuchte.org/mapData
+VITE_BACKEND_URL=https://api.bodenfeuchte.org
diff --git a/README.md b/README.md
index 18cf2be..647a8b2 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
## Available Scripts
-Before running/building the app either create a `.env` file or set the environment variable `VITE_MOISTURE_DATA_URL`.
+Before running/building the app either create a `.env` file or set the environment variable `VITE_BACKEND_URL`.
In the project directory, you can run:
diff --git a/package-lock.json b/package-lock.json
index 1f67257..5c51bcb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18,6 +18,7 @@
"date-fns": "^2.30.0",
"leaflet": "^1.9.4",
"react": "^18.2.0",
+ "react-chartjs-2": "^5.2.0",
"react-dom": "^18.2.0",
"react-leaflet": "^4.2.1",
"use-http": "^1.0.28"
@@ -2992,6 +2993,12 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
+ "node_modules/@kurkle/color": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz",
+ "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==",
+ "peer": true
+ },
"node_modules/@microsoft/load-themed-styles": {
"version": "1.10.295",
"resolved": "https://registry.npmjs.org/@microsoft/load-themed-styles/-/load-themed-styles-1.10.295.tgz",
@@ -4692,6 +4699,18 @@
"url": "https://github.com/chalk/chalk-template?sponsor=1"
}
},
+ "node_modules/chart.js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.1.tgz",
+ "integrity": "sha512-C74QN1bxwV1v2PEujhmKjOZ7iUM4w6BWs23Md/6aOZZSlwMzeCIDGuZay++rBgChYru7/+QFeoQW0fQoP534Dg==",
+ "peer": true,
+ "dependencies": {
+ "@kurkle/color": "^0.3.0"
+ },
+ "engines": {
+ "pnpm": ">=7"
+ }
+ },
"node_modules/cli-boxes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz",
@@ -8466,6 +8485,15 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-chartjs-2": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.2.0.tgz",
+ "integrity": "sha512-98iN5aguJyVSxp5U3CblRLH67J8gkfyGNbiK3c+l1QI/G4irHMPQw44aEPmjVag+YKTyQ260NcF82GTQ3bdscA==",
+ "peerDependencies": {
+ "chart.js": "^4.1.1",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/react-dom": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
diff --git a/package.json b/package.json
index 763b12e..b32e150 100644
--- a/package.json
+++ b/package.json
@@ -14,6 +14,7 @@
"date-fns": "^2.30.0",
"leaflet": "^1.9.4",
"react": "^18.2.0",
+ "react-chartjs-2": "^5.2.0",
"react-dom": "^18.2.0",
"react-leaflet": "^4.2.1",
"use-http": "^1.0.28"
diff --git a/src/components/SensorChart/index.tsx b/src/components/SensorChart/index.tsx
new file mode 100644
index 0000000..d8f061c
--- /dev/null
+++ b/src/components/SensorChart/index.tsx
@@ -0,0 +1,100 @@
+import {
+ Chart as ChartJS,
+ CategoryScale,
+ LinearScale,
+ PointElement,
+ LineElement,
+ BarElement,
+ Tooltip,
+ Legend,
+ ChartData,
+} from "chart.js";
+import { Chart } from "react-chartjs-2";
+import { SensorDetails, SensorInfo } from "../../model/models";
+import useSensorDetails from "../../hooks/useSensorDetails";
+
+// ChartJS setup
+ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement, BarElement, Tooltip, Legend);
+
+const recentDaysChartOptions = {
+ responsive: true,
+ interaction: {
+ mode: "index" as const,
+ intersect: false,
+ },
+ plugins: {
+ legend: {
+ position: "top" as const,
+ labels: {
+ boxWidth: 20,
+ boxHeight: 1,
+ },
+ },
+ },
+ maintainAspectRatio: false,
+ scales: {
+ moisture: {
+ type: "linear" as const,
+ display: true,
+ position: "left" as const,
+ ticks: {
+ callback: (value: any, index: any, ticks: any) => value + " %",
+ },
+ suggestMin: 0,
+ suggestMax: 50,
+ },
+ // precipitation: {
+ // type: 'linear' as const,
+ // display: true,
+ // position: 'right' as const,
+ // suggestedMax: 10,
+ // grid: {
+ // drawOnChartArea: false,
+ // },
+ // ticks: {
+ // callback: (value: any, index: any, ticks: any) => (value + " mm")
+ // }
+ // },
+ },
+};
+
+function extractRecentDaysDataset(details: SensorDetails): ChartData<"bar" | "line", number[], string> {
+ const colors = {
+ red: "rgb(255, 99, 132)",
+ orange: "rgb(255, 159, 64)",
+ yellow: "rgb(255, 205, 86)",
+ green: "rgb(75, 192, 192)",
+ blue: "rgb(54, 162, 235)",
+ purple: "rgb(153, 102, 255)",
+ grey: "rgb(201, 203, 207)",
+ };
+ return {
+ labels: details.measurements.map((d) => d.timestamp.toLocaleDateString()),
+ datasets: [
+ {
+ label: "Tageswert",
+ type: "line",
+ data: details.measurements.map((d) => d.moisture),
+ borderColor: colors.green,
+ backgroundColor: colors.green,
+ yAxisID: "moisture",
+ },
+ {
+ label: "Globales Mittel",
+ type: "line",
+ data: details.peerMeasurements.map((d) => d.moisture),
+ borderColor: colors.grey,
+ backgroundColor: colors.grey,
+ yAxisID: "moisture",
+ },
+ ],
+ };
+}
+
+export default function SensorChart({ sensorInfo }: { sensorInfo: SensorInfo }) {
+ const { details, loading, error } = useSensorDetails(sensorInfo);
+ if (details) return
@@ -86,6 +90,9 @@ const SensorTooltip = ({ record }: { record: SensorInfo }) => {
Letzte Aktualisierung: {record.last_updated.toLocaleString()}
+
- tagesmittel
+ Tagesmittel
letzte