noranisa commited on
Commit
af7900c
Β·
verified Β·
1 Parent(s): ababcd4

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +241 -16
templates/index.html CHANGED
@@ -1,28 +1,253 @@
1
  <!DOCTYPE html>
2
- <html>
3
  <head>
4
- <title>Sentiment Analysis</title>
5
- <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  </head>
7
- <body class="bg-dark text-white">
8
 
9
- <div class="container mt-5 text-center">
10
- <h1>πŸ”₯ Sentiment Analysis Multi-Platform</h1>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
- <form method="POST">
13
- <input class="form-control mt-3" name="keyword" placeholder="Contoh: Jokowi" required>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
- <div class="mt-4">
16
- <label>Pilih Sumber:</label><br>
 
 
 
 
17
 
18
- <input type="radio" name="source" value="all" checked> Semua
19
- <input type="radio" name="source" value="youtube"> YouTube
20
- <input type="radio" name="source" value="reddit"> Reddit
21
- </div>
 
 
22
 
23
- <button class="btn btn-primary mt-4">Analisis</button>
24
- </form>
25
  </div>
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  </body>
28
  </html>
 
1
  <!DOCTYPE html>
2
+ <html lang="id">
3
  <head>
4
+ <meta charset="UTF-8">
5
+ <title>AI Sentiment Dashboard</title>
6
+
7
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
8
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
9
+
10
+ <style>
11
+ body { background:#0f172a; color:white; }
12
+ .sidebar {
13
+ width:230px;
14
+ height:100vh;
15
+ position:fixed;
16
+ background:#111827;
17
+ padding:20px;
18
+ }
19
+ .main {
20
+ margin-left:250px;
21
+ padding:20px;
22
+ }
23
+ .card {
24
+ background:#1f2937;
25
+ color:white;
26
+ border-radius:10px;
27
+ }
28
+ table { font-size: 13px; }
29
+ </style>
30
+
31
  </head>
 
32
 
33
+ <body>
34
+
35
+ <!-- πŸ”₯ SIDEBAR -->
36
+ <div class="sidebar">
37
+ <h4>πŸ”₯ Dashboard</h4>
38
+
39
+ <input id="keyword" class="form-control mt-3" placeholder="Masukkan keyword">
40
+
41
+ <div class="mt-3">
42
+ <input type="radio" name="source" value="all" checked> Semua<br>
43
+ <input type="radio" name="source" value="youtube"> YouTube<br>
44
+ <input type="radio" name="source" value="reddit"> Reddit
45
+ </div>
46
+
47
+ <button onclick="runAnalysis()" class="btn btn-primary mt-3 w-100">
48
+ Analisis
49
+ </button>
50
+
51
+ <hr>
52
+
53
+ <h6>Filter Sentimen</h6>
54
+ <button onclick="filterData('All')" class="btn btn-dark btn-sm w-100 mt-1">All</button>
55
+ <button onclick="filterData('Positive')" class="btn btn-success btn-sm w-100 mt-1">Positive</button>
56
+ <button onclick="filterData('Neutral')" class="btn btn-secondary btn-sm w-100 mt-1">Neutral</button>
57
+ <button onclick="filterData('Negative')" class="btn btn-danger btn-sm w-100 mt-1">Negative</button>
58
+
59
+ <hr>
60
+
61
+ <a href="/download" class="btn btn-success w-100">⬇ Download CSV</a>
62
+ </div>
63
+
64
+ <!-- πŸ”₯ MAIN -->
65
+ <div class="main">
66
+
67
+ <h3>πŸ“Š AI Sentiment Dashboard</h3>
68
 
69
+ <!-- LOADING -->
70
+ <div id="loading" style="display:none;">
71
+ <div class="spinner-border text-light"></div>
72
+ <p>Memproses data...</p>
73
+ </div>
74
+
75
+ <!-- CHART + WORD -->
76
+ <div class="row mt-3">
77
+
78
+ <div class="col-md-6">
79
+ <div class="card p-3">
80
+ <h5>Distribusi Sentimen</h5>
81
+ <canvas id="chart"></canvas>
82
+ </div>
83
+ </div>
84
+
85
+ <div class="col-md-6">
86
+ <div class="card p-3">
87
+ <h5>Top Kata (Trend)</h5>
88
+ <ul id="topWords"></ul>
89
+ </div>
90
+ </div>
91
+
92
+ </div>
93
+
94
+ <!-- HEATMAP + WORDCLOUD -->
95
+ <div class="row mt-3">
96
 
97
+ <div class="col-md-6">
98
+ <div class="card p-3">
99
+ <h5>πŸ”₯ Heatmap</h5>
100
+ <img src="/static/heatmap.png" width="100%">
101
+ </div>
102
+ </div>
103
 
104
+ <div class="col-md-6">
105
+ <div class="card p-3">
106
+ <h5>☁️ WordCloud</h5>
107
+ <img src="/static/wordcloud.png" width="100%">
108
+ </div>
109
+ </div>
110
 
 
 
111
  </div>
112
 
113
+ <!-- TOPIC -->
114
+ <div class="card mt-3 p-3">
115
+ <h5>🧠 Topic Modeling</h5>
116
+ <ul id="topics"></ul>
117
+ </div>
118
+
119
+ <!-- INSIGHT -->
120
+ <div class="card mt-3 p-3">
121
+ <h5>πŸ€– AI Insight</h5>
122
+ <pre id="insightBox"></pre>
123
+ </div>
124
+
125
+ <!-- TABLE -->
126
+ <div class="card mt-3 p-3">
127
+ <h5>Data Komentar</h5>
128
+
129
+ <table class="table table-dark table-striped">
130
+ <thead>
131
+ <tr><th>No</th><th>Text</th><th>Sentiment</th><th>Source</th></tr>
132
+ </thead>
133
+ <tbody id="table"></tbody>
134
+ </table>
135
+
136
+ </div>
137
+
138
+ </div>
139
+
140
+ <script>
141
+
142
+ let allData = [];
143
+ let chart;
144
+
145
+ // πŸ”₯ RUN ANALYSIS
146
+ function runAnalysis() {
147
+ const keyword = document.getElementById("keyword").value;
148
+ const source = document.querySelector('input[name="source"]:checked').value;
149
+
150
+ document.getElementById("loading").style.display = "block";
151
+
152
+ fetch('/analyze', {
153
+ method:'POST',
154
+ headers:{'Content-Type':'application/json'},
155
+ body:JSON.stringify({keyword,source})
156
+ })
157
+ .then(res=>res.json())
158
+ .then(res=>{
159
+ allData = res.data;
160
+ updateUI(res.data, res.top_words, res.topics, res.insight);
161
+ document.getElementById("loading").style.display = "none";
162
+ });
163
+ }
164
+
165
+ // πŸ”₯ UPDATE UI
166
+ function updateUI(data, topWords, topics, insight) {
167
+ renderTable(data);
168
+ renderChart(data);
169
+ renderTopWords(topWords);
170
+ renderTopics(topics);
171
+ renderInsight(insight);
172
+ }
173
+
174
+ // πŸ”₯ TABLE
175
+ function renderTable(data) {
176
+ const table = document.getElementById("table");
177
+ table.innerHTML="";
178
+
179
+ data.forEach((d,i)=>{
180
+ table.innerHTML += `
181
+ <tr>
182
+ <td>${i+1}</td>
183
+ <td>${d.text}</td>
184
+ <td>${d.sentiment}</td>
185
+ <td>${d.source}</td>
186
+ </tr>`;
187
+ });
188
+ }
189
+
190
+ // πŸ”₯ CHART DINAMIS
191
+ function renderChart(data) {
192
+ let counts = {Positive:0, Neutral:0, Negative:0};
193
+
194
+ data.forEach(d=>counts[d.sentiment]++);
195
+
196
+ if(chart) chart.destroy();
197
+
198
+ chart = new Chart(document.getElementById("chart"), {
199
+ type:'pie',
200
+ data:{
201
+ labels:Object.keys(counts),
202
+ datasets:[{data:Object.values(counts)}]
203
+ }
204
+ });
205
+ }
206
+
207
+ // πŸ”₯ FILTER
208
+ function filterData(type){
209
+ if(type==="All"){
210
+ updateUI(allData, [], [], "");
211
+ } else {
212
+ const filtered = allData.filter(d=>d.sentiment===type);
213
+ updateUI(filtered, [], [], "");
214
+ }
215
+ }
216
+
217
+ // πŸ”₯ TOP WORDS
218
+ function renderTopWords(words){
219
+ const list = document.getElementById("topWords");
220
+ list.innerHTML="";
221
+
222
+ words.forEach(w=>{
223
+ list.innerHTML += `<li>${w.word} (${w.count})</li>`;
224
+ });
225
+ }
226
+
227
+ // πŸ”₯ TOPIC
228
+ function renderTopics(topics){
229
+ const el = document.getElementById("topics");
230
+ el.innerHTML="";
231
+
232
+ topics.forEach((t,i)=>{
233
+ el.innerHTML += `<li><b>Topik ${i+1}:</b> ${t.join(", ")}</li>`;
234
+ });
235
+ }
236
+
237
+ // πŸ”₯ INSIGHT
238
+ function renderInsight(text){
239
+ document.getElementById("insightBox").innerText = text;
240
+ }
241
+
242
+ // πŸ”₯ AUTO REFRESH (REAL-TIME)
243
+ setInterval(()=>{
244
+ const keyword = document.getElementById("keyword").value;
245
+ if(keyword){
246
+ runAnalysis();
247
+ }
248
+ }, 5000);
249
+
250
+ </script>
251
+
252
  </body>
253
  </html>