display graph composition history

This commit is contained in:
Muhammad Izza Alfiansyah 2024-07-09 22:50:48 +07:00
parent f2220bb5db
commit 6fce5352f9
5 changed files with 240 additions and 48 deletions

View File

@ -0,0 +1,21 @@
import IconProps from "./type";
export default function (props: IconProps) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="h-6 w-6"
{...props}
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z"
/>
</svg>
);
}

View File

@ -0,0 +1,21 @@
import IconProps from "./type";
export default function (props: IconProps) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-6 h-6"
{...props}
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m5.231 13.481L15 17.25m-4.5-15H5.625c-.621 0-1.125.504-1.125 1.125v16.5c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Zm3.75 11.625a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z"
/>
</svg>
);
}

View File

@ -1,16 +1,23 @@
import { createSignal, onMount } from "solid-js";
import Table from "../components/Table";
import { Histori } from "../types/Histori";
import { Histori, PerubahanKomposisi } from "../types/Histori";
import supabase from "../utils/supabase";
import { getDates } from "../utils/dates";
import TrashIcon from "../icons/TrashIcon";
import { KondisiTapai } from "../types/KondisiTapai";
import ClockIcon from "../icons/ClockIcon";
import ChartBarIcon from "../icons/ChartBarIcon";
import { Chart, registerables } from "chart.js";
export default function () {
let canvas: any;
const [items, setItems] = createSignal<Histori[]>([]);
const [dataPengujianAwal, setDataPengujianAwal] =
createSignal<KondisiTapai>();
const [showDetail, setShowDetail] = createSignal<boolean>(false);
const [dataKomposisi, setDataKomposisi] =
createSignal<PerubahanKomposisi[]>();
const [chartDetail, setChartDetail] = createSignal<any>();
const getData = async () => {
const { data } = await supabase
@ -30,7 +37,7 @@ export default function () {
};
const deleteHistory = async (id: any) => {
const isOk = confirm("Anda yakin menghapus history?");
const isOk = confirm("Anda yakin menghapus histori terpilih?");
if (isOk) {
await supabase.from("histori_fermentasi").delete().eq("id", id);
@ -38,57 +45,194 @@ export default function () {
}
};
const renderChart = async (berhasil: boolean) => {
let labels: any[] = [];
let values: any[] = [];
dataKomposisi()?.forEach((item) => {
labels.push(item.jam_ke);
values.push(item.kadar_gas);
});
chartDetail()?.destroy();
const chart = new Chart(canvas, {
type: "line",
data: {
labels: labels,
datasets: [
{
label: "Kadar Gas",
data: values,
borderColor: berhasil ? "lightgreen" : "red",
cubicInterpolationMode: "monotone",
tension: 0.4,
},
],
},
options: {
responsive: true,
scales: {
x: {
display: true,
title: {
display: true,
},
},
y: {
display: true,
title: {
display: true,
text: "Kadar Gas Alkohol",
},
min: 0,
max: 10,
ticks: {
callback: (val) => {
return val + "%";
},
},
},
},
plugins: {
tooltip: {
callbacks: {
title(_) {
return "";
},
label(tooltipItem) {
return (
tooltipItem.dataset.label +
": " +
tooltipItem.parsed.y.toFixed(2) +
"%"
);
},
},
},
},
},
});
setChartDetail(chart);
};
onMount(async () => {
await getData();
Chart.register(...registerables);
});
return (
<div class="space-y-5">
<div class="bg-white rounded p-5 shadow">
<div class="text-xl">Histori</div>
<p class="text-sm">
Menampilkan hasil fermentasi yang telah dilakukan.
</p>
<div class="flex text-sm items-center mt-5">
<ClockIcon class="text-blue-500 w-6 h-6 mr-1" />
<div>: Proses sedang berlangsung</div>
</div>
<Table
headers={[
"Tanggal",
"Lama Fermentasi",
"Rentang Suhu (C)",
"Status",
"Opsi",
]}
items={items().map((item) => [
getDates(item.created_at),
Math.round((item.waktu_akhir - item.waktu_awal) / 3600) + " Jam",
item.rentang_suhu,
<span
class={
"uppercase " +
(item.berhasil ? "text-green-500" : "text-red-500")
<>
<div class="space-y-5">
<div class="bg-white rounded p-5 shadow">
<div class="text-xl">Histori</div>
<p class="text-sm">
Menampilkan hasil fermentasi yang telah dilakukan.
</p>
<div class="flex text-sm items-center mt-5">
<ClockIcon class="text-blue-500 w-6 h-6 mr-1" />
<div>: Proses sedang berlangsung</div>
</div>
<Table
headers={[
"",
"Tanggal",
"Lama Fermentasi",
"Rentang Suhu (C)",
"Status",
"",
]}
items={items().map((item) => {
let sedangBerlangsung: boolean = false;
if (
!!dataPengujianAwal() &&
dataPengujianAwal()!.created_time <= item.waktu_akhir
) {
sedangBerlangsung = true;
}
>
{item.berhasil ? "SUKSES" : "GAGAL"}
</span>,
!!dataPengujianAwal() &&
dataPengujianAwal()!.created_time <= item.waktu_akhir ? (
<ClockIcon class="text-blue-500 w-6 h-6" />
) : (
<button
type="button"
class="text-orange-500"
onClick={() => deleteHistory(item.id)}
>
<TrashIcon />
</button>
),
])}
class="my-5"
></Table>
return [
sedangBerlangsung ? (
<div class="text-center">
<ClockIcon
class="text-blue-500 h-6 w-6 inline animate-spin"
style={{ "animation-duration": "2s" }}
/>
</div>
) : (
""
),
getDates(item.created_at),
Math.round((item.waktu_akhir - item.waktu_awal) / 3600) +
" Jam",
item.rentang_suhu,
<span
class={
"uppercase " +
(item.berhasil ? "text-green-500" : "text-red-500")
}
>
{item.berhasil ? "SUKSES" : "GAGAL"}
</span>,
<div class="text-center">
<button
type="button"
class="text-blue-400"
onClick={() => {
setDataKomposisi(item.perubahan_komposisi);
renderChart(item.berhasil);
setShowDetail(true);
}}
>
<ChartBarIcon />
</button>
{sedangBerlangsung ? (
""
) : (
<button
type="button"
class="text-orange-500 ml-2"
onClick={() => deleteHistory(item.id)}
>
<TrashIcon />
</button>
)}
</div>,
];
})}
class="my-5"
></Table>
</div>
</div>
</div>
<div
class="bg-black bg-opacity-25 fixed top-0 left-0 right-0 bottom-0 z-[500] items-center justify-center p-5 hidden"
classList={{ "!flex": showDetail() }}
>
<div class="bg-white rounded shadow p-5 w-full lg:w-3/4">
<div class="text-xl">Detail Histori</div>
<div class="text-sm mb-5">
Menampilkan data perubahan kadar gas selama histori proses
fermentasi.
</div>
<canvas ref={canvas} style={{ "max-height": "400px" }}></canvas>
<div
class="text-sm text-center -mt-3"
style={{ "font-family": "Arial" }}
>
Jam Ke-
</div>
<div class="mt-8 flex space-x-3 justify-end">
<button
class="bg-gray-400 text-white px-5 py-2 uppercase rounded"
onClick={() => setShowDetail(false)}
>
TUTUP
</button>
</div>
</div>
</div>
</>
);
}

View File

@ -111,7 +111,7 @@ export default function () {
display: true,
title: {
display: true,
text: "Nilai",
text: "Kadar Gas Alkohol",
},
min: 0,
max: 10,

View File

@ -1,3 +1,8 @@
export type PerubahanKomposisi = {
kadar_gas: number;
jam_ke: number;
};
export interface Histori {
id: number;
waktu_awal: number;
@ -6,4 +11,5 @@ export interface Histori {
berhasil: boolean;
created_at: string;
selesai: boolean;
perubahan_komposisi: PerubahanKomposisi[];
}