270 lines
9.8 KiB
Dart
270 lines
9.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:skripsi/config/theme.dart';
|
|
import 'package:skripsi/controller/cPerhitunganKNN.dart';
|
|
import 'package:skripsi/controller/cTambahDataTesting.dart';
|
|
import 'package:skripsi/controller/cUser.dart';
|
|
import 'package:skripsi/view/home_page.dart';
|
|
|
|
class TmbhDataTesting extends StatefulWidget {
|
|
const TmbhDataTesting({super.key});
|
|
|
|
@override
|
|
State<TmbhDataTesting> createState() => _TmbhDataTestingState();
|
|
}
|
|
|
|
class _TmbhDataTestingState extends State<TmbhDataTesting> {
|
|
final cTambahDataTesting = Get.put(CTambahDataTesting());
|
|
final cUser = Get.put(CUser());
|
|
|
|
List<List<double>> features = [];
|
|
|
|
List<String> labels = [];
|
|
|
|
getData() async {
|
|
await cTambahDataTesting.getDataTrainingForTesting();
|
|
final listData = cTambahDataTesting.listTambahDataTesting;
|
|
labels = listData.map((e) => e.status ?? '').toList();
|
|
features = listData
|
|
.map((e) => [
|
|
double.parse(e.jumlahKejahatan ?? '0'),
|
|
double.parse(e.jarakTkpPolres ?? '0')
|
|
])
|
|
.toList();
|
|
}
|
|
|
|
String result = '';
|
|
List<String> nearestNeighbors = [];
|
|
List<Map<String, dynamic>> distances = [];
|
|
|
|
final tkpController = TextEditingController();
|
|
final jumlahKejahatanController = TextEditingController();
|
|
final jarakTkpPolresController = TextEditingController();
|
|
final kController = TextEditingController();
|
|
|
|
classify() async {
|
|
if (tkpController.text.isEmpty) {
|
|
Get.snackbar("Error", "Masukkan TKP", backgroundColor: Colors.red);
|
|
} else if (jumlahKejahatanController.text.isEmpty) {
|
|
Get.snackbar("Error", "Masukkan Jumlah Kejahatan",
|
|
backgroundColor: Colors.red);
|
|
} else if (jarakTkpPolresController.text.isEmpty) {
|
|
Get.snackbar("Error", "Masukkan Jarak TKP - Polres Terdekat",
|
|
backgroundColor: Colors.red);
|
|
} else if (kController.text.isEmpty) {
|
|
Get.snackbar("Error", "Masukkan Nilai K", backgroundColor: Colors.red);
|
|
} else {
|
|
double suhu = double.tryParse(jumlahKejahatanController.text) ?? 0.0;
|
|
double kelembapan = double.tryParse(jarakTkpPolresController.text) ?? 0.0;
|
|
int k = int.tryParse(kController.text) ?? 1;
|
|
|
|
List<double> newPoint = [suhu, kelembapan];
|
|
PerhitunganKNN perhitunganKNN = PerhitunganKNN(features, labels);
|
|
Map<String, dynamic> classificationResult =
|
|
perhitunganKNN.classify(newPoint, k);
|
|
setState(() {
|
|
result = classificationResult['result'];
|
|
nearestNeighbors = classificationResult['nearestNeighbors'];
|
|
distances = classificationResult['distances'];
|
|
});
|
|
}
|
|
}
|
|
|
|
postDataHasilTesting() async {
|
|
if (tkpController.text.isEmpty) {
|
|
Get.snackbar("Error", "Masukkan TKP", backgroundColor: Colors.red);
|
|
} else if (jumlahKejahatanController.text.isEmpty) {
|
|
Get.snackbar("Error", "Masukkan Jumlah Kejahatan",
|
|
backgroundColor: Colors.red);
|
|
} else if (jarakTkpPolresController.text.isEmpty) {
|
|
Get.snackbar("Error", "Masukkan Jarak TKP - Polres Terdekat",
|
|
backgroundColor: Colors.red);
|
|
} else {
|
|
await cTambahDataTesting.postDataTesting(
|
|
cUser.data.idUser ?? "",
|
|
tkpController.text,
|
|
jumlahKejahatanController.text,
|
|
jarakTkpPolresController.text,
|
|
result);
|
|
if (cTambahDataTesting.success) {
|
|
Get.snackbar("Success", 'Data Berhasil Ditambahkan',
|
|
backgroundColor: Colors.green);
|
|
Get.offAll(const HomePage());
|
|
} else {
|
|
Get.snackbar("Error", 'Data Gagal Ditambahkan',
|
|
backgroundColor: Colors.red);
|
|
}
|
|
}
|
|
}
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
getData();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
resizeToAvoidBottomInset: false,
|
|
backgroundColor: whiteColor,
|
|
appBar: AppBar(
|
|
elevation: 0,
|
|
backgroundColor: whiteColor,
|
|
leadingWidth: 70.w,
|
|
leading: TextButton(
|
|
onPressed: () {
|
|
Navigator.pop(context);
|
|
},
|
|
child: Text('Batal', style: robotoSedangHitam),
|
|
),
|
|
centerTitle: true,
|
|
title: Text('Tambah Kasus Testing', style: robotoSedangHitam),
|
|
),
|
|
body: GetBuilder<CTambahDataTesting>(builder: (_) {
|
|
if (_.loading) {
|
|
return const Center(
|
|
child: CircularProgressIndicator(),
|
|
);
|
|
}
|
|
return SingleChildScrollView(
|
|
child: Padding(
|
|
padding: EdgeInsets.all(8.w),
|
|
child: Column(
|
|
children: [
|
|
TextFormField(
|
|
keyboardType: TextInputType.emailAddress,
|
|
controller: tkpController,
|
|
autofocus: true,
|
|
decoration: InputDecoration(
|
|
labelText: 'TKP',
|
|
labelStyle: robotoSedangHitam.copyWith(
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
hintText: 'Masukkan TKP',
|
|
enabledBorder: const UnderlineInputBorder(
|
|
borderSide: BorderSide(
|
|
color: Color(0xffC6C6C6),
|
|
),
|
|
),
|
|
focusedBorder: const UnderlineInputBorder(
|
|
borderSide: BorderSide(
|
|
color: Color(0xffC6C6C6),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
SizedBox(height: 20.h),
|
|
TextFormField(
|
|
controller: jumlahKejahatanController,
|
|
keyboardType: TextInputType.number,
|
|
autofocus: true,
|
|
decoration: InputDecoration(
|
|
labelText: 'Jumlah Kejahatan',
|
|
labelStyle:
|
|
robotoSedangHitam.copyWith(fontWeight: FontWeight.bold),
|
|
hintText: 'Masukkan Jumlah Kejahatan',
|
|
enabledBorder: const UnderlineInputBorder(
|
|
borderSide: BorderSide(
|
|
color: Color(0xffC6C6C6),
|
|
),
|
|
),
|
|
focusedBorder: const UnderlineInputBorder(
|
|
borderSide: BorderSide(
|
|
color: Color(0xffC6C6C6),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
SizedBox(height: 20.h),
|
|
TextFormField(
|
|
keyboardType: TextInputType.number,
|
|
controller: jarakTkpPolresController,
|
|
autofocus: true,
|
|
decoration: InputDecoration(
|
|
labelText: 'Jarak TKP - Polres',
|
|
labelStyle:
|
|
robotoSedangHitam.copyWith(fontWeight: FontWeight.bold),
|
|
hintText: 'Masukkan Jarak TKP - Polres',
|
|
enabledBorder: const UnderlineInputBorder(
|
|
borderSide: BorderSide(
|
|
color: Color(0xffC6C6C6),
|
|
),
|
|
),
|
|
focusedBorder: const UnderlineInputBorder(
|
|
borderSide: BorderSide(
|
|
color: Color(0xffC6C6C6),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
SizedBox(height: 20.h),
|
|
TextFormField(
|
|
keyboardType: TextInputType.number,
|
|
controller: kController,
|
|
autofocus: true,
|
|
decoration: InputDecoration(
|
|
labelText: 'Masukkan Nilai K',
|
|
labelStyle:
|
|
robotoSedangHitam.copyWith(fontWeight: FontWeight.bold),
|
|
hintText: 'Masukkan Nilai K',
|
|
enabledBorder: const UnderlineInputBorder(
|
|
borderSide: BorderSide(
|
|
color: Color(0xffC6C6C6),
|
|
),
|
|
),
|
|
focusedBorder: const UnderlineInputBorder(
|
|
borderSide: BorderSide(
|
|
color: Color(0xffC6C6C6),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
SizedBox(height: 12.h),
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
ElevatedButton(
|
|
onPressed: () {
|
|
classify();
|
|
},
|
|
child: Text(
|
|
'Klasifikasi',
|
|
style: robotoSedangHitam.copyWith(
|
|
color: primaryColor, fontWeight: FontWeight.bold),
|
|
),
|
|
),
|
|
SizedBox(width: 16.w),
|
|
ElevatedButton(
|
|
onPressed: () {
|
|
postDataHasilTesting();
|
|
},
|
|
child: Text(
|
|
'Simpan',
|
|
style: robotoSedangHitam.copyWith(
|
|
color: primaryColor, fontWeight: FontWeight.bold),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
SizedBox(height: 12.h),
|
|
Text('Hasil Klasifkasi: $result'),
|
|
Text('K Tetangga Terdekat: $nearestNeighbors'),
|
|
if (distances.isNotEmpty) ...[
|
|
SizedBox(height: 12.h),
|
|
Text('Jarak newPoint ke setiap titik:',
|
|
style: robotoKecilHitam),
|
|
for (var distance in distances)
|
|
Text(
|
|
'Jarak ke titik ${distance['index']}: ${distance['distance'].toStringAsFixed(5)}')
|
|
]
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}),
|
|
);
|
|
}
|
|
}
|