Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 12 additions & 11 deletions frontend/src/main-page/dashboard/Charts/BarYearGrantStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ const BarYearGrantStatus = observer(
.sort((a, b) => b.value - a.value);

return (
<div className="chart-container">
<div className="">
<div className="flex flex-row w-full justify-between">
<div>
{/* Title */}
<div className="text-lg w-full text-left font-semibold align">
Year Grant Status
<div className="text-md lg:text-lg w-full text-left font-semibold align">
Grant Status
</div>
{/* Year */}
<div className="text-sm w-full text-left align">{recentYear}</div>
Expand All @@ -77,20 +77,20 @@ const BarYearGrantStatus = observer(
</label>
</div>
</div>
<ResponsiveContainer width="100%" height={450} min-width={400}>
<ResponsiveContainer width="100%" height={150} min-width={400}>
<BarChart
data={checked ? data_money : data_count}
layout="vertical"
margin={{ top: 10, right: 60, left: 40, bottom: 30 }}
layout="horizontal"
margin={{ top: 25, right: 20, left: 20, bottom: 0 }}
>
<YAxis
<XAxis
axisLine={false}
type="category"
dx={-10}
dataKey="name"
tickLine={false}
style={{fontSize: "var(--font-size-sm)"}}
/>
<XAxis
<YAxis
type="number"
width="auto"
hide
Expand All @@ -103,14 +103,15 @@ const BarYearGrantStatus = observer(
type="monotone"
stackId="a"
dataKey="value"
fill="var(--color-primary-800)"
fill="var(--color-primary-900)"
strokeWidth={2}
name="Grants"
radius={[15, 15, 15, 15]}
>
<LabelList
dataKey="value"
position="right"
position="top"
style={{fontSize: "var(--font-size-xs)", fill: "var(--color-grey-600)"}}
formatter={(label: any) =>
typeof label === "number"
? checked
Expand Down
84 changes: 39 additions & 45 deletions frontend/src/main-page/dashboard/Charts/DonutMoneyApplied.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ import { aggregateMoneyGrantsByYear, YearAmount } from "../grantCalculations";
import "../styles/Dashboard.css";
import { Grant } from "../../../../../middle-layer/types/Grant";
import { getListApplied } from "../../../../../middle-layer/types/Status";
import { FaCircle } from "react-icons/fa";
import { useState } from "react";

const DonutMoneyApplied = observer(({ grants }: { grants: Grant[] }) => {
const [width, setWidth] = useState(0);

// Helper to sum values for given statuses
const sumByStatus = (data: Record<string, number>, statuses: string[]) =>
Object.entries(data)
Expand All @@ -18,7 +22,7 @@ const DonutMoneyApplied = observer(({ grants }: { grants: Grant[] }) => {
year: grant.year.toString(),
received: sumByStatus(grant.data, getListApplied(true)),
unreceived: sumByStatus(grant.data, getListApplied(false)),
})
}),
);

// Summing values across years
Expand All @@ -27,94 +31,84 @@ const DonutMoneyApplied = observer(({ grants }: { grants: Grant[] }) => {
sumR + received,
sumU + unreceived,
],
[0, 0]
[0, 0],
);
const total = sumReceived + sumUnreceived;
const data = [
{ name: "Received", value: sumReceived, fill: "var(--color-yellow)"},
{ name: "Unreceived", value: sumUnreceived, fill: "var(--color-primary-800)" },
{ name: "Received", value: sumReceived, fill: "var(--color-primary-900)" },
{
name: "Unreceived",
value: sumUnreceived,
fill: "var(--color-primary-700)",
},
];

// Creating the label for the slices
const LabelItem = ({
name,
value,
percent,
color,
}: {
name: string;
value: number;
percent: number;
color: string;
}) => {
return (
<div className="w-[100px] ">
<div className="font-semibold">{name}</div>
<div className="h-[0.15rem] w-[80%] mt-0 rounded-full"
style={{
backgroundColor: color,
}}
/>
<div className="text-sm font-medium text-grey-800 mt-1">
{`${(percent * 100).toFixed(0)}% ($${(value / 1_000_000).toFixed(
2
)}M)`}
<div className="flex flex-row items-center">
<FaCircle className=" mr-2 text-sm" style={{ color }} />
<div className="text-xs lg:text-sm font-medium text-grey-700">
{`${(percent * 100).toFixed(0)}%`}&nbsp;{name}
</div>
</div>
);
};

return (
<div
className="chart-container flex flex-col align-center"
>
<div className="relative w-full h-full flex flex-col">
<div className="flex flex-col align-center h-full">
<div className={`w-full ${width > 250 ? "mb-0" : "mb-14"}`}>
{/* Title */}
<div className="text-lg font-semibold relative text-left">
Money Applied For {/* Total Amount */}
<div className="text-2xl font-semibold mt-1 absolute">
<div className="text-md lg:text-lg font-semibold text-left h-full align">
Money Applied All Time {/* Total Amount */}
<div className={`text-2xl lg:text-3xl font-semibold`}>
{`$${((sumReceived + sumUnreceived) / 1000000).toLocaleString(
"en-us",
{
maximumFractionDigits: 2,
}
},
)}M`}
</div>
{/* Floating Right Label */}
{sumUnreceived > 0 && (
<div className="absolute top-2 right-2 p-4 mx-10 my-4 z-50 rounded-3xl bg-white bg-opacity-50">
<div className={`gap-1 flex flex-col absolute ${width > 250 ? "mt-12" : "mt-2"}`}>
<LabelItem
name="Received"
percent={sumReceived / total}
color="var(--color-primary-900)"
/>
<div className="rounded-3xl">
<LabelItem
name="Unreceived"
value={sumUnreceived}
percent={sumUnreceived / total}
color="var(--color-primary-800)"
color="var(--color-primary-700)"
/>
</div>
)}
{/* Floating Left Label */}
{sumReceived > 0 && (
<div className="absolute -bottom-[240px] left-2 p-4 mx-10 my-4 z-50 rounded-3xl bg-white bg-opacity-50">
<LabelItem
name="Received"
value={sumReceived}
percent={sumReceived / total}
color="var(--color-yellow)"
/>
</div>
)}
</div>
</div>
</div>
<ResponsiveContainer width="100%" height={250}>
<ResponsiveContainer
width="100%"
height="100%"
onResize={(w) => setWidth(w)}
>
<PieChart
style={{ maxWidth: "1000px", maxHeight: "300px", aspectRatio: 1 }}
style={{ aspectRatio: 1 }}
margin={{ top: 0, right: 0, left: width > 250 ? 150 : 0, bottom: 0 }}
>
<Pie
data={data}
startAngle={90}
endAngle={450}
dataKey="value"
nameKey="name"
innerRadius="60%"
innerRadius="55%"
outerRadius="80%"
cornerRadius={50}
stroke="white"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export const GanttYearGrantTimeline = observer(
// Filtering events that are included in current date range
// Example can be also found on video https://youtu.be/9oy4rTVEfBQ?t=118&si=52BGKSIYz6bTZ7fx
// and in the react-scheduler repo App.tsx file https://github.com/Bitnoise/react-scheduler/blob/master/src/App.tsx
const filteredMockedSchedulerData = data.map((grant) => ({
const filteredSchedulerData = data.map((grant) => ({
...grant,
data: grant.data.filter((project) => {
const startInRange =
Expand All @@ -140,10 +140,10 @@ export const GanttYearGrantTimeline = observer(
}));

return (
<div className="chart-container h-full w-full">
<div className="h-full w-full">
{/* Title */}
<div className="text-lg w-full text-left font-semibold">
Year Grant Timeline
<div className="text-md lg:text-lg w-full text-left font-semibold">
Grant Timeline
</div>
{/* Year */}
<div className="text-sm w-full text-left">
Expand All @@ -152,9 +152,9 @@ export const GanttYearGrantTimeline = observer(
: ""}
{recentYear}
</div>
<div className="w-full h-full max-w-screen relative">
<div className="w-full h-96 max-w-screen relative">
<Scheduler
data={filteredMockedSchedulerData}
data={filteredSchedulerData}
isLoading={false}
onRangeChange={handleRangeChange}
config={{
Expand Down
56 changes: 31 additions & 25 deletions frontend/src/main-page/dashboard/Charts/KPICard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { observer } from "mobx-react-lite";
import { FaArrowTrendUp, FaArrowTrendDown } from "react-icons/fa6";
import { FaArrowDown, FaArrowUp } from "react-icons/fa6";

const KPICard = observer(
({
Expand All @@ -16,38 +16,44 @@ const KPICard = observer(
percentChange: number;
}) => {
return (
<div className="chart-container !bg-orange-light w-full flex flex-col justify-between">
<div className="chart-container bg-white w-full flex flex-col justify-between">
{/* Title */}
<div className="text-lg w-full text-left font-semibold">{title}</div>

<div className="text-md lg:text-lg w-full text-left font-semibold">{title}</div>
<div className="text-2xl lg:text-3xl font-semibold text-left">{formattedValue}</div>
{/* Value and Percent Change */}
<div className="flex flex-row justify-between items-center w-full">
<div className="text-xl font-semibold text-left">
{formattedValue}
</div>

<div className="flex flex-row justify-between items-center w-full mt-auto">
{priorYear && (
<div className="text-sm text-right flex items-center justify-end">
{percentChange >= 0
? `+${percentChange.toFixed(0)}%`
: `-${Math.abs(percentChange).toFixed(0)}%`}
{percentChange >= 0 ? (
<FaArrowTrendUp className="inline ms-2 text-green-dark text-sm" />
) : (
<FaArrowTrendDown className="inline ms-2 text-red-dark text-sm" />
<div className="text-xs lg:text-sm text-right flex items-center justify-end mr-1">
{percentChange === 0 && (
<span className="flex items-center text-grey-700">
<span className="inline mr-1 font-bold">-</span>
{` 0%`}
</span>
)}
{percentChange > 0 && (
<span className="flex items-center text-green">
<FaArrowUp className="inline "></FaArrowUp>
{`${percentChange.toFixed(0)}%`}
</span>

)}
</div>
{percentChange < 0 && (
<span className="flex items-center text-red">
<FaArrowDown className="inline"></FaArrowDown>
{`${Math.abs(percentChange).toFixed(0)}%`}
</span>
)}
</div>
)}
</div>

{/* Year comparison at bottom */}
<div className="text-sm text-left mt-auto text-gray-700 w-full">
{recentYear}
{priorYear ? ` vs. ${priorYear}` : ""}
{/* Year comparison at bottom */}
<div className="text-xs lg:text-sm text-left ml-1 text-grey-600 w-full">
{recentYear}
{priorYear ? ` vs. ${priorYear}` : ""}
</div>
</div>
</div>
);
}
},
);

export default KPICard;
Loading