3.0.3: Cant fix team avg. removed.
This commit is contained in:
@@ -40,7 +40,7 @@
|
||||
<!-- Mini Stats -->
|
||||
<div class="grid grid-cols-3 gap-x-4 gap-y-2 text-xs text-gray-600 dark:text-gray-300 mb-4 w-full text-center">
|
||||
<div>
|
||||
<span class="block font-bold">{{ "%.2f"|format(player.basic_avg_rating|default(0)) }}</span>
|
||||
<span class="block font-bold">{{ "%.2f"|format(player.core_avg_rating2|default(player.basic_avg_rating)|default(0)) }}</span>
|
||||
<span class="text-gray-400">Rating</span>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
@@ -869,6 +869,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
// Prepare Distribution Data
|
||||
const dist = data.radar_dist || {};
|
||||
const hasDist = Object.keys(dist).length > 0;
|
||||
const getDist = (key) => dist[key] || { rank: '?', avg: 0 };
|
||||
|
||||
// Map friendly names to keys
|
||||
@@ -877,41 +878,49 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
const rawLabels = ['枪法 (Aim)', '生存 (Defense)', '道具 (Utility)', '残局 (Clutch)', '经济 (Economy)', '节奏 (Pace)', '手枪 (Pistol)', '稳定 (Stability)'];
|
||||
|
||||
const labels = rawLabels.map((l, i) => {
|
||||
if (!hasDist) return l;
|
||||
const k = keys[i];
|
||||
const d = getDist(k);
|
||||
return `${l} #${d.rank}`;
|
||||
});
|
||||
|
||||
const teamAvgs = keys.map(k => getDist(k).avg);
|
||||
let teamAvgs;
|
||||
if (data.team_avg_radar) {
|
||||
teamAvgs = keys.map(k => data.team_avg_radar[k] || 0);
|
||||
}
|
||||
|
||||
const datasets = [{
|
||||
label: 'Player',
|
||||
data: [
|
||||
data.radar.AIM, data.radar.DEFENSE, data.radar.UTILITY,
|
||||
data.radar.CLUTCH, data.radar.ECONOMY, data.radar.PACE,
|
||||
data.radar.PISTOL, data.radar.STABILITY
|
||||
],
|
||||
backgroundColor: 'rgba(124, 58, 237, 0.2)',
|
||||
borderColor: '#7c3aed',
|
||||
borderWidth: 2,
|
||||
pointBackgroundColor: '#7c3aed',
|
||||
pointBorderColor: '#fff',
|
||||
pointHoverBackgroundColor: '#fff',
|
||||
pointHoverBorderColor: '#7c3aed'
|
||||
}];
|
||||
if (teamAvgs) {
|
||||
datasets.push({
|
||||
label: 'Team Avg',
|
||||
data: teamAvgs,
|
||||
backgroundColor: 'rgba(148, 163, 184, 0.2)',
|
||||
borderColor: '#94a3b8',
|
||||
borderWidth: 2,
|
||||
pointRadius: 0,
|
||||
borderDash: [5, 5]
|
||||
});
|
||||
}
|
||||
|
||||
new Chart(ctxRadar, {
|
||||
type: 'radar',
|
||||
data: {
|
||||
labels: labels,
|
||||
datasets: [{
|
||||
label: 'Player',
|
||||
data: [
|
||||
data.radar.AIM, data.radar.DEFENSE, data.radar.UTILITY,
|
||||
data.radar.CLUTCH, data.radar.ECONOMY, data.radar.PACE,
|
||||
data.radar.PISTOL, data.radar.STABILITY
|
||||
],
|
||||
backgroundColor: 'rgba(124, 58, 237, 0.2)',
|
||||
borderColor: '#7c3aed',
|
||||
borderWidth: 2,
|
||||
pointBackgroundColor: '#7c3aed',
|
||||
pointBorderColor: '#fff',
|
||||
pointHoverBackgroundColor: '#fff',
|
||||
pointHoverBorderColor: '#7c3aed'
|
||||
},
|
||||
{
|
||||
label: 'Team Avg',
|
||||
data: teamAvgs,
|
||||
backgroundColor: 'rgba(148, 163, 184, 0.2)', // Slate-400
|
||||
borderColor: '#94a3b8',
|
||||
borderWidth: 2,
|
||||
pointRadius: 0,
|
||||
borderDash: [5, 5]
|
||||
}]
|
||||
datasets: datasets
|
||||
},
|
||||
options: {
|
||||
plugins: {
|
||||
|
||||
@@ -120,7 +120,7 @@
|
||||
|
||||
<span class="text-sm font-bold truncate w-full text-center dark:text-white mb-1" x-text="p.username || p.name"></span>
|
||||
<div class="px-2.5 py-1 bg-white dark:bg-slate-900 rounded-full text-xs text-gray-500 dark:text-gray-400 shadow-inner border border-gray-100 dark:border-slate-700">
|
||||
Rating: <span class="font-bold text-yrtv-600" x-text="(p.stats?.basic_avg_rating || 0).toFixed(2)"></span>
|
||||
Rating: <span class="font-bold text-yrtv-600" x-text="((p.stats?.core_avg_rating2 || p.stats?.basic_avg_rating) || 0).toFixed(2)"></span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -153,6 +153,15 @@
|
||||
<span class="text-sm text-gray-500">Team Rating</span>
|
||||
<span class="text-4xl font-black text-yrtv-600 tracking-tight" x-text="analysisResult.avg_stats.rating.toFixed(2)"></span>
|
||||
</div>
|
||||
<div class="flex items-baseline gap-2">
|
||||
<span class="text-sm text-gray-500">Chemistry Score</span>
|
||||
<span class="text-4xl font-black text-blue-600 tracking-tight" x-text="(analysisResult.chemistry_score || 0).toFixed(0)"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Analysis Radar Chart -->
|
||||
<div class="bg-gray-50 dark:bg-slate-700 p-4 rounded-xl border border-gray-100 dark:border-slate-600 h-[300px]">
|
||||
<canvas id="analysisRadarChart"></canvas>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-3 gap-6 text-center">
|
||||
@@ -336,6 +345,7 @@ function tacticsApp() {
|
||||
// Analysis State
|
||||
analysisLineup: [],
|
||||
analysisResult: null,
|
||||
analysisChart: null,
|
||||
debounceTimer: null,
|
||||
|
||||
// Data Center State
|
||||
@@ -410,7 +420,8 @@ function tacticsApp() {
|
||||
steam_id_64: player.steam_id_64,
|
||||
username: player.username || player.name,
|
||||
name: player.name || player.username,
|
||||
avatar_url: player.avatar_url
|
||||
avatar_url: player.avatar_url,
|
||||
stats: player.stats || { basic_avg_rating: 0.0 } // Include stats for drag preview
|
||||
};
|
||||
event.dataTransfer.setData('text/plain', JSON.stringify(payload));
|
||||
event.dataTransfer.effectAllowed = 'copy';
|
||||
@@ -529,8 +540,9 @@ function tacticsApp() {
|
||||
const datasets = rawData.map((p, idx) => {
|
||||
const color = this.getPlayerColor(idx);
|
||||
const d = [
|
||||
p.radar.BAT || 0, p.radar.PTL || 0, p.radar.HPS || 0,
|
||||
p.radar.SIDE || 0, p.radar.UTIL || 0, p.radar.STA || 0
|
||||
p.radar.AIM || 0, p.radar.DEFENSE || 0, p.radar.UTILITY || 0,
|
||||
p.radar.CLUTCH || 0, p.radar.ECONOMY || 0, p.radar.PACE || 0,
|
||||
p.radar.PISTOL || 0, p.radar.STABILITY || 0
|
||||
];
|
||||
|
||||
return {
|
||||
@@ -548,7 +560,7 @@ function tacticsApp() {
|
||||
this.radarChart = new Chart(ctx, {
|
||||
type: 'radar',
|
||||
data: {
|
||||
labels: ['BAT (火力)', 'PTL (手枪)', 'HPS (抗压)', 'SIDE (阵营)', 'UTIL (道具)', 'STA (稳定)'],
|
||||
labels: ['AIM (枪法)', 'DEF (生存)', 'UTIL (道具)', 'CLUTCH (残局)', 'ECO (经济)', 'PACE (节奏)', 'PISTOL (手枪)', 'STA (稳定)'],
|
||||
datasets: datasets
|
||||
},
|
||||
options: {
|
||||
@@ -595,7 +607,7 @@ function tacticsApp() {
|
||||
this.radarChart = new Chart(ctx, {
|
||||
type: 'radar',
|
||||
data: {
|
||||
labels: ['BAT (火力)', 'PTL (手枪)', 'HPS (抗压)', 'SIDE (阵营)', 'UTIL (道具)', 'STA (稳定)'],
|
||||
labels: ['AIM (枪法)', 'DEF (生存)', 'UTIL (道具)', 'CLUTCH (残局)', 'ECO (经济)', 'PACE (节奏)', 'PISTOL (手枪)', 'STA (稳定)'],
|
||||
datasets: []
|
||||
},
|
||||
options: {
|
||||
@@ -659,6 +671,59 @@ function tacticsApp() {
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
this.analysisResult = data;
|
||||
this.$nextTick(() => {
|
||||
this.updateAnalysisChart();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
updateAnalysisChart() {
|
||||
if (this.analysisChart) {
|
||||
this.analysisChart.destroy();
|
||||
this.analysisChart = null;
|
||||
}
|
||||
|
||||
const canvas = document.getElementById('analysisRadarChart');
|
||||
if (!canvas || !this.analysisResult || !this.analysisResult.radar_stats) return;
|
||||
|
||||
const stats = this.analysisResult.radar_stats;
|
||||
const data = [
|
||||
stats.AIM || 0, stats.DEFENSE || 0, stats.UTILITY || 0,
|
||||
stats.CLUTCH || 0, stats.ECONOMY || 0, stats.PACE || 0,
|
||||
stats.PISTOL || 0, stats.STABILITY || 0
|
||||
];
|
||||
|
||||
const ctx = canvas.getContext('2d');
|
||||
this.analysisChart = new Chart(ctx, {
|
||||
type: 'radar',
|
||||
data: {
|
||||
labels: ['AIM (枪法)', 'DEF (生存)', 'UTIL (道具)', 'CLUTCH (残局)', 'ECO (经济)', 'PACE (节奏)', 'PISTOL (手枪)', 'STA (稳定)'],
|
||||
datasets: [{
|
||||
label: 'Team Average',
|
||||
data: data,
|
||||
backgroundColor: 'rgba(59, 130, 246, 0.2)',
|
||||
borderColor: '#3b82f6',
|
||||
borderWidth: 2,
|
||||
pointRadius: 3
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
r: {
|
||||
min: 0, max: 100,
|
||||
ticks: { display: false, stepSize: 20 },
|
||||
pointLabels: {
|
||||
font: { size: 11, weight: 'bold' },
|
||||
color: (ctx) => document.documentElement.classList.contains('dark') ? '#cbd5e1' : '#374151'
|
||||
},
|
||||
grid: {
|
||||
color: (ctx) => document.documentElement.classList.contains('dark') ? 'rgba(51, 65, 85, 0.5)' : 'rgba(229, 231, 235, 0.8)'
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: { legend: { display: false } }
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -69,14 +69,18 @@
|
||||
</div>
|
||||
|
||||
<!-- Stats Grid -->
|
||||
<div class="grid grid-cols-2 gap-2 w-full text-center mb-auto">
|
||||
<div class="grid grid-cols-3 gap-1 w-full text-center mb-auto">
|
||||
<div class="bg-gray-50 dark:bg-slate-700 rounded p-1">
|
||||
<div class="text-xs text-gray-400">Rating</div>
|
||||
<div class="font-bold text-yrtv-600 dark:text-yrtv-400" x-text="(player.stats?.core_avg_rating || 0).toFixed(2)"></div>
|
||||
<div class="text-[10px] text-gray-400">Rating</div>
|
||||
<div class="font-bold text-yrtv-600 dark:text-yrtv-400 text-sm" x-text="(player.stats?.core_avg_rating2 || player.stats?.core_avg_rating || 0).toFixed(2)"></div>
|
||||
</div>
|
||||
<div class="bg-gray-50 dark:bg-slate-700 rounded p-1">
|
||||
<div class="text-xs text-gray-400">K/D</div>
|
||||
<div class="font-bold" x-text="(player.stats?.core_avg_kd || 0).toFixed(2)"></div>
|
||||
<div class="text-[10px] text-gray-400">K/D</div>
|
||||
<div class="font-bold text-sm" x-text="(player.stats?.core_avg_kd || 0).toFixed(2)"></div>
|
||||
</div>
|
||||
<div class="bg-gray-50 dark:bg-slate-700 rounded p-1">
|
||||
<div class="text-[10px] text-gray-400">OVR</div>
|
||||
<div class="font-black text-sm text-yrtv-700 dark:text-yrtv-300" x-text="(player.stats?.score_overall || 0).toFixed(0)"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -16,7 +16,10 @@
|
||||
<a href="{{ url_for('players.detail', steam_id=p.steam_id_64) }}" class="text-sm font-medium text-gray-900 dark:text-white hover:text-yrtv-600 truncate w-full text-center">
|
||||
{{ p.username }}
|
||||
</a>
|
||||
<span class="text-xs text-gray-500">Rating: {{ "%.2f"|format(p.rating if p.rating else 0) }}</span>
|
||||
<div class="flex gap-2 text-xs text-gray-500 mt-1">
|
||||
<span>R: <span class="font-bold {{ 'text-green-600' if p.rating >= 1.1 else '' }}">{{ "%.2f"|format(p.rating if p.rating else 0) }}</span></span>
|
||||
<span class="border-l border-gray-300 pl-2">OVR: <span class="font-bold text-yrtv-600">{{ p.stats.get('score_overall', 0)|int }}</span></span>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user