162 lines
5.8 KiB
HTML
162 lines
5.8 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block content %}
|
|
<div class="space-y-6">
|
|
<div class="bg-white dark:bg-slate-800 shadow rounded-lg p-6">
|
|
<h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-6">数据对比中心 (Data Center)</h2>
|
|
|
|
<!-- Search & Add -->
|
|
<div class="mb-6 relative">
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">添加对比玩家</label>
|
|
<input type="text" id="playerSearch" placeholder="输入 ID 或昵称搜索..." class="w-full border border-gray-300 rounded-md py-2 px-4 dark:bg-slate-700 dark:text-white">
|
|
<div id="searchResults" class="absolute z-10 w-full bg-white dark:bg-slate-700 shadow-lg rounded-b-md hidden"></div>
|
|
</div>
|
|
|
|
<!-- Selected Players Tags -->
|
|
<div id="selectedPlayers" class="flex flex-wrap gap-2 mb-6">
|
|
<!-- Tags will be injected here -->
|
|
</div>
|
|
|
|
<!-- Chart -->
|
|
<div class="relative h-96">
|
|
<canvas id="compareChart"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const searchInput = document.getElementById('playerSearch');
|
|
const resultsDiv = document.getElementById('searchResults');
|
|
const selectedDiv = document.getElementById('selectedPlayers');
|
|
|
|
let selectedIds = [];
|
|
let chartInstance = null;
|
|
|
|
// Init Chart
|
|
const ctx = document.getElementById('compareChart').getContext('2d');
|
|
chartInstance = new Chart(ctx, {
|
|
type: 'radar',
|
|
data: {
|
|
labels: ['STA', 'BAT', 'HPS', 'PTL', 'SIDE', 'UTIL'],
|
|
datasets: []
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
scales: {
|
|
r: {
|
|
beginAtZero: true,
|
|
suggestedMax: 2.0
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
// Search
|
|
let debounceTimer;
|
|
searchInput.addEventListener('input', function() {
|
|
clearTimeout(debounceTimer);
|
|
const query = this.value;
|
|
if (query.length < 2) {
|
|
resultsDiv.classList.add('hidden');
|
|
return;
|
|
}
|
|
|
|
debounceTimer = setTimeout(() => {
|
|
fetch(`/players/api/search?q=${query}`)
|
|
.then(r => r.json())
|
|
.then(data => {
|
|
resultsDiv.innerHTML = '';
|
|
if (data.length > 0) {
|
|
resultsDiv.classList.remove('hidden');
|
|
data.forEach(p => {
|
|
const div = document.createElement('div');
|
|
div.className = 'p-2 hover:bg-gray-100 dark:hover:bg-slate-600 cursor-pointer text-gray-900 dark:text-white';
|
|
div.innerText = `${p.username} (${p.steam_id})`;
|
|
div.onclick = () => addPlayer(p);
|
|
resultsDiv.appendChild(div);
|
|
});
|
|
} else {
|
|
resultsDiv.classList.add('hidden');
|
|
}
|
|
});
|
|
}, 300);
|
|
});
|
|
|
|
// Hide results on click outside
|
|
document.addEventListener('click', function(e) {
|
|
if (!searchInput.contains(e.target) && !resultsDiv.contains(e.target)) {
|
|
resultsDiv.classList.add('hidden');
|
|
}
|
|
});
|
|
|
|
function addPlayer(player) {
|
|
if (selectedIds.includes(player.steam_id)) return;
|
|
selectedIds.push(player.steam_id);
|
|
|
|
// Add Tag
|
|
const tag = document.createElement('span');
|
|
tag.className = 'inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-yrtv-100 text-yrtv-800';
|
|
tag.innerHTML = `
|
|
${player.username}
|
|
<button type="button" class="flex-shrink-0 ml-1.5 h-4 w-4 rounded-full inline-flex items-center justify-center text-yrtv-400 hover:bg-yrtv-200 hover:text-yrtv-500 focus:outline-none" onclick="removePlayer('${player.steam_id}', this)">
|
|
<span class="sr-only">Remove</span>
|
|
×
|
|
</button>
|
|
`;
|
|
selectedDiv.appendChild(tag);
|
|
|
|
// Fetch Stats and Update Chart
|
|
updateChart();
|
|
|
|
searchInput.value = '';
|
|
resultsDiv.classList.add('hidden');
|
|
}
|
|
|
|
window.removePlayer = function(id, btn) {
|
|
selectedIds = selectedIds.filter(sid => sid !== id);
|
|
btn.parentElement.remove();
|
|
updateChart();
|
|
}
|
|
|
|
function updateChart() {
|
|
if (selectedIds.length === 0) {
|
|
chartInstance.data.datasets = [];
|
|
chartInstance.update();
|
|
return;
|
|
}
|
|
|
|
const ids = selectedIds.join(',');
|
|
fetch(`/players/api/batch_stats?ids=${ids}`)
|
|
.then(r => r.json())
|
|
.then(data => {
|
|
const datasets = data.map((p, index) => {
|
|
const colors = [
|
|
'rgba(124, 58, 237, 1)', 'rgba(16, 185, 129, 1)', 'rgba(239, 68, 68, 1)',
|
|
'rgba(59, 130, 246, 1)', 'rgba(245, 158, 11, 1)'
|
|
];
|
|
const color = colors[index % colors.length];
|
|
|
|
return {
|
|
label: p.username,
|
|
data: [
|
|
p.radar.STA, p.radar.BAT, p.radar.HPS,
|
|
p.radar.PTL, p.radar.SIDE, p.radar.UTIL
|
|
],
|
|
backgroundColor: color.replace('1)', '0.2)'),
|
|
borderColor: color,
|
|
pointBackgroundColor: color
|
|
};
|
|
});
|
|
|
|
chartInstance.data.datasets = datasets;
|
|
chartInstance.update();
|
|
});
|
|
}
|
|
});
|
|
</script>
|
|
{% endblock %}
|