Untitled
unknown
plain_text
a year ago
10 kB
8
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