Untitled
unknown
plain_text
a year ago
10 kB
4
Indexable
"use client"; import React, { useState, useEffect } from "react"; import { Line } from "react-chartjs-2"; import moment from "moment-timezone"; import Image from "next/image"; import zoomPlugin from 'chartjs-plugin-zoom'; import { Chart, registerables } from 'chart.js'; import { queryCost, CostData, RangeTime } from "@/app/lib/influxQueries"; import { Types } from "@/app/types"; Chart.register(...registerables, zoomPlugin); interface Props { allDevices: Types.Device[]; deviceId:string | null; devicePhase:string | null; dayId:string | null; } const devices: { [key: string]: number } = { "0": 2, "1": 2, "215616591345044": 3, }; const IndexPage: React.FC<Props> = ({ allDevices, deviceId, devicePhase, dayId }) => { const [activeDevice, setActiveDevice] = useState<string>(deviceId ?? "0"); const [activeDevicePhase, setActiveDevicePhase] = useState<number>(devicePhase == "Single Phase" ? 2 : 3); const [costData, setCostData] = useState<CostData | null>(null); const [loading, setLoading] = useState(false); const [selectedDuration, setSelectedDuration] = useState<string>(dayId ?? "-1d"); // useEffect(() => { // if (deviceId !== null) { // setActiveDevice(deviceId); // setPhase(devices[deviceId]); // } // if (dayId !== null) { // setSelectedDuration(dayId); // } // }, [deviceId, dayId]); useEffect(() => { const fetchData = async () => { setLoading(true); try { const kwh = await queryCost({ id: activeDevice, phase: activeDevicePhase }, selectedDuration as RangeTime); console.log("COST DATA",kwh); setCostData(kwh); } catch (error) { } finally { setLoading(false); } }; fetchData(); }, [activeDevice, activeDevicePhase, selectedDuration]); const handleDeviceChange = (event: React.ChangeEvent<HTMLSelectElement>) => { setActiveDevice(event.target.value); // activeDevicePhase(devices[event.target.value]); }; const handleDurationChange = (event: React.ChangeEvent<HTMLSelectElement>) => { setSelectedDuration(event.target.value); }; if (loading) { return ( <p className="h-full flex justify-center items-center poppins text-[48px] font-semibold"> Loading... </p> ); } const formatTimestamps = (timestamps: string[], duration: string) => { if (duration === "-1y") { return timestamps.map((timestamp) => moment(timestamp).tz("Asia/Dhaka").format("MMM YYYY") ); } else if (duration === "-30d") { return timestamps.map((timestamp) => moment(timestamp).tz("Asia/Dhaka").format("DD MMM") ); } else { return timestamps.map((timestamp) => moment(timestamp).tz("Asia/Dhaka").format("HH:mm") ); } }; const calculateAverage = (data: number[]): number => { if (data.length === 0) return 0; const sum = data.reduce((acc, value) => acc + value, 0); return sum / data.length; }; if (!costData) { return ( <p className="h-full flex justify-center items-center poppins text-[48px] font-semibold"> No data available </p> ); } const kwhLabels = formatTimestamps(costData.xAxis, selectedDuration); const renderKwhDatasets = () => { const datasets = [ { label: activeDevicePhase !== 3 ? "Killo Watt" : "Phase 1", data: costData.costSeries, fill: true, borderColor: "rgb(163, 39, 114)", backgroundColor: "rgba(163, 39, 114, 0.1)", tension: 0.6, }, ]; if (activeDevicePhase === 3) { datasets.push({ label: "Phase 2", data: costData.costSeries, fill: true, borderColor: "rgb(114, 57, 234)", backgroundColor: "rgba(114, 57, 234, 0.1)", tension: 0.6, }); datasets.push({ label: "Phase 3", data: costData.costSeries, fill: true, borderColor: "rgb(246, 192, 0)", backgroundColor: "rgba(246, 192, 0, 0.1)", tension: 0.6, }); } return datasets; }; const kwhAverage = calculateAverage( costData.costSeries.concat( costData.costSeries, costData.costSeries ) ); return ( <div> {/* killoWatt Data Chart */} <div className="flex flex-col items-center bg-[#FFFFFF] rounded-xl p-6 text-[#3F4254] dark:bg-[#030304]" style={{ marginBottom: "20px" }} > <h2 className="items-center text-[#918F92] poppins text-[14px] dark:text-[#FFFFFFD9]"> Cost </h2> {activeDevicePhase !== 3 && ( <div className="text-[#1C469C] text-[20px] font-medium py-2 poppins"> {kwhAverage.toFixed(2)} </div> )} <div className="flex gap-6"> {/* Dropdown to select Group */} <div className="relative inline-flex items-center mb-4 poppins"> <select id="activeGroup" // onChange={handleGroupChange} // value={activeGroup} className="custom-select px-2 py-1 border border-gray-300 rounded-md text-[#918F92] bg-[#ffffff] focus:outline-none dark:bg-[#030304] dark:border-[#FFFFFF40] appearance-none w-full" > <option value="Group X">Group X</option> <option value="Group Y">Group Y</option> <option value="Group Z">Group Z</option> </select> <Image className="absolute right-2 pointer-events-none w-auto h-auto" src="/dashboard/caret-down-fill.svg" alt="caret-down" width={12} height={12} /> </div> {/* Dropdown to select Vendor */} <div className="relative inline-flex items-center mb-4 poppins"> <select id="activeVendor" // onChange={handleVendorChange} // value={activeVendor} className="custom-select px-2 py-1 border border-gray-300 rounded-md text-[#918F92] bg-[#ffffff] focus:outline-none dark:bg-[#030304] dark:border-[#FFFFFF40] appearance-none w-full" > <option value="Vendor X">Vendor X</option> <option value="Vendor Y">Vendor Y</option> <option value="Vendor Z">Vendor Z</option> </select> <Image className="absolute right-2 pointer-events-none w-auto h-auto" src="/dashboard/caret-down-fill.svg" alt="caret-down" width={12} height={12} /> </div> {/* Dropdown to select device */} <div className="relative inline-flex items-center mb-4 c"> <select id="activeDevice" onChange={handleDeviceChange} value={activeDevice} className="custom-select px-2 py-1 border border-gray-300 rounded-md text-[#918F92] bg-[#ffffff] focus:outline-none dark:bg-[#030304] dark:border-[#FFFFFF40] appearance-none w-full" > <option value="0">Device 1</option> <option value="1">Device 2</option> <option value="215616591345044">Device 3</option> </select> <Image className="absolute right-2 pointer-events-none w-auto h-auto" src="/dashboard/caret-down-fill.svg" alt="caret-down" width={12} height={12} /> </div> {/* Dropdown to select duration */} <div className="relative inline-flex items-center mb-4 poppins"> <select id="selectedDuration" onChange={handleDurationChange} value={selectedDuration} className="custom-select px-2 py-1 border border-gray-300 rounded-md text-[#918F92] bg-[#ffffff] focus:outline-none dark:bg-[#030304] dark:border-[#FFFFFF40] appearance-none w-full" > <option value="-1d">Today</option> <option value="-30d">Last month</option> <option value="-1y">Last year</option> </select> <Image className="absolute right-2 pointer-events-none" src="/dashboard/calender.svg" alt="caret-down" width={12} height={12} /> </div> {/* Dropdown to select Interval */} <div className="relative inline-flex items-center mb-4 poppins"> <select id="activeInterval" // onChange={handleIntervalChange} // value={activeInterval} className="custom-select px-2 py-1 border border-gray-300 rounded-md text-[#918F92] bg-[#ffffff] focus:outline-none dark:bg-[#030304] dark:border-[#FFFFFF40] appearance-none w-full" > <option value="Interval X">15 mins Interval</option> <option value="Interval Y">30 mins Interval</option> <option value="Interval Z">1 hours Interval</option> </select> <Image className="absolute right-2 pointer-events-none w-auto h-auto" src="/dashboard/caret-down-fill.svg" alt="caret-down" width={12} height={12} /> </div> </div> { costData ? <div style={{ height: "300px", width: "100%"}}> <Line data={{ labels: kwhLabels, datasets: renderKwhDatasets(), }} options={{ plugins: { legend: { display: true, position: "bottom", align: "start", }, zoom: { pan: { enabled: true, mode: 'x', }, zoom: { mode: 'x', drag: { enabled: true, backgroundColor: 'rgb(163, 39, 114,0.2)', borderColor: 'rgb(163, 39, 114, 1)', borderWidth: 1 } } } }, maintainAspectRatio: false, scales: { x: { grid: { display: false, }, }, }, }} /> </div> :null } </div> </div> ); }; export default IndexPage;
Editor is loading...
Leave a Comment