1.4.0: Updated Profile

This commit is contained in:
2026-01-27 16:51:53 +08:00
parent 28dc02c0c4
commit 0be68a86f6
7 changed files with 342 additions and 81 deletions

View File

@@ -103,7 +103,7 @@
<!-- Footer -->
<footer class="bg-white dark:bg-slate-800 border-t border-slate-200 dark:border-slate-700 mt-auto">
<div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
<p class="text-center text-sm text-gray-500">&copy; 2026 YRTV CS2 Data Platform. All rights reserved.</p>
<p class="text-center text-sm text-gray-500">&copy; 2026 YRTV Data Platform. All rights reserved. 赣ICP备2026001600号</p>
</div>
</footer>

View File

@@ -194,97 +194,86 @@
<!-- Tab: Head to Head -->
<div x-show="tab === 'h2h'" class="bg-white dark:bg-slate-800 shadow rounded-lg overflow-hidden p-6" style="display: none;">
<h3 class="text-lg font-medium text-gray-900 dark:text-white mb-4">Head-to-Head Kills</h3>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
<thead class="bg-gray-50 dark:bg-slate-700">
<tr>
<th class="px-3 py-2 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Killer \ Victim</th>
{% for victim in team2_players %}
<th class="px-3 py-2 text-center text-xs font-medium text-gray-500 dark:text-gray-300 tracking-wider w-20" title="{{ victim.username }}">
<div class="flex flex-col items-center">
{% if victim.avatar_url %}
<img class="h-6 w-6 rounded-full mb-1" src="{{ victim.avatar_url }}">
{% else %}
<div class="h-6 w-6 rounded-full bg-yrtv-100 flex items-center justify-center text-yrtv-600 font-bold text-xs border border-yrtv-200 mb-1">
{{ (victim.username or victim.steam_id_64)[:2] | upper }}
</div>
{% endif %}
<span class="truncate w-16 text-center">{{ victim.username or 'Player' }}</span>
</div>
</th>
{% endfor %}
</tr>
</thead>
<tbody class="bg-white dark:bg-slate-800 divide-y divide-gray-200 dark:divide-gray-700">
{% for killer in team1_players %}
<tr>
<td class="px-3 py-2 whitespace-nowrap font-medium text-gray-900 dark:text-white flex items-center">
{% if killer.avatar_url %}
<img class="h-6 w-6 rounded-full mr-2" src="{{ killer.avatar_url }}">
{% else %}
<div class="h-6 w-6 rounded-full bg-yrtv-100 flex items-center justify-center text-yrtv-600 font-bold text-xs border border-yrtv-200 mr-2">
{{ (killer.username or killer.steam_id_64)[:2] | upper }}
</div>
{% endif %}
<span class="truncate w-24">{{ killer.username or 'Player' }}</span>
</td>
{% for victim in team2_players %}
{% set kills = h2h_matrix.get(killer.steam_id_64, {}).get(victim.steam_id_64, 0) %}
<td class="px-3 py-2 text-center text-sm border-l border-gray-100 dark:border-gray-700
{% if kills > 0 %}font-bold text-gray-900 dark:text-white{% else %}text-gray-300 dark:text-gray-600{% endif %}"
style="{% if kills > 0 %}background-color: rgba(239, 68, 68, {{ kills * 0.1 }}){% endif %}">
{{ kills if kills > 0 else '-' }}
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
<div class="flex justify-between items-end mb-6">
<div>
<h3 class="text-lg font-bold text-gray-900 dark:text-white">Head-to-Head Matrix</h3>
<p class="text-sm text-gray-500 mt-1">Shows <span class="font-bold text-green-600 bg-green-50 px-1 rounded">Kills</span> : <span class="font-bold text-red-500 bg-red-50 px-1 rounded">Deaths</span> interaction between players</p>
</div>
<div class="text-xs text-gray-400 font-mono">
Row: Team 1 Players<br>
Col: Team 2 Players
</div>
</div>
<div class="my-6 border-t border-gray-200 dark:border-gray-700"></div>
<div class="overflow-x-auto">
<div class="overflow-x-auto rounded-xl border border-gray-200 dark:border-gray-700">
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
<thead class="bg-gray-50 dark:bg-slate-700">
<thead class="bg-gray-50 dark:bg-slate-700/50">
<tr>
<th class="px-3 py-2 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Killer \ Victim</th>
{% for victim in team1_players %}
<th class="px-3 py-2 text-center text-xs font-medium text-gray-500 dark:text-gray-300 tracking-wider w-20" title="{{ victim.username }}">
<div class="flex flex-col items-center">
{% if victim.avatar_url %}
<img class="h-6 w-6 rounded-full mb-1" src="{{ victim.avatar_url }}">
{% else %}
<div class="h-6 w-6 rounded-full bg-yrtv-100 flex items-center justify-center text-yrtv-600 font-bold text-xs border border-yrtv-200 mb-1">
{{ (victim.username or victim.steam_id_64)[:2] | upper }}
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 dark:text-gray-400 uppercase tracking-wider bg-gray-50 dark:bg-slate-700/50 sticky left-0 z-10">
Team 1 \ Team 2
</th>
{% for victim in team2_players %}
<th class="px-2 py-3 text-center text-xs font-medium text-gray-500 dark:text-gray-300 tracking-wider min-w-[80px]" title="{{ victim.username }}">
<div class="flex flex-col items-center group">
<div class="relative">
{% if victim.avatar_url %}
<img class="h-8 w-8 rounded-full mb-1 border-2 border-transparent group-hover:border-yrtv-400 transition-all" src="{{ victim.avatar_url }}">
{% else %}
<div class="h-8 w-8 rounded-full bg-yrtv-100 flex items-center justify-center text-yrtv-600 font-bold text-xs border-2 border-yrtv-200 mb-1 group-hover:border-yrtv-400 transition-all">
{{ (victim.username or victim.steam_id_64)[:2] | upper }}
</div>
{% endif %}
</div>
{% endif %}
<span class="truncate w-16 text-center">{{ victim.username or 'Player' }}</span>
<span class="truncate w-20 text-center font-bold text-gray-700 dark:text-gray-300 group-hover:text-yrtv-600 transition-colors text-[10px]">{{ victim.username or 'Player' }}</span>
</div>
</th>
{% endfor %}
</tr>
</thead>
<tbody class="bg-white dark:bg-slate-800 divide-y divide-gray-200 dark:divide-gray-700">
{% for killer in team2_players %}
<tr>
<td class="px-3 py-2 whitespace-nowrap font-medium text-gray-900 dark:text-white flex items-center">
{% if killer.avatar_url %}
<img class="h-6 w-6 rounded-full mr-2" src="{{ killer.avatar_url }}">
{% else %}
<div class="h-6 w-6 rounded-full bg-yrtv-100 flex items-center justify-center text-yrtv-600 font-bold text-xs border border-yrtv-200 mr-2">
{{ (killer.username or killer.steam_id_64)[:2] | upper }}
<tbody class="bg-white dark:bg-slate-800 divide-y divide-gray-100 dark:divide-gray-700">
{% for killer in team1_players %}
<tr class="hover:bg-gray-50 dark:hover:bg-slate-700/30 transition-colors">
<td class="px-4 py-3 whitespace-nowrap font-medium text-gray-900 dark:text-white bg-white dark:bg-slate-800 sticky left-0 z-10 border-r border-gray-100 dark:border-gray-700 shadow-sm">
<div class="flex items-center group">
{% if killer.avatar_url %}
<img class="h-8 w-8 rounded-full mr-3 border-2 border-transparent group-hover:border-blue-400 transition-all" src="{{ killer.avatar_url }}">
{% else %}
<div class="h-8 w-8 rounded-full bg-blue-100 flex items-center justify-center text-blue-600 font-bold text-xs border-2 border-blue-200 mr-3 group-hover:border-blue-400 transition-all">
{{ (killer.username or killer.steam_id_64)[:2] | upper }}
</div>
{% endif %}
<span class="truncate w-28 font-bold group-hover:text-blue-600 transition-colors">{{ killer.username or 'Player' }}</span>
</div>
</td>
{% for victim in team2_players %}
<!-- Kills: Killer -> Victim -->
{% set kills = h2h_matrix.get(killer.steam_id_64, {}).get(victim.steam_id_64, 0) %}
<!-- Deaths: Victim -> Killer (which is Killer's death) -->
{% set deaths = h2h_matrix.get(victim.steam_id_64, {}).get(killer.steam_id_64, 0) %}
<td class="px-2 py-3 text-center border-l border-gray-50 dark:border-gray-700/50">
<div class="flex items-center justify-center gap-1.5 font-mono">
<!-- Kills -->
<span class="{% if kills > deaths %}font-black text-lg text-green-600{% elif kills > 0 %}font-bold text-gray-900 dark:text-white{% else %}text-gray-300 dark:text-gray-600 text-xs{% endif %}">
{{ kills }}
</span>
<span class="text-gray-300 dark:text-gray-600 text-[10px]">:</span>
<!-- Deaths -->
<span class="{% if deaths > kills %}font-black text-lg text-red-500{% elif deaths > 0 %}font-bold text-gray-900 dark:text-white{% else %}text-gray-300 dark:text-gray-600 text-xs{% endif %}">
{{ deaths }}
</span>
</div>
<!-- Interaction Bar (Optional visual) -->
{% if kills + deaths > 0 %}
<div class="w-full h-1 bg-gray-100 dark:bg-slate-700 rounded-full mt-1 overflow-hidden flex">
{% set total = kills + deaths %}
<div class="bg-green-500 h-full" style="width: {{ (kills / total * 100) }}%"></div>
<div class="bg-red-500 h-full" style="width: {{ (deaths / total * 100) }}%"></div>
</div>
{% endif %}
<span class="truncate w-24">{{ killer.username or 'Player' }}</span>
</td>
{% for victim in team1_players %}
{% set kills = h2h_matrix.get(killer.steam_id_64, {}).get(victim.steam_id_64, 0) %}
<td class="px-3 py-2 text-center text-sm border-l border-gray-100 dark:border-gray-700
{% if kills > 0 %}font-bold text-gray-900 dark:text-white{% else %}text-gray-300 dark:text-gray-600{% endif %}"
style="{% if kills > 0 %}background-color: rgba(59, 130, 246, {{ kills * 0.1 }}){% endif %}">
{{ kills if kills > 0 else '-' }}
</td>
{% endfor %}
</tr>

View File

@@ -416,6 +416,65 @@
{{ vs_item_val('Multi-Assist Rate (多助攻)', t_ma, ct_ma, '{:.1%}') }}
</div>
</div>
<!-- New Section: Party & Stratification -->
<div>
<h4 class="text-xs font-black text-gray-400 uppercase tracking-widest mb-4 border-b border-gray-100 dark:border-slate-700 pb-2">
👥 组排与分层表现 (Party & Stratification)
</h4>
<div class="space-y-8">
<!-- Group 1: Party Size -->
<div>
<h5 class="text-[10px] font-bold text-gray-400 uppercase tracking-wider mb-3">Party Size Performance (组排表现)</h5>
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-y-6 gap-x-4">
{{ detail_item('Solo Win% (单排胜率)', features['party_1_win_rate'], 'party_1_win_rate', '{:.1%}') }}
{{ detail_item('Solo Rating (单排分)', features['party_1_rating'], 'party_1_rating') }}
{{ detail_item('Solo ADR (单排伤)', features['party_1_adr'], 'party_1_adr', '{:.1f}') }}
{{ detail_item('Duo Win% (双排胜率)', features['party_2_win_rate'], 'party_2_win_rate', '{:.1%}') }}
{{ detail_item('Duo Rating (双排分)', features['party_2_rating'], 'party_2_rating') }}
{{ detail_item('Duo ADR (双排伤)', features['party_2_adr'], 'party_2_adr', '{:.1f}') }}
{{ detail_item('Trio Win% (三排胜率)', features['party_3_win_rate'], 'party_3_win_rate', '{:.1%}') }}
{{ detail_item('Trio Rating (三排分)', features['party_3_rating'], 'party_3_rating') }}
{{ detail_item('Trio ADR (三排伤)', features['party_3_adr'], 'party_3_adr', '{:.1f}') }}
{{ detail_item('Quad Win% (四排胜率)', features['party_4_win_rate'], 'party_4_win_rate', '{:.1%}') }}
{{ detail_item('Quad Rating (四排分)', features['party_4_rating'], 'party_4_rating') }}
{{ detail_item('Quad ADR (四排伤)', features['party_4_adr'], 'party_4_adr', '{:.1f}') }}
{{ detail_item('Full Win% (五排胜率)', features['party_5_win_rate'], 'party_5_win_rate', '{:.1%}') }}
{{ detail_item('Full Rating (五排分)', features['party_5_rating'], 'party_5_rating') }}
{{ detail_item('Full ADR (五排伤)', features['party_5_adr'], 'party_5_adr', '{:.1f}') }}
</div>
</div>
<!-- Group 2: Rating Distribution -->
<div>
<h5 class="text-[10px] font-bold text-gray-400 uppercase tracking-wider mb-3">Performance Tiers (表现分层)</h5>
<div class="grid grid-cols-2 md:grid-cols-4 gap-y-6 gap-x-4">
{{ detail_item('Carry Rate (>1.5)', features['rating_dist_carry_rate'], 'rating_dist_carry_rate', '{:.1%}') }}
{{ detail_item('Normal Rate (1.0-1.5)', features['rating_dist_normal_rate'], 'rating_dist_normal_rate', '{:.1%}') }}
{{ detail_item('Sacrifice Rate (0.6-1.0)', features['rating_dist_sacrifice_rate'], 'rating_dist_sacrifice_rate', '{:.1%}') }}
{{ detail_item('Sleeping Rate (<0.6)', features['rating_dist_sleeping_rate'], 'rating_dist_sleeping_rate', '{:.1%}') }}
</div>
</div>
<!-- Group 3: ELO Stratification -->
<div>
<h5 class="text-[10px] font-bold text-gray-400 uppercase tracking-wider mb-3">Performance vs ELO (不同分段表现)</h5>
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-y-6 gap-x-4">
{{ detail_item('<1200 Rating', features['elo_lt1200_rating'], 'elo_lt1200_rating') }}
{{ detail_item('1200-1400 Rating', features['elo_1200_1400_rating'], 'elo_1200_1400_rating') }}
{{ detail_item('1400-1600 Rating', features['elo_1400_1600_rating'], 'elo_1400_1600_rating') }}
{{ detail_item('1600-1800 Rating', features['elo_1600_1800_rating'], 'elo_1600_1800_rating') }}
{{ detail_item('1800-2000 Rating', features['elo_1800_2000_rating'], 'elo_1800_2000_rating') }}
{{ detail_item('>2000 Rating', features['elo_gt2000_rating'], 'elo_gt2000_rating') }}
</div>
</div>
</div>
</div>
</div>
</div>