mirror of
https://github.com/Sosokker/HomieCare.git
synced 2025-12-19 02:04:03 +01:00
Add action pie chart
This commit is contained in:
parent
68a26edcfc
commit
57617eff34
@ -1,9 +1,11 @@
|
|||||||
import { ApexOptions } from 'apexcharts';
|
import { ApexOptions } from 'apexcharts';
|
||||||
import React, { useState } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import ReactApexChart from 'react-apexcharts';
|
import ReactApexChart from 'react-apexcharts';
|
||||||
|
|
||||||
interface ChartThreeState {
|
interface ChartData {
|
||||||
series: number[];
|
action: string;
|
||||||
|
count: number;
|
||||||
|
percentage: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const options: ApexOptions = {
|
const options: ApexOptions = {
|
||||||
@ -12,7 +14,7 @@ const options: ApexOptions = {
|
|||||||
type: 'donut',
|
type: 'donut',
|
||||||
},
|
},
|
||||||
colors: ['#3C50E0', '#6577F3', '#8FD0EF', '#0FADCF'],
|
colors: ['#3C50E0', '#6577F3', '#8FD0EF', '#0FADCF'],
|
||||||
labels: ['Desktop', 'Tablet', 'Mobile', 'Unknown'],
|
labels: ['Sitting', 'Walking', 'Standing', 'Unknown'],
|
||||||
legend: {
|
legend: {
|
||||||
show: false,
|
show: false,
|
||||||
position: 'bottom',
|
position: 'bottom',
|
||||||
@ -50,111 +52,67 @@ const options: ApexOptions = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const PieChart: React.FC = () => {
|
const PieChart: React.FC = () => {
|
||||||
const [state, setState] = useState<ChartThreeState>({
|
const [chartData, setChartData] = useState<ChartData[]>([]);
|
||||||
series: [65, 34, 12, 56],
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const fetchData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch('http://127.0.0.1:8000/api/v1/action/week');
|
||||||
|
const data: ActionData[] = await response.json();
|
||||||
|
|
||||||
|
const actionCounts: { [key: string]: number } = {};
|
||||||
|
data.forEach((item) => {
|
||||||
|
actionCounts[item.action] = (actionCounts[item.action] || 0) + 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleReset = () => {
|
const totalCount = data.length;
|
||||||
setState((prevState) => ({
|
const chartData = Object.keys(actionCounts).map((action) => ({
|
||||||
...prevState,
|
action,
|
||||||
series: [65, 34, 12, 56],
|
count: actionCounts[action],
|
||||||
|
percentage: (actionCounts[action] / totalCount) * 100,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
setChartData(chartData);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching data:', error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
handleReset;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="sm:px-7.5 col-span-12 rounded-sm border border-stroke bg-white px-5 pb-5 pt-7.5 shadow-default dark:border-strokedark dark:bg-boxdark xl:col-span-5">
|
<div className="sm:px-7.5 col-span-12 rounded-sm border border-stroke bg-white px-5 pb-5 pt-7.5 shadow-default dark:border-strokedark dark:bg-boxdark xl:col-span-5">
|
||||||
<div className="mb-3 justify-between gap-4 sm:flex">
|
<div className="mb-3 justify-between gap-4 sm:flex">
|
||||||
<div>
|
<div>
|
||||||
<h5 className="text-xl font-semibold text-black dark:text-white">
|
<h5 className="text-xl font-semibold text-black dark:text-white">
|
||||||
Visitors Analytics
|
Action Analysis
|
||||||
</h5>
|
</h5>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<div className="relative z-20 inline-block">
|
|
||||||
<select
|
|
||||||
name=""
|
|
||||||
id=""
|
|
||||||
className="relative z-20 inline-flex appearance-none bg-transparent py-1 pl-3 pr-8 text-sm font-medium outline-none"
|
|
||||||
>
|
|
||||||
<option value="" className="dark:bg-boxdark">
|
|
||||||
Monthly
|
|
||||||
</option>
|
|
||||||
<option value="" className="dark:bg-boxdark">
|
|
||||||
Yearly
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
<span className="absolute right-3 top-1/2 z-10 -translate-y-1/2">
|
|
||||||
<svg
|
|
||||||
width="10"
|
|
||||||
height="6"
|
|
||||||
viewBox="0 0 10 6"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M0.47072 1.08816C0.47072 1.02932 0.500141 0.955772 0.54427 0.911642C0.647241 0.808672 0.809051 0.808672 0.912022 0.896932L4.85431 4.60386C4.92785 4.67741 5.06025 4.67741 5.14851 4.60386L9.09079 0.896932C9.19376 0.793962 9.35557 0.808672 9.45854 0.911642C9.56151 1.01461 9.5468 1.17642 9.44383 1.27939L5.50155 4.98632C5.22206 5.23639 4.78076 5.23639 4.51598 4.98632L0.558981 1.27939C0.50014 1.22055 0.47072 1.16171 0.47072 1.08816Z"
|
|
||||||
fill="#637381"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
fillRule="evenodd"
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M1.22659 0.546578L5.00141 4.09604L8.76422 0.557869C9.08459 0.244537 9.54201 0.329403 9.79139 0.578788C10.112 0.899434 10.0277 1.36122 9.77668 1.61224L9.76644 1.62248L5.81552 5.33722C5.36257 5.74249 4.6445 5.7544 4.19352 5.32924C4.19327 5.32901 4.19377 5.32948 4.19352 5.32924L0.225953 1.61241C0.102762 1.48922 -4.20186e-08 1.31674 -3.20269e-08 1.08816C-2.40601e-08 0.905899 0.0780105 0.712197 0.211421 0.578787C0.494701 0.295506 0.935574 0.297138 1.21836 0.539529L1.22659 0.546578ZM4.51598 4.98632C4.78076 5.23639 5.22206 5.23639 5.50155 4.98632L9.44383 1.27939C9.5468 1.17642 9.56151 1.01461 9.45854 0.911642C9.35557 0.808672 9.19376 0.793962 9.09079 0.896932L5.14851 4.60386C5.06025 4.67741 4.92785 4.67741 4.85431 4.60386L0.912022 0.896932C0.809051 0.808672 0.647241 0.808672 0.54427 0.911642C0.500141 0.955772 0.47072 1.02932 0.47072 1.08816C0.47072 1.16171 0.50014 1.22055 0.558981 1.27939L4.51598 4.98632Z"
|
|
||||||
fill="#637381"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mb-2">
|
<div className="mb-2">
|
||||||
<div id="chartThree" className="mx-auto flex justify-center">
|
<div id="chartThree" className="mx-auto flex justify-center">
|
||||||
<ReactApexChart
|
<ReactApexChart
|
||||||
options={options}
|
options={options}
|
||||||
series={state.series}
|
series={chartData.map((item) => item.count)}
|
||||||
type="donut"
|
type="donut"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="-mx-8 flex flex-wrap items-center justify-center gap-y-3">
|
<div className="-mx-8 flex flex-wrap items-center justify-center gap-y-3">
|
||||||
<div className="sm:w-1/2 w-full px-8">
|
{chartData.map((item, index) => (
|
||||||
|
<div key={index} className="sm:w-1/2 w-full px-8">
|
||||||
<div className="flex w-full items-center">
|
<div className="flex w-full items-center">
|
||||||
<span className="mr-2 block h-3 w-full max-w-3 rounded-full bg-primary"></span>
|
<span className="mr-2 block h-3 w-full max-w-3 rounded-full bg-primary"></span>
|
||||||
<p className="flex w-full justify-between text-sm font-medium text-black dark:text-white">
|
<p className="flex w-full justify-between text-sm font-medium text-black dark:text-white">
|
||||||
<span> Desktop </span>
|
<span>{item.action}</span>
|
||||||
<span> 65% </span>
|
<span>{item.count} times</span>
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="sm:w-1/2 w-full px-8">
|
|
||||||
<div className="flex w-full items-center">
|
|
||||||
<span className="mr-2 block h-3 w-full max-w-3 rounded-full bg-[#6577F3]"></span>
|
|
||||||
<p className="flex w-full justify-between text-sm font-medium text-black dark:text-white">
|
|
||||||
<span> Tablet </span>
|
|
||||||
<span> 34% </span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="sm:w-1/2 w-full px-8">
|
|
||||||
<div className="flex w-full items-center">
|
|
||||||
<span className="mr-2 block h-3 w-full max-w-3 rounded-full bg-[#8FD0EF]"></span>
|
|
||||||
<p className="flex w-full justify-between text-sm font-medium text-black dark:text-white">
|
|
||||||
<span> Mobile </span>
|
|
||||||
<span> 45% </span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="sm:w-1/2 w-full px-8">
|
|
||||||
<div className="flex w-full items-center">
|
|
||||||
<span className="mr-2 block h-3 w-full max-w-3 rounded-full bg-[#0FADCF]"></span>
|
|
||||||
<p className="flex w-full justify-between text-sm font-medium text-black dark:text-white">
|
|
||||||
<span> Unknown </span>
|
|
||||||
<span> 12% </span>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
4
frontend/src/types/action.ts
Normal file
4
frontend/src/types/action.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
interface ActionData {
|
||||||
|
timestamp: string;
|
||||||
|
action: string;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user