word cloud
This commit is contained in:
parent
8518f670c2
commit
acae57aea6
|
@ -3,6 +3,8 @@
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use Illuminate\Support\Facades\File;
|
||||||
|
|
||||||
class HomeController extends Controller
|
class HomeController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -10,4 +12,48 @@ class HomeController extends Controller
|
||||||
{
|
{
|
||||||
return redirect('dashboard');
|
return redirect('dashboard');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function wordcloudData(Request $request)
|
||||||
|
{
|
||||||
|
$source = $request->query('source', 'gopay'); // default 'gopay'
|
||||||
|
|
||||||
|
// Tentukan file berdasarkan sumber
|
||||||
|
if ($source === 'gopay') {
|
||||||
|
$files = ['gopaylabel.csv'];
|
||||||
|
} elseif ($source === 'dana') {
|
||||||
|
$files = ['danalabel.csv'];
|
||||||
|
} elseif($source === 'shopeepay'){
|
||||||
|
$files = ['shopeepaylabel.csv'];
|
||||||
|
} else {
|
||||||
|
$files = ['gopaylabel.csv', 'danalabel.csv', 'shopeepaylabel.csv'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$allText = '';
|
||||||
|
foreach ($files as $file) {
|
||||||
|
$path = resource_path("views/{$file}");
|
||||||
|
if (File::exists($path)) {
|
||||||
|
// Baca baris per baris
|
||||||
|
$csv = array_map('str_getcsv', File::lines($path)->toArray());
|
||||||
|
$header = array_shift($csv);
|
||||||
|
$idx = array_search('cleaned_text', $header);
|
||||||
|
foreach ($csv as $row) {
|
||||||
|
if (isset($row[$idx])) {
|
||||||
|
$allText .= ' '.strtolower($row[$idx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$words = str_word_count($allText, 1);
|
||||||
|
$filtered = array_filter($words, fn($w) => strlen($w) > 2);
|
||||||
|
$counts = array_count_values($filtered);
|
||||||
|
arsort($counts);
|
||||||
|
$top100 = array_slice($counts, 0, 100, true);
|
||||||
|
|
||||||
|
$list = [];
|
||||||
|
foreach ($top100 as $word => $count) {
|
||||||
|
$list[] = [$word, $count];
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json($list);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,6 +237,34 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="center d-flex flex-column justify-content-center align-items-center"
|
||||||
|
style="padding: 2rem; min-height: 100vh;">
|
||||||
|
|
||||||
|
<div class="row justify-content-center my-5">
|
||||||
|
<div class="col-lg-8">
|
||||||
|
<div class="mb-3" style="width: 300px;">
|
||||||
|
<select id="sourceSelect" class="form-select">
|
||||||
|
<option value="gopay" selected>Gopay</option>
|
||||||
|
<option value="dana">Dana</option>
|
||||||
|
<option value="shopeepay">Shopeepay</option>
|
||||||
|
<option value="gabungan">Gabungan</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="card shadow-lg border-radius-lg bg-white">
|
||||||
|
<div class="card-header pb-2">
|
||||||
|
</div>
|
||||||
|
<div class="card-body d-flex justify-content-center align-items-center py-4">
|
||||||
|
<canvas id="wc" width="1800" height="800"
|
||||||
|
style="max-width: 100%; height: auto;"></canvas>
|
||||||
|
</div>
|
||||||
|
<div class="card-footer text-muted text-end small">
|
||||||
|
Generated on {{ date('d F Y, H:i') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@push('dashboard')
|
@push('dashboard')
|
||||||
|
@ -471,146 +499,40 @@
|
||||||
negatifEl.textContent = d.negatif;
|
negatifEl.textContent = d.negatif;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// Word Cloud
|
</script>
|
||||||
// var danaData = [{{ $cDana['positif'] }}, {{ $cDana['netral'] }}, {{ $cDana['negatif'] }}];
|
<script src="https://cdn.jsdelivr.net/npm/wordcloud@1.1.2/src/wordcloud2.min.js" defer></script>
|
||||||
// var goPayData = [{{ $cGoPay['positif'] }}, {{ $cGoPay['netral'] }}, {{ $cGoPay['negatif'] }}];
|
<script defer>
|
||||||
// var shopeeData = [{{ $cShopee['positif'] }}, {{ $cShopee['netral'] }}, {{ $cShopee['negatif'] }}];
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const canvas = document.getElementById('wc');
|
||||||
|
const select = document.getElementById('sourceSelect');
|
||||||
|
|
||||||
// var danaData = [{{ $cDana['positif'] }}, {{ $cDana['netral'] }}, {{ $cDana['negatif'] }}];
|
function loadWordCloud(source) {
|
||||||
// var goPayData = [{{ $cGoPay['positif'] }}, {{ $cGoPay['netral'] }}, {{ $cGoPay['negatif'] }}];
|
fetch(`/wordcloud-data?source=${source}`)
|
||||||
// var shopeeData = [{{ $cShopee['positif'] }}, {{ $cShopee['netral'] }}, {{ $cShopee['negatif'] }}];
|
.then(res => res.json())
|
||||||
|
.then(list => {
|
||||||
|
console.log('WordCloud data:', list); // → pastikan ada data
|
||||||
|
WordCloud(canvas, {
|
||||||
|
list,
|
||||||
|
gridSize: Math.round(1600 / 100),
|
||||||
|
weightFactor: w => Math.pow(w, 0.5) * 8,
|
||||||
|
|
||||||
// var wordData = [{
|
fontFamily: 'Arial, sans-serif',
|
||||||
// text: 'Positif Dana',
|
rotateRatio: 0,
|
||||||
// weight: danaData[0]
|
shape: 'elliptic',
|
||||||
// },
|
ellipticity: 0.65,
|
||||||
// {
|
drawOutOfBound: false,
|
||||||
// text: 'Netral Dana',
|
backgroundColor: '#ffffff'
|
||||||
// weight: danaData[1]
|
});
|
||||||
// },
|
})
|
||||||
// {
|
.catch(err => console.error('WC fetch err:', err));
|
||||||
// text: 'Negatif Dana',
|
|
||||||
// weight: danaData[2]
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// text: 'Positif GoPay',
|
|
||||||
// weight: goPayData[0]
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// text: 'Netral GoPay',
|
|
||||||
// weight: goPayData[1]
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// text: 'Negatif GoPay',
|
|
||||||
// weight: goPayData[2]
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// text: 'Positif Shopee',
|
|
||||||
// weight: shopeeData[0]
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// text: 'Netral Shopee',
|
|
||||||
// weight: shopeeData[1]
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// text: 'Negatif Shopee',
|
|
||||||
// weight: shopeeData[2]
|
|
||||||
// }
|
|
||||||
// ];
|
|
||||||
|
|
||||||
// // Menggunakan WordCloud.js untuk membuat visualisasi
|
|
||||||
// WordCloud(document.getElementById('wordCloud'), {
|
|
||||||
// list: wordData.map(function(item) {
|
|
||||||
// return [item.text, item.weight]; // Format: [kata, ukuran]
|
|
||||||
// }),
|
|
||||||
// gridSize: 10,
|
|
||||||
// weightFactor: 10,
|
|
||||||
// fontFamily: 'Arial',
|
|
||||||
// color: 'random-light',
|
|
||||||
// backgroundColor: '#f4f6f9',
|
|
||||||
// rotateRatio: 0.5
|
|
||||||
// });
|
|
||||||
// var wordData = [{
|
|
||||||
// text: 'Positif Dana',
|
|
||||||
// weight: danaData[0]
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// text: 'Netral Dana',
|
|
||||||
// weight: danaData[1]
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// text: 'Negatif Dana',
|
|
||||||
// weight: danaData[2]
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// text: 'Positif GoPay',
|
|
||||||
// weight: goPayData[0]
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// text: 'Netral GoPay',
|
|
||||||
// weight: goPayData[1]
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// text: 'Negatif GoPay',
|
|
||||||
// weight: goPayData[2]
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// text: 'Positif Shopee',
|
|
||||||
// weight: shopeeData[0]
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// text: 'Netral Shopee',
|
|
||||||
// weight: shopeeData[1]
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// text: 'Negatif Shopee',
|
|
||||||
// weight: shopeeData[2]
|
|
||||||
// }
|
|
||||||
// ];
|
|
||||||
|
|
||||||
// Pastikan canvas sudah siap
|
|
||||||
// setTimeout(() => {
|
|
||||||
// WordCloud(document.getElementById('wordCloud'), {
|
|
||||||
// list: wordData.map(item => [item.text, item.weight]),
|
|
||||||
// gridSize: 8,
|
|
||||||
// weightFactor: 2,
|
|
||||||
// fontFamily: 'Arial',
|
|
||||||
// color: 'random-dark',
|
|
||||||
// backgroundColor: '#f4f6f9',
|
|
||||||
// rotateRatio: 0.5,
|
|
||||||
// minSize: 12
|
|
||||||
// });
|
|
||||||
// }, 100);
|
|
||||||
var danaTotal = {{ $cDana['positif'] + $cDana['netral'] + $cDana['negatif'] }};
|
|
||||||
var goPayTotal = {{ $cGoPay['positif'] + $cGoPay['netral'] + $cGoPay['negatif'] }};
|
|
||||||
var shopeeTotal = {{ $cShopee['positif'] + $cShopee['netral'] + $cShopee['negatif'] }};
|
|
||||||
|
|
||||||
var wordData = [{
|
|
||||||
text: 'Dana',
|
|
||||||
weight: danaTotal
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'GoPay',
|
|
||||||
weight: goPayTotal
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Shopeepay',
|
|
||||||
weight: shopeeTotal
|
|
||||||
}
|
}
|
||||||
];
|
|
||||||
|
|
||||||
// Render Word Cloud
|
// Load pertama kali pakai nilai default di <select>
|
||||||
setTimeout(() => {
|
loadWordCloud(select.value);
|
||||||
WordCloud(document.getElementById('wordCloud'), {
|
|
||||||
list: wordData.map(item => [item.text, item.weight]),
|
select.addEventListener('change', () => {
|
||||||
gridSize: 6,
|
loadWordCloud(select.value);
|
||||||
weightFactor: 4, // semakin besar, semakin beda ukurannya
|
|
||||||
fontFamily: 'Arial',
|
|
||||||
color: 'random-dark',
|
|
||||||
backgroundColor: '#f4f6f9',
|
|
||||||
rotateRatio: 0,
|
|
||||||
minSize: 12
|
|
||||||
});
|
});
|
||||||
}, 100);
|
});
|
||||||
</script>
|
</script>
|
||||||
@endpush
|
@endpush
|
||||||
|
|
|
@ -86,3 +86,4 @@ Route::group(['middleware' => 'guest'], function () {
|
||||||
Route::get('/login', function () {
|
Route::get('/login', function () {
|
||||||
return view('session/login-session');
|
return view('session/login-session');
|
||||||
})->name('login');
|
})->name('login');
|
||||||
|
Route::get('/wordcloud-data', [HomeController::class, 'wordcloudData']);
|
||||||
|
|
Loading…
Reference in New Issue