Tugas Akhir E32210601
This commit is contained in:
commit
692f297461
|
@ -0,0 +1,263 @@
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <Wire.h>
|
||||||
|
#include "RTClib.h"
|
||||||
|
|
||||||
|
// INA226
|
||||||
|
#include <WiFi.h>
|
||||||
|
#include <HTTPClient.h>
|
||||||
|
#include <INA226_WE.h>
|
||||||
|
#define I2C_ADDRESS 0x40 //alamat I2C
|
||||||
|
|
||||||
|
// Config Wifi
|
||||||
|
const char *ssid = "KOSTR5"; //Nama Wifi
|
||||||
|
const char *password = "tanyapakjoko"; // pass wifi
|
||||||
|
INA226_WE ina226 = INA226_WE(I2C_ADDRESS);
|
||||||
|
|
||||||
|
//Global Variable
|
||||||
|
float shuntVoltage_mV = 0.0;
|
||||||
|
float loadVoltage_V = 0.0;
|
||||||
|
float busVoltage_V = 0.0;
|
||||||
|
float current_A = 0.0;
|
||||||
|
float power_mW = 0.0;
|
||||||
|
|
||||||
|
unsigned long previousMillis = 0; // variabel untuk menyimpan waktu terakhir pembaruan
|
||||||
|
const long interval = 10000; // interval waktu dalam milidetik
|
||||||
|
|
||||||
|
|
||||||
|
RTC_DS3231 rtc;
|
||||||
|
char daysOfTheWeek[7][12] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const int RELAY_1 = 33;
|
||||||
|
const int RELAY_2 = 25;
|
||||||
|
const int RELAY_5 = 32;
|
||||||
|
|
||||||
|
int LDR_PIN_1 = 34;
|
||||||
|
int LDR_PIN_2 = 35;
|
||||||
|
|
||||||
|
|
||||||
|
int ldrValue1;
|
||||||
|
int ldrValue2;
|
||||||
|
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
// put your setup code here, to run once:
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
Wire.begin();
|
||||||
|
ina226.init();
|
||||||
|
|
||||||
|
connectToWifi();
|
||||||
|
|
||||||
|
ina226.setResistorRange(0.075, 50.0); // choose resistor 5 mOhm and gain range up to 10 A
|
||||||
|
ina226.setCorrectionFactor(1.0);
|
||||||
|
if (!rtc.begin()) {
|
||||||
|
Serial.println("Couldn't find RTC");
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtc.adjust(DateTime(__DATE__, __TIME__));
|
||||||
|
|
||||||
|
pinMode(LDR_PIN_1, INPUT);
|
||||||
|
pinMode(LDR_PIN_2, INPUT);
|
||||||
|
|
||||||
|
pinMode(RELAY_1, OUTPUT);
|
||||||
|
pinMode(RELAY_2, OUTPUT);
|
||||||
|
pinMode(RELAY_5, OUTPUT);
|
||||||
|
|
||||||
|
digitalWrite(RELAY_1, HIGH);
|
||||||
|
digitalWrite(RELAY_2, HIGH);
|
||||||
|
digitalWrite(RELAY_5, HIGH);
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
DateTime now = rtc.now();
|
||||||
|
|
||||||
|
int hour = now.hour();
|
||||||
|
int minute = now.minute();
|
||||||
|
int second = now.second();
|
||||||
|
|
||||||
|
|
||||||
|
ldrValue1 = digitalRead(LDR_PIN_1);
|
||||||
|
ldrValue2 = digitalRead(LDR_PIN_2);
|
||||||
|
|
||||||
|
Serial.println(ldrValue1);
|
||||||
|
Serial.println(ldrValue2);
|
||||||
|
|
||||||
|
delay(100);
|
||||||
|
showTime();
|
||||||
|
|
||||||
|
Serial.println(minute);
|
||||||
|
// mengaktifkan alat relay suplai power
|
||||||
|
if (hour >= 7 && minute >= 0) {
|
||||||
|
digitalWrite(RELAY_1, LOW);
|
||||||
|
Serial.println("Relay 4 CH nyala");
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
//mematikan alat relay suplay power
|
||||||
|
if (hour >= 18 && minute > 0) {
|
||||||
|
digitalWrite(RELAY_1, HIGH);
|
||||||
|
Serial.println("Relay 4 CH mati");
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
//reset panel ke popsisi awal
|
||||||
|
if (hour == 17 && minute == 58 && second >= 0) {
|
||||||
|
digitalWrite(RELAY_2, LOW);
|
||||||
|
delay(10);
|
||||||
|
} else if (hour == 17 && minute == 58 && second >= 20) {
|
||||||
|
digitalWrite(RELAY_2, HIGH);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logika untuk relay 2 berdasarkan nilai LDR
|
||||||
|
if (ldrValue1 == 0) {
|
||||||
|
digitalWrite(RELAY_2, LOW);
|
||||||
|
Serial.println("nyala1");
|
||||||
|
delay(100);
|
||||||
|
} else {
|
||||||
|
digitalWrite(RELAY_2, HIGH);
|
||||||
|
Serial.println("mati1");
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logika untuk relay 5 berdasarkan nilai LDR
|
||||||
|
if (ldrValue2 == 0) {
|
||||||
|
digitalWrite(RELAY_5, LOW);
|
||||||
|
Serial.println("nyala1");
|
||||||
|
delay(100);
|
||||||
|
} else {
|
||||||
|
digitalWrite(RELAY_5, HIGH);
|
||||||
|
Serial.println("mati1");
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Perluangan tiap 10 meniit sekali dengan waktu RTC
|
||||||
|
// if (minute % 10 == 0 && second == 0) {
|
||||||
|
// bacaSensor();
|
||||||
|
// Serial.println("Data terbaca");
|
||||||
|
// delay(1000);
|
||||||
|
// kirim_data();
|
||||||
|
// Serial.println("Data terkirim");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bacaSensor();
|
||||||
|
// Serial.println("Data terbaca");
|
||||||
|
// delay(1000);
|
||||||
|
// kirim_data();
|
||||||
|
// Serial.println("Data terkirim");
|
||||||
|
|
||||||
|
//Perluangan tiap 10 meniit sekali dan mengambil data dari jam 7-18 wib dengan waktu RTC
|
||||||
|
if (hour >= 7 && hour < 18) {
|
||||||
|
if (minute % 10 == 0 && second == 0) {
|
||||||
|
bacaSensor(); // Memanggil fungsi untuk membaca sensor
|
||||||
|
Serial.println("Data terbaca");
|
||||||
|
delay(1000);
|
||||||
|
kirim_data(); // Memanggil fungsi untuk mengirim data
|
||||||
|
Serial.println("Data terkirim");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Serial.println("Tidak mengirim data (18.00 - 07.00 WIB)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void showTime() {
|
||||||
|
DateTime now = rtc.now();
|
||||||
|
Serial.print(now.hour(), DEC);
|
||||||
|
Serial.print(":");
|
||||||
|
if (now.minute() < 10) {
|
||||||
|
Serial.print("0");
|
||||||
|
}
|
||||||
|
Serial.print(now.minute(), DEC);
|
||||||
|
Serial.print(":");
|
||||||
|
if (now.second() < 10) {
|
||||||
|
Serial.print("0");
|
||||||
|
}
|
||||||
|
Serial.print(now.second(), DEC);
|
||||||
|
Serial.print(" ");
|
||||||
|
|
||||||
|
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
|
||||||
|
Serial.print(" ");
|
||||||
|
|
||||||
|
Serial.print(now.day(), DEC);
|
||||||
|
Serial.print("-");
|
||||||
|
Serial.print(now.month(), DEC);
|
||||||
|
Serial.print("-");
|
||||||
|
Serial.println(now.year(), DEC);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bacaSensor() {
|
||||||
|
ina226.readAndClearFlags();
|
||||||
|
shuntVoltage_mV = ina226.getShuntVoltage_mV();
|
||||||
|
busVoltage_V = ina226.getBusVoltage_V();
|
||||||
|
current_A = ina226.getCurrent_mA() /1000;
|
||||||
|
power_mW = ina226.getBusPower();
|
||||||
|
loadVoltage_V = busVoltage_V + (shuntVoltage_mV / 1000);
|
||||||
|
|
||||||
|
Serial.print("Shunt Voltage [mV]: ");
|
||||||
|
Serial.println(shuntVoltage_mV);
|
||||||
|
Serial.print("Bus Voltage [V]: ");
|
||||||
|
Serial.println(busVoltage_V);
|
||||||
|
Serial.print("Load Voltage [V]: ");
|
||||||
|
Serial.println(loadVoltage_V);
|
||||||
|
Serial.print("Current[A]: ");
|
||||||
|
Serial.println(current_A);
|
||||||
|
Serial.print("Bus Power [mW]: ");
|
||||||
|
Serial.println(power_mW);
|
||||||
|
if (!ina226.overflow) {
|
||||||
|
Serial.println("Values OK - no overflow");
|
||||||
|
} else {
|
||||||
|
Serial.println("Overflow! Choose higher current range");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
void kirim_data() {
|
||||||
|
|
||||||
|
int kelembaban = random(10, 20);
|
||||||
|
|
||||||
|
String postData = (String) "tegangan=" + loadVoltage_V + "&arus=" + current_A;
|
||||||
|
|
||||||
|
HTTPClient http;
|
||||||
|
http.begin("http://192.168.18.26/esp32_http/api2.php"); //mengirim ke database localhost melalui file api.php
|
||||||
|
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||||
|
|
||||||
|
auto httpCode = http.POST(postData);
|
||||||
|
String payload = http.getString();
|
||||||
|
|
||||||
|
Serial.println(postData);
|
||||||
|
Serial.println(payload);
|
||||||
|
|
||||||
|
http.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void connectToWifi() {
|
||||||
|
delay(1000);
|
||||||
|
WiFi.mode(WIFI_OFF);
|
||||||
|
delay(1000);
|
||||||
|
WiFi.mode(WIFI_STA);
|
||||||
|
|
||||||
|
WiFi.begin(ssid, password);
|
||||||
|
Serial.println("");
|
||||||
|
|
||||||
|
Serial.print("Connecting");
|
||||||
|
// Wait for connection
|
||||||
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
|
delay(500);
|
||||||
|
Serial.print(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println("");
|
||||||
|
Serial.print("Connected to ");
|
||||||
|
Serial.println(ssid);
|
||||||
|
Serial.print("IP address: ");
|
||||||
|
Serial.println(WiFi.localIP()); //IP address assigned to your ESP
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
// database.php
|
||||||
|
$host = 'localhost';
|
||||||
|
$db = 'monitoringdaya';
|
||||||
|
$user = 'root';
|
||||||
|
$pass = '';
|
||||||
|
$charset = 'utf8mb4';
|
||||||
|
|
||||||
|
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
|
||||||
|
$options = [
|
||||||
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||||
|
PDO::ATTR_EMULATE_PREPARES => false,
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$pdo = new PDO($dsn, $user, $pass, $options);
|
||||||
|
} catch (\PDOException $e) {
|
||||||
|
throw new \PDOException($e->getMessage(), (int)$e->getCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
function getData($date = null) {
|
||||||
|
global $pdo;
|
||||||
|
|
||||||
|
$query = "SELECT tegangan, arus, waktu FROM sensor";
|
||||||
|
$params = [];
|
||||||
|
|
||||||
|
if ($date) {
|
||||||
|
$query .= " WHERE DATE(waktu) = ?";
|
||||||
|
$params = [$date];
|
||||||
|
}
|
||||||
|
|
||||||
|
$query .= " ORDER BY waktu";
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare($query);
|
||||||
|
$stmt->execute($params);
|
||||||
|
return $stmt->fetchAll();
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?php
|
||||||
|
// get_data.php
|
||||||
|
require_once 'database.php';
|
||||||
|
|
||||||
|
$date = $_GET['date'] ?? null;
|
||||||
|
|
||||||
|
$data = getData($date);
|
||||||
|
echo json_encode($data);
|
|
@ -0,0 +1,204 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="id">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Dashboard Monitoring Daya</title>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/moment@2.29.1/moment.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment@1.0.0/dist/chartjs-adapter-moment.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="content">
|
||||||
|
<header>
|
||||||
|
<div class="container">
|
||||||
|
<h1 class="title_h1">Dashboard Monitoring Daya</h1>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="dashboard">
|
||||||
|
<div id="dateFilter">
|
||||||
|
<!-- <label for="date">Pilih Tanggal:</label> -->
|
||||||
|
<input type="date" id="date">
|
||||||
|
<button class="btn" onclick="filterData()"><i class="bi bi-search"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="nama">
|
||||||
|
<div class="chart-nama">
|
||||||
|
<h1> Pengukuran Tegangan </h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="dashboard-tegangan-arus">
|
||||||
|
<div class="chart-container">
|
||||||
|
<canvas id="voltageChart"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="nama">
|
||||||
|
<div class="chart-nama">
|
||||||
|
<h1> Pengukuran Arus </h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="dashboard-tegangan-arus">
|
||||||
|
<div class="chart-container">
|
||||||
|
<canvas id="currentChart"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<div class="container">
|
||||||
|
<p class="copyright">© 2024 Dashboard Monitoring Daya</p>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button id="scrollTopBtn" class="scroll-top-btn" onclick="scrollToTop()"> ⇧</button>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
|
// Mendapatkan elemen input tanggal
|
||||||
|
var tanggalInput = document.getElementById("date");
|
||||||
|
|
||||||
|
// Mendapatkan tanggal hari ini
|
||||||
|
var today = new Date();
|
||||||
|
var day = String(today.getDate()).padStart(2, '0');
|
||||||
|
var month = String(today.getMonth() + 1).padStart(2, '0'); // Januari adalah 0!
|
||||||
|
var year = today.getFullYear();
|
||||||
|
|
||||||
|
// Format YYYY-MM-DD
|
||||||
|
var todayFormatted = year + '-' + month + '-' + day;
|
||||||
|
|
||||||
|
// Mengatur nilai input tanggal ke hari ini
|
||||||
|
tanggalInput.value = todayFormatted;
|
||||||
|
filterData();
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
let voltageChart, currentChart;
|
||||||
|
|
||||||
|
function createCharts(data) {
|
||||||
|
const ctx1 = document.getElementById('voltageChart').getContext('2d');
|
||||||
|
const ctx2 = document.getElementById('currentChart').getContext('2d');
|
||||||
|
|
||||||
|
// Mendapatkan nilai minimum untuk tegangan dan arus dari data
|
||||||
|
const minVoltage = Math.min(...data.map(item => item.tegangan));
|
||||||
|
const minCurrent = Math.min(...data.map(item => item.arus));
|
||||||
|
|
||||||
|
// Tentukan nilai minimum yang akan digunakan
|
||||||
|
const minVoltageValue = Math.floor(minVoltage) - 2; // Dimulai dari nilai minimum tegangan dikurangi 2
|
||||||
|
const minCurrentValue = Math.floor(minCurrent) - 2; // Dimulai dari nilai minimum arus dikurangi 2
|
||||||
|
|
||||||
|
const chartOptions = {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
scales: {
|
||||||
|
x: {
|
||||||
|
type: 'time',
|
||||||
|
time: {
|
||||||
|
unit: 'hour'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
// Skala untuk tegangan (V)
|
||||||
|
voltage: {
|
||||||
|
beginAtZero: false,
|
||||||
|
suggestedMin: minVoltageValue
|
||||||
|
},
|
||||||
|
// Skala untuk arus (A)
|
||||||
|
current: {
|
||||||
|
beginAtZero: false,
|
||||||
|
suggestedMin: minCurrentValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
voltageChart = new Chart(ctx1, {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: data.map(item => item.waktu),
|
||||||
|
datasets: [{
|
||||||
|
label: 'Tegangan (V)',
|
||||||
|
data: data.map(item => ({ x: item.waktu, y: item.tegangan })),
|
||||||
|
borderColor: '#1a237e',
|
||||||
|
backgroundColor: 'rgba(26, 35, 126, 0.1)',
|
||||||
|
tension: 0.1
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: chartOptions
|
||||||
|
});
|
||||||
|
|
||||||
|
currentChart = new Chart(ctx2, {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: data.map(item => item.waktu),
|
||||||
|
datasets: [{
|
||||||
|
label: 'Arus (A)',
|
||||||
|
data: data.map(item => ({ x: item.waktu, y: item.arus })),
|
||||||
|
borderColor: '#3949ab',
|
||||||
|
backgroundColor: 'rgba(57, 73, 171, 0.1)',
|
||||||
|
tension: 0.1
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: chartOptions
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function filterData() {
|
||||||
|
const date = document.getElementById('date').value;
|
||||||
|
|
||||||
|
fetch(`get_data.php?date=${date}`)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (voltageChart) voltageChart.destroy();
|
||||||
|
if (currentChart) currentChart.destroy();
|
||||||
|
createCharts(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inisialisasi grafik dengan semua data
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
filterData();
|
||||||
|
}, 10000);
|
||||||
|
|
||||||
|
fetch('get_data.php')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => createCharts(data));
|
||||||
|
|
||||||
|
// Tampilkan tombol ketika pengguna scroll ke bawah 20px dari atas dokumen
|
||||||
|
window.onscroll = function() {
|
||||||
|
scrollFunction();
|
||||||
|
};
|
||||||
|
|
||||||
|
function scrollFunction() {
|
||||||
|
const scrollTopBtn = document.getElementById('scrollTopBtn');
|
||||||
|
if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
|
||||||
|
scrollTopBtn.style.display = 'block';
|
||||||
|
} else {
|
||||||
|
scrollTopBtn.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scroll ke atas halaman ketika tombol ditekan
|
||||||
|
function scrollToTop() {
|
||||||
|
document.body.scrollTop = 0; // Untuk Safari
|
||||||
|
document.documentElement.scrollTop = 0; // Untuk Chrome, Firefox, IE, dan Opera
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,172 @@
|
||||||
|
html {
|
||||||
|
scroll-behavior: smooth; /* Membuat scroll lebih smooth */
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
margin: 0;
|
||||||
|
position: -webkit-sticky;
|
||||||
|
padding: 0;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
padding-bottom: 50px; /* Tambahkan padding bawah */
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 10px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
background-color: #1a237e;
|
||||||
|
color: white;
|
||||||
|
padding: 10px 0;
|
||||||
|
position: sticky;
|
||||||
|
/* position: -webkit-sticky; */
|
||||||
|
top: 0;
|
||||||
|
/* display: flex;
|
||||||
|
justify-content: space-between; */
|
||||||
|
/* align-items: center; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.container .title_h1 {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar ul {
|
||||||
|
list-style-type: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar ul li {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar ul li a {
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar ul li a:hover {
|
||||||
|
background-color: #3949ab;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.2em;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard {
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 0 10px rgba(0,0,0,0.1);
|
||||||
|
margin-top: 20px;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
.dashboard-tegangan-arus {
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 0 10px rgba(0,0,0,0.1);
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nama {
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 0 10px rgba(0,0,0,0.1);
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
padding: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-nama {
|
||||||
|
width: 70%;
|
||||||
|
height: 20px;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nama h1 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.2em;
|
||||||
|
text-align: left;
|
||||||
|
color: #1a237e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-container {
|
||||||
|
width: 70%;
|
||||||
|
height: 300px;
|
||||||
|
margin: 20px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#dateFilter {
|
||||||
|
/* margin-bottom: 7px; */
|
||||||
|
text-align: right;
|
||||||
|
margin-right: 10px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#dateFilter input {
|
||||||
|
padding: 7px;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
footer {
|
||||||
|
background-color: #1a237e;
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
padding: 5px 0;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright {
|
||||||
|
font-size: 0.8em;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
background-color: #1a237e;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 8px 15px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover {
|
||||||
|
background-color: #3949ab;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-top-btn {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 55px;
|
||||||
|
right: 20px;
|
||||||
|
background-color: #1e2ab1;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 25%; /* Changed to a circle */
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0 0 10px rgba(0,0,0,0.1);
|
||||||
|
font-size: 18px;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
.scroll-top-btn:hover {
|
||||||
|
background-color: #2f3986;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
}
|
Loading…
Reference in New Issue