fix: cluster charts cap at 50 bars + silhouette label fix + manual page progress bar

This commit is contained in:
PM-pinou
2026-07-19 21:36:51 +08:00
parent 3e98acecf9
commit b90dcbf11c
2 changed files with 26 additions and 13 deletions
+22 -12
View File
@@ -207,18 +207,28 @@ if (clusterSizes.length > 0) {
const canvas = document.getElementById('clusterSizesChart');
if (!canvas) return;
const ctx = canvas.getContext('2d');
const W = canvas.parentElement.clientWidth || 600;
const H = Math.max(200, clusterSizes.length * 40 + 60);
var maxClusters = 50;
var shownClusters = clusterSizes.slice(0, maxClusters);
var note = '';
if (clusterSizes.length > maxClusters) {
note = ' (top ' + maxClusters + ' of ' + clusterSizes.length + ' clusters)';
}
var W = canvas.parentElement.clientWidth || 600;
var H = Math.max(200, shownClusters.length * 36 + 60);
canvas.width = W; canvas.height = H;
const pad = { top: 20, bottom: 30, left: 80, right: 30 };
const plotW = W - pad.left - pad.right;
const plotH = H - pad.top - pad.bottom;
const maxSize = Math.max(...clusterSizes.map(d => d.size));
var pad = { top: 20, bottom: 30, left: 80, right: 30 };
var plotW = W - pad.left - pad.right;
var plotH = H - pad.top - pad.bottom;
var maxSize = Math.max(1, ...shownClusters.map(function(d) { return d.size; }));
ctx.clearRect(0, 0, W, H);
clusterSizes.forEach((d, i) => {
const barH = Math.min(40, plotH / clusterSizes.length * 0.6);
const y = pad.top + i * (barH + 4);
const bw = (d.size / maxSize) * plotW;
if (note) {
ctx.fillStyle = '#999'; ctx.font = '11px sans-serif'; ctx.textAlign = 'left';
ctx.fillText(note, pad.left, 15);
}
shownClusters.forEach(function(d, i) {
var barH = Math.min(32, plotH / shownClusters.length * 0.7);
var y = pad.top + i * (barH + 4);
var bw = Math.max(2, (d.size / maxSize) * plotW);
ctx.fillStyle = chartColors[i % chartColors.length];
ctx.fillRect(pad.left, y, bw, barH);
ctx.fillStyle = '#333';
@@ -227,7 +237,7 @@ if (clusterSizes.length > 0) {
ctx.fillText('#' + d.label, pad.left - 5, y + barH / 2 + 4);
ctx.textAlign = 'left';
ctx.fillStyle = '#666';
ctx.fillText(d.size + ' (' + (d.size / clusterSizes.reduce((a,b) => a+b.size, 0) * 100).toFixed(1) + '%)', pad.left + bw + 5, y + barH / 2 + 4);
ctx.fillText(d.size, pad.left + bw + 5, y + barH / 2 + 4);
});
})();
@@ -266,7 +276,7 @@ if (clusterSizes.length > 0) {
ctx.fillText(d.silhouette.toFixed(4), x + bw + 5, y - 2);
} else {
ctx.textAlign = 'right';
ctx.fillText(d.silhouette.toFixed(4), x + bw - 5, y + barH + 12);
ctx.fillText(d.silhouette.toFixed(4), x - Math.abs(bw) - 5, y + barH + 12);
}
});
// Zero line
+4 -1
View File
@@ -135,7 +135,10 @@ async function runAnalysis() {
const poll = setInterval(async () => {
const r = await fetch(`/runs/${runId}/status/`);
const s = await r.json();
document.getElementById('runStatus').textContent = s.status;
const pct = s.progress_pct || 0;
const msg = s.progress_msg || s.status;
document.getElementById('runStatus').textContent = msg + ' (' + pct + '%)';
document.getElementById('runBar').style.width = pct + '%';
if (s.status === 'completed') { clearInterval(poll); window.location.href = `/runs/${runId}/`; }
if (s.status === 'failed') { clearInterval(poll); document.getElementById('runStatus').textContent = '失败: ' + (s.error_message || ''); }
}, 1000);