Quantcast
Channel: Active questions tagged mongodb-atlas - Stack Overflow
Viewing all articles
Browse latest Browse all 271

i'm trying to fetch data from mongodb atlas collection and display it in react front end

$
0
0

I've made a server.js in my npx cra project that's connecting to atlas cluster and formatting the received data using a schema.

The data is about solar generation data I've downloaded from kaggle and uploaded to the solar collection using mongodb compass.

I ran into a problem when I tried to fetch the data and visualize it using graphs.

Using a graph component it keeps showing a single document regardless of date range.

Here's my server.js:

const express = require('express');const mongoose = require('mongoose');const cors = require('cors');require('dotenv').config();const app = express();app.use(cors());app.use(express.json());mongoose.connect(process.env.MONGODB_URI, {    dbName: 'solargenerationdata'})    .then(() => console.log('Connected to MongoDB'))    .catch((err) => console.error('Failed to connect to MongoDB:', err));const GenerationDataSchema = new mongoose.Schema({    _id: mongoose.Schema.Types.ObjectId,    DATE_TIME: String,    PLANT_ID: String,    DC_POWER: Number,    AC_POWER: Number,    DAILY_YIELD: Number,    TOTAL_YIELD: Number,});const GenerationDataModel = mongoose.model('solar', GenerationDataSchema, 'solar');// Modified API endpointsapp.get('/api/generation_data/summary', async (req, res) => {    try {        const startDate = req.query.startDate || new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString();        const endDate = req.query.endDate || new Date().toISOString();        const data = await GenerationDataModel.aggregate([            {                $match: {                    DATE_TIME: {                        $gte: startDate,                        $lte: endDate                    }                }            },            {                $group: {                    _id: {                        date: { $substr: ["$DATE_TIME", 0, 10] },                        plantId: "$PLANT_ID"                    },                    avgDcPower: { $avg: "$DC_POWER" },                    avgAcPower: { $avg: "$AC_POWER" },                    totalDailyYield: { $max: "$DAILY_YIELD" },                    maxTotalYield: { $max: "$TOTAL_YIELD" }                }            },            {                $sort: { "_id.date": 1 }            }        ]);        console.log('Summary Data:', data); // Log the fetched data        res.status(200).json(data);    } catch (error) {        res.status(500).json({ error: 'Server Error' });    }});app.get('/api/generation_data/latest', async (req, res) => {    try {        const latestData = await GenerationDataModel.findOne()            .sort({ DATE_TIME: -1 });        console.log('Latest Data:', latestData); // Log the fetched data        res.status(200).json(latestData);    } catch (error) {        res.status(500).json({ error: 'Server Error' });    }});const PORT = 5000;app.listen(PORT, () => {    console.log(`Server running on http://localhost:${PORT}`);});

and graphcomponent.js

