Bintang Fajar Julio
update
3f19b74
raw
history blame
No virus
18.5 kB
{% extends 'dashboard/base.html' %} {% block title %}Klasifikasi{% endblock
title %} {% block content %}
<h1 class="app-page-title">Klasifikasi</h1>
<hr class="my-4" />
<div class="row g-4 settings-section">
<div class="col-12">
<h3 class="section-title">Kelas</h3>
<div class="section-intro">
Terdapat
<span class="text-unmuted">4 kelompok bidang keahlian </span> sebagai
kelas klasifikasi.
</div>
</div>
<div class="col-12 col-lg-6">
<div
class="app-card app-card-basic d-flex flex-column align-items-start shadow-sm"
>
<div class="app-card-header p-3 border-bottom-0">
<div class="row align-items-center gx-3">
<div class="col-auto">
<div class="app-icon-holder">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-code-square"
viewBox="0 0 16 16"
>
<path
d="M14 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z"
/>
<path
d="M6.854 4.646a.5.5 0 0 1 0 .708L4.207 8l2.647 2.646a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708l3-3a.5.5 0 0 1 .708 0m2.292 0a.5.5 0 0 0 0 .708L11.793 8l-2.647 2.646a.5.5 0 0 0 .708.708l3-3a.5.5 0 0 0 0-.708l-3-3a.5.5 0 0 0-.708 0"
/>
</svg>
</div>
<!--//icon-holder-->
</div>
<!--//col-->
<div class="col-auto">
<h4 class="app-card-title">Rekayasa Perangkat Lunak</h4>
</div>
<!--//col-->
</div>
<!--//row-->
</div>
</div>
<!--//app-card-->
</div>
<div class="col-12 col-lg-6">
<div
class="app-card app-card-basic d-flex flex-column align-items-start shadow-sm"
>
<div class="app-card-header p-3 border-bottom-0">
<div class="row align-items-center gx-3">
<div class="col-auto">
<div class="app-icon-holder">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-robot"
viewBox="0 0 16 16"
>
<path
d="M6 12.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5M3 8.062C3 6.76 4.235 5.765 5.53 5.886a26.6 26.6 0 0 0 4.94 0C11.765 5.765 13 6.76 13 8.062v1.157a.93.93 0 0 1-.765.935c-.845.147-2.34.346-4.235.346s-3.39-.2-4.235-.346A.93.93 0 0 1 3 9.219zm4.542-.827a.25.25 0 0 0-.217.068l-.92.9a25 25 0 0 1-1.871-.183.25.25 0 0 0-.068.495c.55.076 1.232.149 2.02.193a.25.25 0 0 0 .189-.071l.754-.736.847 1.71a.25.25 0 0 0 .404.062l.932-.97a25 25 0 0 0 1.922-.188.25.25 0 0 0-.068-.495c-.538.074-1.207.145-1.98.189a.25.25 0 0 0-.166.076l-.754.785-.842-1.7a.25.25 0 0 0-.182-.135"
/>
<path
d="M8.5 1.866a1 1 0 1 0-1 0V3h-2A4.5 4.5 0 0 0 1 7.5V8a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1v1a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-1a1 1 0 0 0 1-1V9a1 1 0 0 0-1-1v-.5A4.5 4.5 0 0 0 10.5 3h-2zM14 7.5V13a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7.5A3.5 3.5 0 0 1 5.5 4h5A3.5 3.5 0 0 1 14 7.5"
/>
</svg>
</div>
<!--//icon-holder-->
</div>
<!--//col-->
<div class="col-auto">
<h4 class="app-card-title">Sistem Cerdas</h4>
</div>
<!--//col-->
</div>
<!--//row-->
</div>
</div>
<!--//app-card-->
</div>
<div class="col-12 col-lg-6">
<div
class="app-card app-card-basic d-flex flex-column align-items-start shadow-sm"
>
<div class="app-card-header p-3 border-bottom-0">
<div class="row align-items-center gx-3">
<div class="col-auto">
<div class="app-icon-holder">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-router"
viewBox="0 0 16 16"
>
<path
d="M5.525 3.025a3.5 3.5 0 0 1 4.95 0 .5.5 0 1 0 .707-.707 4.5 4.5 0 0 0-6.364 0 .5.5 0 0 0 .707.707"
/>
<path
d="M6.94 4.44a1.5 1.5 0 0 1 2.12 0 .5.5 0 0 0 .708-.708 2.5 2.5 0 0 0-3.536 0 .5.5 0 0 0 .707.707ZM2.5 11a.5.5 0 1 1 0-1 .5.5 0 0 1 0 1m4.5-.5a.5.5 0 1 0 1 0 .5.5 0 0 0-1 0m2.5.5a.5.5 0 1 1 0-1 .5.5 0 0 1 0 1m1.5-.5a.5.5 0 1 0 1 0 .5.5 0 0 0-1 0m2 0a.5.5 0 1 0 1 0 .5.5 0 0 0-1 0"
/>
<path
d="M2.974 2.342a.5.5 0 1 0-.948.316L3.806 8H1.5A1.5 1.5 0 0 0 0 9.5v2A1.5 1.5 0 0 0 1.5 13H2a.5.5 0 0 0 .5.5h2A.5.5 0 0 0 5 13h6a.5.5 0 0 0 .5.5h2a.5.5 0 0 0 .5-.5h.5a1.5 1.5 0 0 0 1.5-1.5v-2A1.5 1.5 0 0 0 14.5 8h-2.306l1.78-5.342a.5.5 0 1 0-.948-.316L11.14 8H4.86zM14.5 9a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.5.5h-13a.5.5 0 0 1-.5-.5v-2a.5.5 0 0 1 .5-.5z"
/>
<path d="M8.5 5.5a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0" />
</svg>
</div>
<!--//icon-holder-->
</div>
<!--//col-->
<div class="col-auto">
<h4 class="app-card-title">Jaringan & IoT</h4>
</div>
<!--//col-->
</div>
<!--//row-->
</div>
</div>
<!--//app-card-->
</div>
<div class="col-12 col-lg-6">
<div
class="app-card app-card-basic d-flex flex-column align-items-start shadow-sm"
>
<div class="app-card-header p-3 border-bottom-0">
<div class="row align-items-center gx-3">
<div class="col-auto">
<div class="app-icon-holder">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-easel2"
viewBox="0 0 16 16"
>
<path
fill-rule="evenodd"
d="M8 0a.5.5 0 0 1 .447.276L8.81 1h4.69A1.5 1.5 0 0 1 15 2.5V11h.5a.5.5 0 0 1 0 1h-2.86l.845 3.379a.5.5 0 0 1-.97.242L12.11 14H3.89l-.405 1.621a.5.5 0 0 1-.97-.242L3.36 12H.5a.5.5 0 0 1 0-1H1V2.5A1.5 1.5 0 0 1 2.5 1h4.691l.362-.724A.5.5 0 0 1 8 0M2 11h12V2.5a.5.5 0 0 0-.5-.5h-11a.5.5 0 0 0-.5.5zm9.61 1H4.39l-.25 1h7.72z"
/>
</svg>
</div>
<!--//icon-holder-->
</div>
<!--//col-->
<div class="col-auto">
<h4 class="app-card-title">Multimedia & Teknologi: AI Game</h4>
</div>
<!--//col-->
</div>
<!--//row-->
</div>
</div>
<!--//app-card-->
</div>
</div>
<hr class="my-4" />
<div class="row g-4 settings-section">
<div class="col-12">
<h3 class="section-title">Data</h3>
<div class="section-intro">
Masukkan <span class="text-unmuted">abstrak dan kata kunci</span> Anda
sebagai data untuk diklasifikasikan.
</div>
</div>
<div class="col-12">
<div class="app-card app-card-settings shadow-sm p-4">
<div class="app-card-body">
<form method="post" id="inference">
<div class="mb-3">
<div class="d-flex justify-content-between">
<label for="abstrak" class="form-label">Abstrak</label>
<div id="wordCounter">0/350</div>
</div>
<textarea
id="abstrak"
class="form-control"
placeholder="Masukkan abstrak"
style="height: 160px"
required
></textarea>
</div>
<div class="mb-5">
<label for="keywordInput" class="form-label">Kata Kunci</label>
<div class="d-flex">
<input
type="text"
class="form-control"
id="keywordInput"
placeholder="Masukkan kata kunci"
style="width: 200px"
/>
<button
class="btn app-btn-secondary ms-2"
href=""
id="addKeywordBtn"
type="button"
>
Tambah
</button>
</div>
<div class="mt-2" id="keywordContainer"></div>
</div>
<div class="row justify-content-between">
<div class="col-auto">
<button
class="btn app-btn-secondary"
type="button"
id="bersihkanBtn"
>
Reset
</button>
</div>
<div class="col-auto">
<button class="btn app-btn-primary" type="submit">
Klasifikasi
</button>
</div>
</div>
</form>
</div>
<!--//app-card-body-->
</div>
<!--//app-card-->
</div>
</div>
<hr class="my-4" />
<div class="row g-3 settings-section justify-content-center d-none" id="hasil">
<div class="col-12">
<h3 class="section-title">Hasil</h3>
</div>
<div class="col-12 col-lg-6">
<div class="app-card app-card-stats-table h-100 shadow-sm">
<div class="app-card-header p-3">
<div class="row justify-content-between align-items-center">
<div class="col-auto">
<h4 class="app-card-title">Skor Klasifikasi</h4>
</div>
</div>
<!--//row-->
</div>
<!--//app-card-header-->
<div class="app-card-body p-3 p-lg-4">
<div class="table-responsive">
<table class="table table-borderless mb-0">
<thead>
<tr>
<th class="meta">Kelas</th>
<th class="meta stat-cell">Skor</th>
</tr>
</thead>
<tbody id="statsResult"></tbody>
</table>
</div>
<!--//table-responsive-->
</div>
<!--//app-card-body-->
</div>
<!--//app-card-->
</div>
<div class="col-12 mt-5 text-center">
<h3 class="section-title">
Dosen Kelompok Bidang Keahlian<br /><span
id="kbk"
style="color: #128c9b"
></span>
</h3>
</div>
<div class="row justify-content-center gy-2" id="lecturers"></div>
<div class="col-12 mt-5 text-center mb-3">
<h3 class="section-title">
Dosen dengan
<span style="color: #128c9b">Riwayat Bimbingan Termirip</span>
</h3>
</div>
<div class="container-xl" id="similarity-results"></div>
</div>
{% endblock content %} {% block script %}
<script>
let keywords = [];
$("#abstrak").on("input", function () {
let text = $(this).val().trim();
let words = text.split(/\s+/).filter((word) => word.length > 0);
let wordCount = words.length;
if (wordCount >= 350) {
let trimmedWords = words.slice(0, 350);
$(this).val(trimmedWords.join(" "));
wordCount = 350;
$("#wordCounter").css("color", "red");
} else {
$("#wordCounter").css("color", "inherit");
}
$("#wordCounter").text(`${wordCount}/350`);
});
$("#addKeywordBtn").on("click", function (event) {
if (keywords.length == 5) {
alertMessage(
"Maksimal 5 kata kunci",
"Tidak dapat menambahkan kata kunci",
"info"
);
return;
}
let keyword = $("#keywordInput").val().trim();
if (keyword) {
let badge = $(
`<span class="badge px-2 me-2" style="border: 1px solid #128c9b; color: #128c9b">${keyword}<svg class="close-badge ms-1" xmlns="http://www.w3.org/2000/svg" width="16" height="13" fill="currentColor" class="bi bi-x" viewBox="0 0 16 16">
<path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708"/>
</svg></span>`
);
$("#keywordContainer").append(badge);
keywords.push(keyword);
$("#keywordInput").val("");
}
});
$(document).on("click", ".close-badge", function () {
let removedKeyword = $(this).closest(".badge").text().trim();
$(this).closest(".badge").remove();
keywords = keywords.filter((word) => word !== removedKeyword);
});
$("#bersihkanBtn").on("click", function () {
$("#abstrak").val("");
$("#keywordInput").val("");
$("#wordCounter").text("0/350").css("color", "inherit");
$("#keywordContainer").empty();
$("#hasil").addClass("d-none");
keywords = [];
});
$("#inference").on("submit", function (e) {
e.preventDefault();
if ($("#abstrak").val().trim() == "") {
alertMessage(
"Abstrak Harus Diisi",
"Tidak dapat melakukan klasifikasi",
"error"
);
return;
}
if (keywords.length == 0) {
alertMessage(
"Minimal 1 Kata Kunci",
"Tidak dapat melakukan klasifikasi",
"error"
);
return;
}
$(".spinner").removeClass("d-none");
$(".overlay").removeClass("d-none");
$.ajax({
type: "POST",
url: '{{ url_for("classifier.inference") }}',
contentType: "application/json",
data: JSON.stringify({
abstrak: $("#abstrak").val(),
kata_kunci: keywords.join(", "),
}),
xhrFields: {
withCredentials: true,
},
success: function (response) {
$("#statsResult").empty();
probs = response["message"]["probs"];
const classificationResult = Object.entries(probs)
.sort((x, y) => x[1] - y[1])
.reverse();
let isFirstRow = true;
classificationResult.forEach(([key, value]) => {
$("#statsResult").append(
`<tr>
<td>${key}</td>
<td class="stat-cell${
isFirstRow ? " fw-bold" : ""
}" style="color: #128c9b">${value}%</td>
</tr>`
);
isFirstRow = false;
});
$("#kbk").text(response["message"]["kbk"]);
$("#lecturers").empty();
$.each(response["message"]["lecturers"], function (index, lecturer) {
$("#lecturers").append(
`<div class="col-6 col-md-3">
<div class="app-card app-card-doc shadow-sm h-100">
<div class="app-card-thumb-holder p-3 d-flex justify-content-center">
<div
style="
width: 95px;
height: 95px;
overflow: hidden;
border-radius: 50%;
border: 2px solid white;
"
>
<img src="${lecturer.foto}" style="width: 100%; height: 100%; object-fit: cover" />
</div>
</div>
<div class="app-card-body p-3 has-card-actions">
<h4 class="app-doc-title truncate mb-0">
<a href="#">${lecturer.nama}</a>
</h4>
<div class="app-doc-meta">
<ul class="list-unstyled mb-0">
<li>
Kelompok Bidang Keahlian:
<span class="text-unmuted">${lecturer.kelompok_bidang_keahlian}</span>
</li>
</ul>
</div>
</div>
</div>
</div>`
);
});
$("#similarity-results").empty();
var topSimilarity = response["message"]["top_similarity"];
for (var index = 0; index < topSimilarity.length; index++) {
$("#similarity-results").append(
`<div class="app-card app-card-notification shadow-sm mb-4">
<div class="app-card-header px-4 py-3">
<div class="row g-3 align-items-center">
<div class="col-12 col-lg-auto text-start">
<div class="notification-type mb-3">
<span class="badge" style="background-color: #128c9b"
>Rank #${topSimilarity[index]["rank"]}</span
>
</div>
<h4 class="notification-title mb-1">${
topSimilarity[index]["supervisor"]
}</h4>
<ul class="notification-meta list-inline mb-0">
<li class="list-inline-item fw-bold">
Skor Kemiripan: <span style="color: #128c9b">${
topSimilarity[index]["similarity_score"]
}%</span>
</li>
${
topSimilarity[index]["similarity_score"] > 80
? `<li class="fw-bold" style="color: red;">Tingkat Kemiripan Sangat Tinggi</li>`
: ``
}
</ul>
</div>
</div>
</div>
<div class="app-card-body p-4">
<div class="notification-content mb-4">
<b>Judul</b><br />${topSimilarity[index]["title"]}
</div>
<div class="notification-content mb-4">
<b>Abstrak</b><br />${topSimilarity[index]["abstract"]}
</div>
<div class="notification-content">
<b>Kata Kunci</b><br />${topSimilarity[index]["keywords"]}
</div>
</div>
<div class="app-card-footer px-4 py-3">
<a class="action-link" href="${topSimilarity[index]["url"]}"
>${topSimilarity[index]["url"]}</a>
</div>
</div>`
);
}
$("#hasil").removeClass("d-none");
$("html, body").animate(
{
scrollTop: $("#hasil").offset().top - 50,
},
700
);
$(".spinner").addClass("d-none");
$(".overlay").addClass("d-none");
},
error: function (response) {
$(".spinner").addClass("d-none");
$(".overlay").addClass("d-none");
alertMessage("Klasifikasi Gagal", "Terjadi kesalahan server", "error");
},
});
});
</script>
{% endblock script %}