Visualisasi & Filter Data, serta fungsi CRUD data.
Langkah - Langkah :
1. Import file datasheet yang akan dipakai ke MongoDB menggunakkan VS Code. pastikan file sudah csv dan nama sesuai dengan nama file. buat file pada VS Code dengan nama film.cvs
berikut kode untuk impor csv :
import csv
from pymongo import MongoClient
client = MongoClient('mongodb://localhost:27017/')
db = client['pbl']
koleksi = db['salary']
# Impor data dari file CSV ke MongoDB
path_csv = 'ds_salaries.csv'
with open(path_csv, 'r') as csvfile:
csv_reader = csv.DictReader(csvfile)
for row in csv_reader:
koleksi.insert_one(row)
print("Data dari CSV berhasil diimpor ke MongoDB.")
2. Untuk menampilkan data dan fungsi CRUD, buat file app.py lalu isi dengan kode seperti dibawah ini :
from flask import Flask, render_template, request, redirect
from pymongo import MongoClient
from bson import ObjectId
import plotly.graph_objs as go
from plotly.subplots import make_subplots
app = Flask(__name__)
client = MongoClient('mongodb://localhost:27017/')
db = client['pbl']
koleksi = db['salary']
def index():
data_cursor = koleksi.find()
formatted_data = []
header = ['work_year', 'experience_level', 'employment_type', 'job_title', 'salary', 'salary_currency', 'salary_in_usd', 'employee_residence', 'remote_ratio', 'company_location', 'company_size']
for row in data_cursor:
formatted_row = {key: row[key] for key in header}
formatted_data.append(formatted_row)
return render_template('index.html', data=formatted_data)
# Rute lainnya untuk tambah, edit, dan hapus data
# Rute untuk menampilkan data dan melakukan pencarian
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
query = request.form.get('query')
if query:
data_cursor = koleksi.find({
'$or': [
{'work_year': {'$regex': query, '$options': 'i'}},
{'experience_level': {'$regex': query, '$options': 'i'}},
{'employment_type': {'$regex': query, '$options': 'i'}},
{'job_title': {'$regex': query, '$options': 'i'}},
{'salary': {'$regex': query, '$options': 'i'}},
{'salary_currency': {'$regex': query, '$options': 'i'}},
{'salary_in_usd': {'$regex': query, '$options': 'i'}},
{'employee_residence': {'$regex': query, '$options': 'i'}},
{'remote_ratio': {'$regex': query, '$options': 'i'}},
{'company_location': {'$regex': query, '$options': 'i'}},
{'company_size': {'$regex': query, '$options': 'i'}}
]
})
data_list = list(data_cursor)
return render_template('index.html', data=data_list)
else:
return redirect('/')
else:
data_cursor = koleksi.find()
data_list = list(data_cursor)
return render_template('index.html', data=data_list)
# Rute untuk menambah data baru
@app.route('/add', methods=['POST'])
def add():
new_data = {
'work_year': request.form['work_year'],
'experience_level': request.form['experience_level'],
'employment_type': request.form['employment_type'],
'job_title': request.form['job_title'],
'salary': request.form['salary'],
'salary_currency': request.form['salary_currency'],
'salary_in_usd': request.form['salary_in_usd'],
'employee_residence': request.form['employee_residence'],
'remote_ratio': request.form['remote_ratio'],
'company_location': request.form['company_location'],
'company_size': request.form['company_size']
}
koleksi.insert_one(new_data)
return redirect('/')
# Rute untuk menghapus data
@app.route('/delete/<id>', methods=['GET'])
def delete(id):
koleksi.delete_one({'_id': ObjectId(id)})
return redirect('/')
# Rute untuk menampilkan form edit
@app.route('/edit/<string:row_id>', methods=['GET'])
def edit_data(row_id):
data = koleksi.find_one({'_id': ObjectId(row_id)})
if data:
return render_template('edit.html', data=data)
else:
return "Data not found", 404 # Optional: Menampilkan pesan jika data tidak ditemukan
@app.route('/charts')
def charts():
# Ambil data dari MongoDB
data_cursor = koleksi.find()
data_list = list(data_cursor)
# Siapkan data untuk grafik lingkaran
salaries = [float(data['salary_in_usd']) for data in data_list]
# Ambil 10 kategori pertama untuk grafik lingkaran
top_10_salaries = sorted(data_list, key=lambda x: float(x['salary_in_usd']), reverse=True)[:10]
salaries = [float(data['salary_in_usd']) for data in top_10_salaries]
labels = [data['job_title'] for data in top_10_salaries]
# Buat grafik lingkaran untuk menampilkan distribusi gaji
fig_pie = go.Figure(data=[go.Pie(labels=labels, values=salaries)])
fig_pie.update_layout(title="Top 10 Job Salaries")
# Grafik batang untuk menampilkan rata-rata gaji per tahun bekerja
work_years = [data['work_year'] for data in data_list]
unique_work_years = list(set(work_years))
avg_salaries = [sum([float(data['salary_in_usd']) for data in data_list if data['work_year'] == year])
/ len([float(data['salary_in_usd']) for data in data_list if data['work_year'] == year])
for year in unique_work_years]
fig_bar = go.Figure(data=go.Bar(x=unique_work_years, y=avg_salaries))
fig_bar.update_layout(title="Average Salary per Work Year")
# Grafik garis untuk menampilkan perbandingan gaji berdasarkan tingkat pengalaman
exp_levels = [data['experience_level'] for data in data_list]
unique_exp_levels = list(set(exp_levels))
avg_salaries_exp = [sum([float(data['salary_in_usd']) for data in data_list if data['experience_level'] == level])
/ len([float(data['salary_in_usd']) for data in data_list if data['experience_level'] == level])
for level in unique_exp_levels]
fig_line = go.Figure(data=go.Scatter(x=unique_exp_levels, y=avg_salaries_exp, mode='lines+markers'))
fig_line.update_layout(title="Average Salary per Experience Level")
# Konversi setiap figure ke dalam representasi HTML agar bisa dimasukkan ke dalam template
graph_html_pie = fig_pie.to_html(full_html=False)
graph_html_bar = fig_bar.to_html(full_html=False)
graph_html_line = fig_line.to_html(full_html=False)
return render_template('charts.html', graph_pie=graph_html_pie, graph_bar=graph_html_bar, graph_line=graph_html_line)
# Rute untuk menyimpan perubahan dari form edit
@app.route('/update/<id>', methods=['POST'])
def update(id):
updated_data = {
'work_year': request.form['work_year'],
'experience_level': request.form['experience_level'],
'employment_type': request.form['employment_type'],
'job_title': request.form['job_title'],
'salary': request.form['salary'],
'salary_currency': request.form['salary_currency'],
'salary_in_usd': request.form['salary_in_usd'],
'employee_residence': request.form['employee_residence'],
'remote_ratio': request.form['remote_ratio'],
'company_location': request.form['company_location'],
'company_size': request.form['company_size']
}
koleksi.update_one({'_id': ObjectId(id)}, {'$set': updated_data})
return redirect('/')
if __name__ == '__main__':
app.run(debug=True)
3. Untuk menampilkan grafik, buat Buatlah folder baru "templates" untuk menyimpan script html, terdapat 3 file yaitu index.html untuk mengatur tampilan halaman awal, edit.html untuk mengatur tampilan halaman edit, dan charts.html untuk mengatur tampilan halaman grafik.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Data Gaji Karyawan</title>
<style>
table {
border-collapse: collapse;
width: 100%;
}
th,
td {
border: 1px solid black;
padding: 8px;
text-align: center;
max-width: 200px; /* Atur lebar maksimum untuk kolom */
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
margin: 4px; /* Menambahkan jarak pada setiap sisi */
}
th:nth-child(1),
td:nth-child(1) {
width: 8%; /* Atur lebar kolom work_year di sini */
}
th:nth-child(2),
td:nth-child(2) {
width: 8%; /* Atur lebar kolom experience_level di sini */
}
th:nth-child(3),
td:nth-child(3) {
width: 8%; /* Atur lebar kolom employment_type di sini */
}
th:nth-child(4),
td:nth-child(4) {
width: 16%; /* Atur lebar kolom job_title di sini */
}
th:nth-child(5),
td:nth-child(5) {
width: 8%; /* Atur lebar kolom salary di sini */
}
th:nth-child(6),
td:nth-child(6) {
width: 12%; /* Atur lebar kolom salary_currency di sini */
}
th:nth-child(7),
td:nth-child(7) {
width: 12%; /* Atur lebar kolom salary_in_usd di sini */
}
th:nth-child(8),
td:nth-child(8) {
width: 12%; /* Atur lebar kolom employee_residence di sini */
}
th:nth-child(9),
td:nth-child(9) {
width: 8%; /* Atur lebar kolom remote_ratio di sini */
}
th:nth-child(10),
td:nth-child(10) {
width: 12%; /* Atur lebar kolom company_location di sini */
}
th:nth-child(11),
td:nth-child(11) {
width: 8%; /* Atur lebar kolom company_size di sini */
}
/* Tambahkan margin-bottom untuk memberikan ruang antara form dan tabel */
form {
margin-bottom: 20px;
}
</style>
</head>
<body>
<h1>Data Gaji Karyawan</h1>
<p>Data Length: {{ data|length }}</p>
<form action="/" method="POST">
<!-- <label for="search">Cari:</label> -->
<input type="text" id="search" name="query" />
<button type="submit">Cari</button>
</form>
<button
type="button"
onclick="window.location.href='/charts'"
style="width: 150px; height: 25px; margin-top: 10px; margin-bottom: 10px"
>
Tampilkan Grafik
</button>
<form
action="/add"
method="POST"
style="display: grid; grid-template-columns: 140px 200px; gap: 10px"
>
<label for="work_year" style="text-align: right">Work Year:</label>
<input type="text" id="work_year" name="work_year" />
<label for="experience_level" style="text-align: right"
>Experience Level:</label
>
<input type="text" id="experience_level" name="experience_level" />
<label for="employment_type" style="text-align: right"
>Employment Type:</label
>
<input type="text" id="employment_type" name="employment_type" />
<label for="job_title" style="text-align: right">Job Title:</label>
<input type="text" id="job_title" name="job_title" />
<label for="salary" style="text-align: right">Salary:</label>
<input type="text" id="salary" name="salary" />
<label for="salary_currency" style="text-align: right"
>Salary Currency:</label
>
<input type="text" id="salary_currency" name="salary_currency" />
<label for="salary_in_usd" style="text-align: right"
>Salary in USD:</label
>
<input type="text" id="salary_in_usd" name="salary_in_usd" />
<label for="employee_residence" style="text-align: right"
>Employee Residence:</label
>
<input type="text" id="employee_residence" name="employee_residence" />
<label for="remote_ratio" style="text-align: right">Remote Ratio:</label>
<input type="text" id="remote_ratio" name="remote_ratio" />
<label for="company_location" style="text-align: right"
>Company Location:</label
>
<input type="text" id="company_location" name="company_location" />
<label for="company_size" style="text-align: right">Company Size:</label>
<input type="text" id="company_size" name="company_size" />
<button type="submit" style="grid-column: span 2; justify-self: end">
Tambah Data
</button>
</form>
<table>
<thead>
<tr>
<th>Work Year</th>
<th>Experience Level</th>
<th>Employment Type</th>
<th>Job Title</th>
<th>Salary</th>
<th>Salary Currency</th>
<th>Salary in USD</th>
<th>Employee Residence</th>
<th>Remote Ratio</th>
<th>Company Location</th>
<th>Company Size</th>
<th>Aksi</th>
</tr>
</thead>
<tbody>
{% for row in data %}
<tr>
<td>{{ row.work_year }}</td>
<td>{{ row.experience_level }}</td>
<td>{{ row.employment_type }}</td>
<td>{{ row.job_title }}</td>
<td>{{ row.salary }}</td>
<td>{{ row.salary_currency }}</td>
<td>{{ row.salary_in_usd }}</td>
<td>{{ row.employee_residence }}</td>
<td>{{ row.remote_ratio }}</td>
<td>{{ row.company_location }}</td>
<td>{{ row.company_size }}</td>
<td>
<form action="/edit/{{ row._id }}" method="GET">
<button type="submit">Edit Data</button>
</form>
<form action="/delete/{{ row._id }}" method="GET">
<button type="submit">Hapus</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Edit Data</title>
<style>
/* Atur gaya sesuai kebutuhan Anda */
</style>
</head>
<body>
<h1>Edit Data</h1>
<form
action="/update/{{ data._id }}"
method="POST"
style="display: grid; grid-template-columns: 140px 200px; gap: 10px"
>
<label for="work_year" style="text-align: right">Work Year:</label>
<input
type="text"
id="work_year"
name="work_year"
value="{{ data.work_year }}"
/>
<label for="experience_level" style="text-align: right"
>Experience Level:</label
>
<input
type="text"
id="experience_level"
name="experience_level"
value="{{ data.experience_level }}"
/>
<label for="employment_type" style="text-align: right"
>Employment Type:</label
>
<input
type="text"
id="employment_type"
name="employment_type"
value="{{ data.employment_type }}"
/>
<label for="job_title" style="text-align: right">Job Title:</label>
<input
type="text"
id="job_title"
name="job_title"
value="{{ data.job_title }}"
/>
<label for="salary" style="text-align: right">Salary:</label>
<input type="text" id="salary" name="salary" value="{{ data.salary }}" />
<label for="salary_currency" style="text-align: right"
>Salary Currency:</label
>
<input
type="text"
id="salary_currency"
name="salary_currency"
value="{{ data.salary_currency }}"
/>
<label for="salary_in_usd" style="text-align: right"
>Salary in USD:</label
>
<input
type="text"
id="salary_in_usd"
name="salary_in_usd"
value="{{ data.salary_in_usd }}"
/>
<label for="employee_residence" style="text-align: right"
>Employee Residence:</label
>
<input
type="text"
id="employee_residence"
name="employee_residence"
value="{{ data.employee_residence }}"
/>
<label for="remote_ratio" style="text-align: right">Remote Ratio:</label>
<input
type="text"
id="remote_ratio"
name="remote_ratio"
value="{{ data.remote_ratio }}"
/>
<label for="company_location" style="text-align: right"
>Company Location:</label
>
<input
type="text"
id="company_location"
name="company_location"
value="{{ data.company_location }}"
/>
<label for="company_size" style="text-align: right">Company Size:</label>
<input
type="text"
id="company_size"
name="company_size"
value="{{ data.company_size }}"
/>
<button type="submit" style="grid-column: span 2; justify-self: end">
Update Data
</button>
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Charts</title>
<!-- Plotly.js -->
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<div id="chart1">
<!-- Ini adalah tempat untuk grafik lingkaran -->
{{ graph_pie|safe }}
</div>
<div id="chart2">
<!-- Ini adalah tempat untuk grafik batang -->
{{ graph_bar|safe }}
</div>
<div id="chart3">
<!-- Ini adalah tempat untuk grafik garis -->
{{ graph_line|safe }}
</div>
</body>
</html>
HASIL :
1. Tampilan Awal
Pada halaman awal akan muncul data yang sudah diimport dan jumlah datanya. Di sini juga terdapat tools untuk melakukan pencarian berdasarkan kategori tertentu, tampilkan grafik, tambah data, hapus data, dan edit data pada pojok kanan tabel (aksi).
2. Tampilan edit data
apabila tombol aksi dikil pada edit, maka akan muncul halaman edit data
3. Hasil tampilan cari berdasarkan kategori
apabila ingin melihat data tertentu saja, kita hanya perlu ketikkan sesuai dengan kategorinya, misal ingin melihat data gaji kategori , maka ketik pada pencarian :
- Data tahun "2002"
hasilnya muncul data seperti berikut:
- Data pekerja "applied scientist"
hasilnya muncul data seperti berikut:
- Data gaji "175000" USD
hasilnya muncul data seperti berikut:
4. Tampilan Grafik berdasarkan kategori :
- Berdasarkan Top 10 Gaji Karyawan
- Berdasarkan Gaji Rata-Rata per Tahun
- Berdasarkan Rata-Rata Gaji per Tingkat Pengalaman
NT: setiap grafik terdapat menu download as png, zoom in, zoom out, dll pada pojok kanan atas
Posting Komentar untuk "Penerapan Database MongoDB dengan Visual Studio Code"