v2.2.0:data-chart-tool 双Y轴折线图(预填充左轴虚线/解码右轴实线)+画图CSV一键复制+下载PNG+默认上下文长度增加4096/16384/65536

This commit is contained in:
2026-08-31 00:17:26 +08:00
parent 577fbf69e3
commit 2d889c80e0
7 changed files with 216 additions and 15 deletions
+58 -2
View File
@@ -21,8 +21,8 @@ let pollTimer = null;
let lastLogId = 0;
let consoleLogs = []; // 当前测试已加载日志 [{id,level,msg,rel}]
// 上下文长度:chips 列表 + 启用集合(默认 512/2048/8192/32768/131072
const DEFAULT_CONTEXT_LENGTHS = [512, 2048, 8192, 32768, 131072];
// 上下文长度:chips 列表 + 启用集合(默认 512/2048/4096/8192/16384/32768/65536/131072
const DEFAULT_CONTEXT_LENGTHS = [512, 2048, 4096, 8192, 16384, 32768, 65536, 131072];
let contextLengths = [...DEFAULT_CONTEXT_LENGTHS];
let contextLengthsActive = new Set(contextLengths);
@@ -421,6 +421,23 @@ async function viewDetail(id) {
<h3>📏 按上下文长度汇总</h3>
${byLengthHtml}
<h3>📈 折线图(预填充左轴虚线 / 解码右轴实线)</h3>
<div class="chart-block">
<div class="chart-toolbar">
<button class="btn small primary" id="dt-chart-gen">🎨 生成/刷新折线图</button>
<span class="hint" id="dt-chart-status"></span>
</div>
<div class="chart-img-wrap" id="dt-chart-img">
<div class="hint">点击上方按钮,用 data-chart-tool 生成双Y轴折线图(左轴=预填充虚线,右轴=解码实线)</div>
</div>
<div class="chart-data-head">📋 画图数据(CSV,可一键复制)</div>
<textarea class="chart-csv" id="dt-chart-csv" readonly spellcheck="false" placeholder="(生成图表后自动填充,或手动复制)"></textarea>
<div class="chart-toolbar" style="margin-top:6px">
<button class="btn small" id="dt-chart-copy">📋 复制画图数据</button>
<button class="btn small" id="dt-chart-download">⬇ 下载图表 PNG</button>
</div>
</div>
<h3>⚙️ 测试参数</h3>
<div class="kv">
<div class="kv-item"><div class="kv-k">测试名称</div><div class="kv-v">${esc(t.name || "—")}</div></div>
@@ -444,6 +461,45 @@ async function viewDetail(id) {
$("#detail-mask").hidden = false;
$("#dt-body").scrollTop = 0;
window.__detail = t;
// 图表:生成/刷新 + 复制数据 + 下载
const genBtn = $("#dt-chart-gen");
const csvTa = $("#dt-chart-csv");
const imgWrap = $("#dt-chart-img");
const statusEl = $("#dt-chart-status");
let chartUrl = "";
const genChart = () => {
statusEl.textContent = "⏳ 正在生成...";
fetch(`/api/tests/${id}/chart-data`).then((r) => r.json()).then((d) => {
if (!d.ok) { statusEl.textContent = "❌ " + (d.error || "生成失败"); return; }
csvTa.value = d.csv;
chartUrl = `/api/tests/${id}/chart?t=${Date.now()}`;
const img = document.createElement("img");
img.src = chartUrl;
img.alt = "预填充/解码 折线图";
img.style.maxWidth = "100%";
img.onload = () => { imgWrap.innerHTML = ""; imgWrap.appendChild(img); statusEl.textContent = "✅ 生成完成"; };
img.onerror = () => { statusEl.textContent = "❌ 图表生成失败"; };
}).catch((e) => { statusEl.textContent = "❌ " + e.message; });
};
genBtn.addEventListener("click", genChart);
$("#dt-chart-copy").addEventListener("click", () => {
if (!csvTa.value) { toast("暂无画图数据,请先生成图表"); return; }
csvTa.select();
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(csvTa.value).then(() => toast("画图数据已复制"));
} else {
document.execCommand("copy");
toast("画图数据已复制");
}
});
$("#dt-chart-download").addEventListener("click", () => {
if (!chartUrl) { toast("请先生成图表"); return; }
const a = document.createElement("a");
a.href = chartUrl;
a.download = `llm_speed_chart_${id}.png`;
document.body.appendChild(a); a.click(); a.remove();
});
}
function closeDetail() { $("#detail-mask").hidden = true; }