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 { createSignal, onMount } from "solid-js";
import Table from "../components/Table"; import Table from "../components/Table";
import { Histori } from "../types/Histori"; import { Histori, PerubahanKomposisi } from "../types/Histori";
import supabase from "../utils/supabase"; import supabase from "../utils/supabase";
import { getDates } from "../utils/dates"; import { getDates } from "../utils/dates";
import TrashIcon from "../icons/TrashIcon"; import TrashIcon from "../icons/TrashIcon";
import { KondisiTapai } from "../types/KondisiTapai"; import { KondisiTapai } from "../types/KondisiTapai";
import ClockIcon from "../icons/ClockIcon"; import ClockIcon from "../icons/ClockIcon";
import ChartBarIcon from "../icons/ChartBarIcon";
import { Chart, registerables } from "chart.js";
export default function () { export default function () {
let canvas: any;
const [items, setItems] = createSignal<Histori[]>([]); const [items, setItems] = createSignal<Histori[]>([]);
const [dataPengujianAwal, setDataPengujianAwal] = const [dataPengujianAwal, setDataPengujianAwal] =
createSignal<KondisiTapai>(); createSignal<KondisiTapai>();
const [showDetail, setShowDetail] = createSignal<boolean>(false);
const [dataKomposisi, setDataKomposisi] =
createSignal<PerubahanKomposisi[]>();
const [chartDetail, setChartDetail] = createSignal<any>();
const getData = async () => { const getData = async () => {
const { data } = await supabase const { data } = await supabase
@ -30,7 +37,7 @@ export default function () {
}; };
const deleteHistory = async (id: any) => { const deleteHistory = async (id: any) => {
const isOk = confirm("Anda yakin menghapus history?"); const isOk = confirm("Anda yakin menghapus histori terpilih?");
if (isOk) { if (isOk) {
await supabase.from("histori_fermentasi").delete().eq("id", id); 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 () => { onMount(async () => {
await getData(); await getData();
Chart.register(...registerables);
}); });
return ( return (
<div class="space-y-5"> <>
<div class="bg-white rounded p-5 shadow"> <div class="space-y-5">
<div class="text-xl">Histori</div> <div class="bg-white rounded p-5 shadow">
<p class="text-sm"> <div class="text-xl">Histori</div>
Menampilkan hasil fermentasi yang telah dilakukan. <p class="text-sm">
</p> Menampilkan hasil fermentasi yang telah dilakukan.
<div class="flex text-sm items-center mt-5"> </p>
<ClockIcon class="text-blue-500 w-6 h-6 mr-1" /> <div class="flex text-sm items-center mt-5">
<div>: Proses sedang berlangsung</div> <ClockIcon class="text-blue-500 w-6 h-6 mr-1" />
</div> <div>: Proses sedang berlangsung</div>
<Table </div>
headers={[ <Table
"Tanggal", headers={[
"Lama Fermentasi", "",
"Rentang Suhu (C)", "Tanggal",
"Status", "Lama Fermentasi",
"Opsi", "Rentang Suhu (C)",
]} "Status",
items={items().map((item) => [ "",
getDates(item.created_at), ]}
Math.round((item.waktu_akhir - item.waktu_awal) / 3600) + " Jam", items={items().map((item) => {
item.rentang_suhu, let sedangBerlangsung: boolean = false;
<span if (
class={ !!dataPengujianAwal() &&
"uppercase " + dataPengujianAwal()!.created_time <= item.waktu_akhir
(item.berhasil ? "text-green-500" : "text-red-500") ) {
sedangBerlangsung = true;
} }
>
{item.berhasil ? "SUKSES" : "GAGAL"} return [
</span>, sedangBerlangsung ? (
!!dataPengujianAwal() && <div class="text-center">
dataPengujianAwal()!.created_time <= item.waktu_akhir ? ( <ClockIcon
<ClockIcon class="text-blue-500 w-6 h-6" /> class="text-blue-500 h-6 w-6 inline animate-spin"
) : ( style={{ "animation-duration": "2s" }}
<button />
type="button" </div>
class="text-orange-500" ) : (
onClick={() => deleteHistory(item.id)} ""
> ),
<TrashIcon /> getDates(item.created_at),
</button> Math.round((item.waktu_akhir - item.waktu_awal) / 3600) +
), " Jam",
])} item.rentang_suhu,
class="my-5" <span
></Table> 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>
<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, display: true,
title: { title: {
display: true, display: true,
text: "Nilai", text: "Kadar Gas Alkohol",
}, },
min: 0, min: 0,
max: 10, max: 10,

View File

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