import { useEffect, useState } from 'react';import { CartesianGrid, Legend, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts';const GraphComponent = () => {    const [data, setData] = useState([]);    const [latestData, setLatestData] = useState(null);    const [loading, setLoading] = useState(true);    const [error, setError] = useState(null);    const [dateRange, setDateRange] = useState({        from: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000),        to: new Date(),    });    useEffect(() => {        const fetchData = async () => {            try {                setLoading(true);                setError(null);                const params = new URLSearchParams({                    startDate: dateRange.from.toISOString(),                    endDate: dateRange.to.toISOString(),                });                // Fetch summary data                const summaryResponse = await fetch(`http://localhost:5000/api/generation_data/summary?${params}`);                if (!summaryResponse.ok) {                    throw new Error(`HTTP error! status: ${summaryResponse.status}`);                }                const summaryData = await summaryResponse.json();                // Process summary data                const formattedData = summaryData.map(item => ({                    date: new Date(item.DATE_TIME).toLocaleDateString(),                    plantId: item.PLANT_ID,                    dcPower: Number(item.DC_POWER) || 0,                    acPower: Number(item.AC_POWER) || 0,                    dailyYield: Number(item.DAILY_YIELD) || 0,                    totalYield: Number(item.TOTAL_YIELD) || 0                }));                // Group by date and calculate averages                const groupedData = formattedData.reduce((acc, curr) => {                    const existingEntry = acc.find(item => item.date === curr.date);                    if (existingEntry) {                        existingEntry.dcPower += curr.dcPower;                        existingEntry.acPower += curr.acPower;                        existingEntry.dailyYield += curr.dailyYield;                        existingEntry.count += 1;                    } else {                        acc.push({                            date: curr.date,                            dcPower: curr.dcPower,                            acPower: curr.acPower,                            dailyYield: curr.dailyYield,                            count: 1                        });                    }                    return acc;                }, []);                // Calculate final averages                const finalData = groupedData.map(item => ({                    date: item.date,                    avgDcPower: Number((item.dcPower / item.count).toFixed(2)),                    avgAcPower: Number((item.acPower / item.count).toFixed(2)),                    totalDailyYield: Number((item.dailyYield / item.count).toFixed(2))                })).sort((a, b) => new Date(a.date) - new Date(b.date));                // Fetch latest data                const latestResponse = await fetch('http://localhost:5000/api/generation_data/latest');                if (!latestResponse.ok) {                    throw new Error(`HTTP error! status: ${latestResponse.status}`);                }                const latestDataResponse = await latestResponse.json();                setData(finalData);                setLatestData(latestDataResponse);                setLoading(false);            } catch (error) {                console.error('Error in fetchData:', error);                setError(`Error fetching data: ${error.message}`);                setLoading(false);            }        };        fetchData();    }, [dateRange]);    const handleDateChange = (event) => {        const { name, value } = event.target;        setDateRange(prev => ({            ...prev,            [name]: new Date(value)        }));    };    if (loading) {        return (<div className="flex items-center justify-center h-64"><div className="animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"></div><span className="ml-2">Loading data...</span></div>        );    }    return (<div className="space-y-6 p-4">            {error && (<div className="bg-red-50 border-l-4 border-red-400 p-4 rounded"><div className="flex"><div className="ml-3"><h3 className="text-sm font-medium text-red-800">Error</h3><div className="mt-2 text-sm text-red-700">{error}</div></div></div></div>            )}            {/* Date Range Selection */}<div className="bg-white p-4 rounded-lg shadow"><h2 className="text-xl font-semibold mb-4">Select Date Range</h2><div className="flex gap-4"><div><label className="block text-sm font-medium text-gray-700">From</label><input                            type="date"                            name="from"                            value={dateRange.from.toISOString().split('T')[0]}                            onChange={handleDateChange}                            className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"                        /></div><div><label className="block text-sm font-medium text-gray-700">To</label><input                            type="date"                            name="to"                            value={dateRange.to.toISOString().split('T')[0]}                            onChange={handleDateChange}                            className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"                        /></div></div></div>            {/* Current Metrics */}            {latestData && (<div className="bg-white p-4 rounded-lg shadow"><h2 className="text-xl font-semibold mb-4">Current Solar Generation Metrics</h2><div className="grid grid-cols-1 md:grid-cols-3 gap-4"><div className="p-4 bg-gray-100 rounded-lg"><h3 className="text-sm font-medium text-gray-500">Plant ID</h3><p className="text-2xl font-bold">{latestData.PLANT_ID || 'N/A'}</p></div><div className="p-4 bg-gray-100 rounded-lg"><h3 className="text-sm font-medium text-gray-500">Daily Yield</h3><p className="text-2xl font-bold">{latestData.DAILY_YIELD?.toFixed(2) || '0'} kWh</p></div><div className="p-4 bg-gray-100 rounded-lg"><h3 className="text-sm font-medium text-gray-500">Total Yield</h3><p className="text-2xl font-bold">{latestData.TOTAL_YIELD?.toFixed(2) || '0'} kWh</p></div></div></div>            )}            {/* Power Generation Trends */}            {data.length > 0 ? (<div className="bg-white p-4 rounded-lg shadow"><h2 className="text-xl font-semibold mb-4">Power Generation Trends</h2><div className="h-[400px]"><ResponsiveContainer width="100%" height="100%"><LineChart data={data}><CartesianGrid strokeDasharray="3 3" /><XAxis                                    dataKey="date"                                    tick={{ fontSize: 12 }}                                    angle={-45}                                    textAnchor="end"                                /><YAxis /><Tooltip /><Legend /><Line                                     type="monotone"                                     dataKey="avgDcPower"                                     stroke="#8884d8"                                     name="Avg DC Power (kW)"                                     dot={false}                                /><Line                                     type="monotone"                                     dataKey="avgAcPower"                                     stroke="#82ca9d"                                     name="Avg AC Power (kW)"                                     dot={false}                                /><Line                                     type="monotone"                                     dataKey="totalDailyYield"                                     stroke="#ffc658"                                     name="Daily Yield (kWh)"                                     dot={false}                                /></LineChart></ResponsiveContainer></div></div>            ) : (<div className="bg-yellow-50 border-l-4 border-yellow-400 p-4"><div className="flex"><div className="ml-3"><h3 className="text-sm font-medium text-yellow-800">No Data Available</h3><div className="mt-2 text-sm text-yellow-700">                                No generation data available for the selected date range.</div></div></div></div>            )}</div>    );};export default GraphComponent;

thanks in advance for your help !


Viewing all articles
Browse latest Browse all 271

Trending Articles