mirror of
https://github.com/Xe138/AI-Trader.git
synced 2026-04-01 17:17:24 -04:00
update frontend
This commit is contained in:
@@ -375,6 +375,12 @@ body {
|
||||
background: rgba(0, 212, 255, 0.1);
|
||||
}
|
||||
|
||||
.legend-icon-img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.legend-color {
|
||||
width: 4px;
|
||||
height: 42px;
|
||||
|
||||
@@ -18,6 +18,27 @@ const agentColors = [
|
||||
'#06ffa5' // Mint
|
||||
];
|
||||
|
||||
// Cache for loaded SVG images
|
||||
const iconImageCache = {};
|
||||
|
||||
// Function to load SVG as image
|
||||
function loadIconImage(iconPath) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (iconImageCache[iconPath]) {
|
||||
resolve(iconImageCache[iconPath]);
|
||||
return;
|
||||
}
|
||||
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
iconImageCache[iconPath] = img;
|
||||
resolve(img);
|
||||
};
|
||||
img.onerror = reject;
|
||||
img.src = iconPath;
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize the page
|
||||
async function init() {
|
||||
showLoading();
|
||||
@@ -28,6 +49,17 @@ async function init() {
|
||||
allAgentsData = await dataLoader.loadAllAgentsData();
|
||||
console.log('Data loaded:', allAgentsData);
|
||||
|
||||
// Preload all agent icons
|
||||
const agentNames = Object.keys(allAgentsData);
|
||||
const iconPromises = agentNames.map(agentName => {
|
||||
const iconPath = dataLoader.getAgentIcon(agentName);
|
||||
return loadIconImage(iconPath).catch(err => {
|
||||
console.warn(`Failed to load icon for ${agentName}:`, err);
|
||||
});
|
||||
});
|
||||
await Promise.all(iconPromises);
|
||||
console.log('Icons preloaded');
|
||||
|
||||
// Update stats
|
||||
updateStats();
|
||||
|
||||
@@ -171,11 +203,7 @@ function createChart() {
|
||||
const x = lastPoint.x;
|
||||
const y = lastPoint.y;
|
||||
|
||||
// Draw icon
|
||||
ctx.save();
|
||||
ctx.font = 'bold 22px Arial';
|
||||
ctx.textAlign = 'left';
|
||||
ctx.textBaseline = 'middle';
|
||||
|
||||
// Draw background circle with glow
|
||||
const iconSize = 30;
|
||||
@@ -191,9 +219,12 @@ function createChart() {
|
||||
// Reset shadow
|
||||
ctx.shadowBlur = 0;
|
||||
|
||||
// Draw icon
|
||||
ctx.fillStyle = '#0a0e27';
|
||||
ctx.fillText(dataset.agentIcon, x + 22 - 9, y);
|
||||
// Draw icon image if loaded
|
||||
if (iconImageCache[dataset.agentIcon]) {
|
||||
const img = iconImageCache[dataset.agentIcon];
|
||||
const imgSize = iconSize * 0.6; // Icon slightly smaller than circle
|
||||
ctx.drawImage(img, x + 22 - imgSize/2, y - imgSize/2, imgSize, imgSize);
|
||||
}
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
@@ -242,8 +273,8 @@ function createChart() {
|
||||
label: function(context) {
|
||||
const label = context.dataset.label || '';
|
||||
const value = dataLoader.formatCurrency(context.parsed.y);
|
||||
const icon = context.dataset.agentIcon || '';
|
||||
return `${icon} ${label}: ${value}`;
|
||||
// Tooltips don't support images, so just show label and value
|
||||
return `${label}: ${value}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -311,13 +342,15 @@ function createLegend() {
|
||||
|
||||
const returnValue = data.return;
|
||||
const returnClass = returnValue >= 0 ? 'positive' : 'negative';
|
||||
const icon = dataLoader.getAgentIcon(agentName);
|
||||
const iconPath = dataLoader.getAgentIcon(agentName);
|
||||
const brandColor = dataLoader.getAgentBrandColor(agentName);
|
||||
|
||||
const legendItem = document.createElement('div');
|
||||
legendItem.className = 'legend-item';
|
||||
legendItem.innerHTML = `
|
||||
<div class="legend-icon" ${brandColor ? `style="background: ${brandColor}20; color: ${brandColor};"` : ''}>${icon}</div>
|
||||
<div class="legend-icon" ${brandColor ? `style="background: ${brandColor}20;"` : ''}>
|
||||
<img src="${iconPath}" alt="${agentName}" class="legend-icon-img" />
|
||||
</div>
|
||||
<div class="legend-color" style="background: ${color}; border-style: ${borderStyle};"></div>
|
||||
<div class="legend-info">
|
||||
<div class="legend-name">${dataLoader.getAgentDisplayName(agentName)}</div>
|
||||
|
||||
@@ -359,17 +359,28 @@ class DataLoader {
|
||||
return names[agentName] || agentName;
|
||||
}
|
||||
|
||||
// Get icon for agent (emoji/symbol representation)
|
||||
// Get icon for agent (SVG file path)
|
||||
getAgentIcon(agentName) {
|
||||
const icons = {
|
||||
'gemini-2.5-flash': '🤖',
|
||||
'qwen3-max': '🧠',
|
||||
'gpt-5': '🔮',
|
||||
'claude-3.7-sonnet': '🎭',
|
||||
'deepseek-chat-v3.1': '🔬',
|
||||
'QQQ': '📈'
|
||||
'gemini-2.5-flash': './figs/google.svg',
|
||||
'qwen3-max': './figs/qwen.svg',
|
||||
'gpt-5': './figs/openai.svg',
|
||||
'claude-3.7-sonnet': './figs/claude-color.svg',
|
||||
'deepseek-chat-v3.1': './figs/deepseek.svg',
|
||||
'QQQ': './figs/stock.svg' // 使用默认图标
|
||||
};
|
||||
return icons[agentName] || '🤖';
|
||||
return icons[agentName] || './figs/stock.svg';
|
||||
}
|
||||
|
||||
// Get agent name without version suffix for icon lookup
|
||||
getAgentIconKey(agentName) {
|
||||
// 处理可能的版本号变体
|
||||
if (agentName.includes('gemini')) return 'gemini-2.5-flash';
|
||||
if (agentName.includes('qwen')) return 'qwen3-max';
|
||||
if (agentName.includes('gpt')) return 'gpt-5';
|
||||
if (agentName.includes('claude')) return 'claude-3.7-sonnet';
|
||||
if (agentName.includes('deepseek')) return 'deepseek-chat-v3.1';
|
||||
return agentName;
|
||||
}
|
||||
|
||||
// Get brand color for agent
|
||||
|
||||
@@ -45,8 +45,8 @@ function populateAgentSelector() {
|
||||
Object.keys(allAgentsData).forEach(agentName => {
|
||||
const option = document.createElement('option');
|
||||
option.value = agentName;
|
||||
const icon = dataLoader.getAgentIcon(agentName);
|
||||
option.textContent = `${icon} ${dataLoader.getAgentDisplayName(agentName)}`;
|
||||
// Use text only for dropdown options (HTML select doesn't support images well)
|
||||
option.textContent = dataLoader.getAgentDisplayName(agentName);
|
||||
select.appendChild(option);
|
||||
});
|
||||
}
|
||||
|
||||
1
docs/figs/claude-color.svg
Normal file
1
docs/figs/claude-color.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Claude</title><path d="M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z" fill="#D97757" fill-rule="nonzero"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
1
docs/figs/deepseek.svg
Normal file
1
docs/figs/deepseek.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>DeepSeek</title><path d="M23.748 4.482c-.254-.124-.364.113-.512.234-.051.039-.094.09-.137.136-.372.397-.806.657-1.373.626-.829-.046-1.537.214-2.163.848-.133-.782-.575-1.248-1.247-1.548-.352-.156-.708-.311-.955-.65-.172-.241-.219-.51-.305-.774-.055-.16-.11-.323-.293-.35-.2-.031-.278.136-.356.276-.313.572-.434 1.202-.422 1.84.027 1.436.633 2.58 1.838 3.393.137.093.172.187.129.323-.082.28-.18.552-.266.833-.055.179-.137.217-.329.14a5.526 5.526 0 01-1.736-1.18c-.857-.828-1.631-1.742-2.597-2.458a11.365 11.365 0 00-.689-.471c-.985-.957.13-1.743.388-1.836.27-.098.093-.432-.779-.428-.872.004-1.67.295-2.687.684a3.055 3.055 0 01-.465.137 9.597 9.597 0 00-2.883-.102c-1.885.21-3.39 1.102-4.497 2.623C.082 8.606-.231 10.684.152 12.85c.403 2.284 1.569 4.175 3.36 5.653 1.858 1.533 3.997 2.284 6.438 2.14 1.482-.085 3.133-.284 4.994-1.86.47.234.962.327 1.78.397.63.059 1.236-.03 1.705-.128.735-.156.684-.837.419-.961-2.155-1.004-1.682-.595-2.113-.926 1.096-1.296 2.746-2.642 3.392-7.003.05-.347.007-.565 0-.845-.004-.17.035-.237.23-.256a4.173 4.173 0 001.545-.475c1.396-.763 1.96-2.015 2.093-3.517.02-.23-.004-.467-.247-.588zM11.581 18c-2.089-1.642-3.102-2.183-3.52-2.16-.392.024-.321.471-.235.763.09.288.207.486.371.739.114.167.192.416-.113.603-.673.416-1.842-.14-1.897-.167-1.361-.802-2.5-1.86-3.301-3.307-.774-1.393-1.224-2.887-1.298-4.482-.02-.386.093-.522.477-.592a4.696 4.696 0 011.529-.039c2.132.312 3.946 1.265 5.468 2.774.868.86 1.525 1.887 2.202 2.891.72 1.066 1.494 2.082 2.48 2.914.348.292.625.514.891.677-.802.09-2.14.11-3.054-.614zm1-6.44a.306.306 0 01.415-.287.302.302 0 01.2.288.306.306 0 01-.31.307.303.303 0 01-.304-.308zm3.11 1.596c-.2.081-.399.151-.59.16a1.245 1.245 0 01-.798-.254c-.274-.23-.47-.358-.552-.758a1.73 1.73 0 01.016-.588c.07-.327-.008-.537-.239-.727-.187-.156-.426-.199-.688-.199a.559.559 0 01-.254-.078c-.11-.054-.2-.19-.114-.358.028-.054.16-.186.192-.21.356-.202.767-.136 1.146.016.352.144.618.408 1.001.782.391.451.462.576.685.914.176.265.336.537.445.848.067.195-.019.354-.25.452z" fill="#4D6BFE"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
1
docs/figs/google.svg
Normal file
1
docs/figs/google.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Google</title><path d="M23 12.245c0-.905-.075-1.565-.236-2.25h-10.54v4.083h6.186c-.124 1.014-.797 2.542-2.294 3.569l-.021.136 3.332 2.53.23.022C21.779 18.417 23 15.593 23 12.245z" fill="#4285F4"></path><path d="M12.225 23c3.03 0 5.574-.978 7.433-2.665l-3.542-2.688c-.948.648-2.22 1.1-3.891 1.1a6.745 6.745 0 01-6.386-4.572l-.132.011-3.465 2.628-.045.124C4.043 20.531 7.835 23 12.225 23z" fill="#34A853"></path><path d="M5.84 14.175A6.65 6.65 0 015.463 12c0-.758.138-1.491.361-2.175l-.006-.147-3.508-2.67-.115.054A10.831 10.831 0 001 12c0 1.772.436 3.447 1.197 4.938l3.642-2.763z" fill="#FBBC05"></path><path d="M12.225 5.253c2.108 0 3.529.892 4.34 1.638l3.167-3.031C17.787 2.088 15.255 1 12.225 1 7.834 1 4.043 3.469 2.197 7.062l3.63 2.763a6.77 6.77 0 016.398-4.572z" fill="#EB4335"></path></svg>
|
||||
|
After Width: | Height: | Size: 920 B |
1
docs/figs/openai.svg
Normal file
1
docs/figs/openai.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>OpenAI</title><path d="M21.55 10.004a5.416 5.416 0 00-.478-4.501c-1.217-2.09-3.662-3.166-6.05-2.66A5.59 5.59 0 0010.831 1C8.39.995 6.224 2.546 5.473 4.838A5.553 5.553 0 001.76 7.496a5.487 5.487 0 00.691 6.5 5.416 5.416 0 00.477 4.502c1.217 2.09 3.662 3.165 6.05 2.66A5.586 5.586 0 0013.168 23c2.443.006 4.61-1.546 5.361-3.84a5.553 5.553 0 003.715-2.66 5.488 5.488 0 00-.693-6.497v.001zm-8.381 11.558a4.199 4.199 0 01-2.675-.954c.034-.018.093-.05.132-.074l4.44-2.53a.71.71 0 00.364-.623v-6.176l1.877 1.069c.02.01.033.029.036.05v5.115c-.003 2.274-1.87 4.118-4.174 4.123zM4.192 17.78a4.059 4.059 0 01-.498-2.763c.032.02.09.055.131.078l4.44 2.53c.225.13.504.13.73 0l5.42-3.088v2.138a.068.068 0 01-.027.057L9.9 19.288c-1.999 1.136-4.552.46-5.707-1.51h-.001zM3.023 8.216A4.15 4.15 0 015.198 6.41l-.002.151v5.06a.711.711 0 00.364.624l5.42 3.087-1.876 1.07a.067.067 0 01-.063.005l-4.489-2.559c-1.995-1.14-2.679-3.658-1.53-5.63h.001zm15.417 3.54l-5.42-3.088L14.896 7.6a.067.067 0 01.063-.006l4.489 2.557c1.998 1.14 2.683 3.662 1.529 5.633a4.163 4.163 0 01-2.174 1.807V12.38a.71.71 0 00-.363-.623zm1.867-2.773a6.04 6.04 0 00-.132-.078l-4.44-2.53a.731.731 0 00-.729 0l-5.42 3.088V7.325a.068.068 0 01.027-.057L14.1 4.713c2-1.137 4.555-.46 5.707 1.513.487.833.664 1.809.499 2.757h.001zm-11.741 3.81l-1.877-1.068a.065.065 0 01-.036-.051V6.559c.001-2.277 1.873-4.122 4.181-4.12.976 0 1.92.338 2.671.954-.034.018-.092.05-.131.073l-4.44 2.53a.71.71 0 00-.365.623l-.003 6.173v.002zm1.02-2.168L12 9.25l2.414 1.375v2.75L12 14.75l-2.415-1.375v-2.75z"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
1
docs/figs/qwen.svg
Normal file
1
docs/figs/qwen.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Qwen</title><path d="M12.604 1.34c.393.69.784 1.382 1.174 2.075a.18.18 0 00.157.091h5.552c.174 0 .322.11.446.327l1.454 2.57c.19.337.24.478.024.837-.26.43-.513.864-.76 1.3l-.367.658c-.106.196-.223.28-.04.512l2.652 4.637c.172.301.111.494-.043.77-.437.785-.882 1.564-1.335 2.34-.159.272-.352.375-.68.37-.777-.016-1.552-.01-2.327.016a.099.099 0 00-.081.05 575.097 575.097 0 01-2.705 4.74c-.169.293-.38.363-.725.364-.997.003-2.002.004-3.017.002a.537.537 0 01-.465-.271l-1.335-2.323a.09.09 0 00-.083-.049H4.982c-.285.03-.553-.001-.805-.092l-1.603-2.77a.543.543 0 01-.002-.54l1.207-2.12a.198.198 0 000-.197 550.951 550.951 0 01-1.875-3.272l-.79-1.395c-.16-.31-.173-.496.095-.965.465-.813.927-1.625 1.387-2.436.132-.234.304-.334.584-.335a338.3 338.3 0 012.589-.001.124.124 0 00.107-.063l2.806-4.895a.488.488 0 01.422-.246c.524-.001 1.053 0 1.583-.006L11.704 1c.341-.003.724.032.9.34zm-3.432.403a.06.06 0 00-.052.03L6.254 6.788a.157.157 0 01-.135.078H3.253c-.056 0-.07.025-.041.074l5.81 10.156c.025.042.013.062-.034.063l-2.795.015a.218.218 0 00-.2.116l-1.32 2.31c-.044.078-.021.118.068.118l5.716.008c.046 0 .08.02.104.061l1.403 2.454c.046.081.092.082.139 0l5.006-8.76.783-1.382a.055.055 0 01.096 0l1.424 2.53a.122.122 0 00.107.062l2.763-.02a.04.04 0 00.035-.02.041.041 0 000-.04l-2.9-5.086a.108.108 0 010-.113l.293-.507 1.12-1.977c.024-.041.012-.062-.035-.062H9.2c-.059 0-.073-.026-.043-.077l1.434-2.505a.107.107 0 000-.114L9.225 1.774a.06.06 0 00-.053-.031zm6.29 8.02c.046 0 .058.02.034.06l-.832 1.465-2.613 4.585a.056.056 0 01-.05.029.058.058 0 01-.05-.029L8.498 9.841c-.02-.034-.01-.052.028-.054l.216-.012 6.722-.012z" fill="url(#lobe-icons-qwen-fill)" fill-rule="nonzero"></path><defs><linearGradient id="lobe-icons-qwen-fill" x1="0%" x2="100%" y1="0%" y2="0%"><stop offset="0%" stop-color="#6336E7" stop-opacity=".84"></stop><stop offset="100%" stop-color="#6F69F7" stop-opacity=".84"></stop></linearGradient></defs></svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
17
docs/figs/stock.svg
Normal file
17
docs/figs/stock.svg
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg version="1.1" id="_x32_" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="800px" height="800px" viewBox="0 0 512 512" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
<![CDATA[
|
||||
.st0{fill:#000000;}
|
||||
]]>
|
||||
</style>
|
||||
<g>
|
||||
<polygon class="st0" points="204.344,155.188 249.469,200.297 409.344,40.422 268.031,40.422 316.063,88.453 249.469,155.031
|
||||
204.953,110.516 41.906,264.969 63.906,288.219 "/>
|
||||
<polygon class="st0" points="512,102.313 276.031,330.281 212.656,266.906 0,471.578 512,471.578 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 782 B |
Reference in New Issue
Block a user