Skip to content

Instantly share code, notes, and snippets.

@fuyi
Created September 4, 2026 06:45
Show Gist options
  • Select an option

  • Save fuyi/f63ae0c5f08249384c4f8f6ed33ab4ec to your computer and use it in GitHub Desktop.

Select an option

Save fuyi/f63ae0c5f08249384c4f8f6ed33ab4ec to your computer and use it in GitHub Desktop.
qc_bullet_marts Production Gantt — 4 models, int_qc_bullet_session dominates at 31 min
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>qc_bullet_marts Production Gantt</title>
<style>
body { font-family: monospace; background: #1a1a2e; color: #eee; margin: 20px; }
h2 { color: #a0c4ff; margin-bottom: 4px; }
.subtitle { color: #666; font-size: 12px; margin-bottom: 16px; }
.bar-ok { fill: #4cc9f0; opacity: 0.88; }
.bar-error { fill: #ff4444; opacity: 0.88; }
.dep-line { stroke: #555; stroke-width: 1; fill: none; stroke-dasharray: 3,3; }
.model-label { font-size: 12px; fill: #aaa; text-anchor: end; }
.time-label { font-size: 10px; fill: #555; }
</style>
</head>
<body>
<h2>qc_bullet_marts — Production execution (2026-09-04 01:01 UTC)</h2>
<div class="subtitle">4 models · ~32 min wall-clock · <strong style="color:#ff9">int_qc_bullet_session dominates at 1869s (31 min)</strong></div>
<div id="chart"></div>
<p style="font-size:11px;color:#666">
<span style="color:#4cc9f0">&#9632;</span> success &nbsp;
<span style="color:#555">- - -</span> dependency
</p>
<script>
const data = [{"model": "int_qc_bullet_session", "start": "2026-09-04T01:01:40.148000+00:00", "end": "2026-09-04T01:32:49.078000+00:00", "dur": 1868.93, "status": "ok"}, {"model": "int_qc_bullet_key", "start": "2026-09-04T01:32:49.086000+00:00", "end": "2026-09-04T01:32:49.866000+00:00", "dur": 0.78, "status": "ok"}, {"model": "qc_question_user_day", "start": "2026-09-04T01:32:49.865000+00:00", "end": "2026-09-04T01:32:57.645000+00:00", "dur": 7.78, "status": "ok"}, {"model": "qc_question_team_day", "start": "2026-09-04T01:32:57.649000+00:00", "end": "2026-09-04T01:34:04.709000+00:00", "dur": 67.06, "status": "ok"}];
const deps = {"qc_question_team_day": ["qc_question_user_day"], "qc_question_user_day": ["int_qc_bullet_key", "int_qc_bullet_session"], "int_qc_bullet_key": ["int_qc_bullet_session"]};
data.sort((a,b) => new Date(a.start)-new Date(b.start));
const runStart = new Date(data[0].start).getTime();
const runEnd = Math.max(...data.map(d=>new Date(d.end).getTime()));
const totalMs = runEnd - runStart;
const LABEL_W = 300, BAR_H = 28, ROW_H = 36, TOP = 30, PX = 1200/(totalMs/1000);
const W = LABEL_W + 1220;
const H = TOP + data.length * ROW_H + 20;
const rowIndex = {};
data.forEach((d,i) => rowIndex[d.model] = i);
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttribute('width', W); svg.setAttribute('height', H);
svg.style.display = 'block';
for (let s = 0; s <= totalMs/1000; s += 300) {
const x = LABEL_W + s*PX;
const tick = document.createElementNS('http://www.w3.org/2000/svg','line');
tick.setAttribute('x1',x); tick.setAttribute('y1',TOP-10);
tick.setAttribute('x2',x); tick.setAttribute('y2',H);
tick.setAttribute('stroke','#222'); tick.setAttribute('stroke-width','1');
svg.appendChild(tick);
const lbl = document.createElementNS('http://www.w3.org/2000/svg','text');
lbl.setAttribute('x',x); lbl.setAttribute('y',TOP-14);
lbl.setAttribute('class','time-label'); lbl.setAttribute('text-anchor','middle');
lbl.textContent = Math.round(s/60)+'m';
svg.appendChild(lbl);
}
Object.entries(deps).forEach(([model, parents]) => {
const toRow = rowIndex[model];
if (toRow===undefined) return;
const toY = TOP + toRow*ROW_H + BAR_H/2;
const toX = LABEL_W + ((new Date(data[toRow].start).getTime()-runStart)/1000)*PX;
parents.forEach(parent => {
const fromRow = rowIndex[parent];
if (fromRow===undefined) return;
const fromY = TOP + fromRow*ROW_H + BAR_H/2;
const fromX = LABEL_W + ((new Date(data[fromRow].end).getTime()-runStart)/1000)*PX;
const path = document.createElementNS('http://www.w3.org/2000/svg','path');
const mx = (fromX+toX)/2;
path.setAttribute('d',`M${fromX},${fromY} C${mx},${fromY} ${mx},${toY} ${toX},${toY}`);
path.setAttribute('class','dep-line');
svg.appendChild(path);
});
});
data.forEach((d,i) => {
const y = TOP + i*ROW_H;
const x = LABEL_W + ((new Date(d.start).getTime()-runStart)/1000)*PX;
const w = Math.max(3, ((new Date(d.end).getTime()-new Date(d.start).getTime())/1000)*PX);
const lbl = document.createElementNS('http://www.w3.org/2000/svg','text');
lbl.setAttribute('x',LABEL_W-4); lbl.setAttribute('y',y+BAR_H-6);
lbl.setAttribute('class','model-label');
lbl.textContent = d.model;
svg.appendChild(lbl);
const durLbl = document.createElementNS('http://www.w3.org/2000/svg','text');
durLbl.setAttribute('x',x+w+4); durLbl.setAttribute('y',y+BAR_H-6);
durLbl.setAttribute('font-size','11'); durLbl.setAttribute('fill','#888');
durLbl.textContent = d.dur > 60 ? Math.round(d.dur/60)+'m' : d.dur+'s';
svg.appendChild(durLbl);
const rect = document.createElementNS('http://www.w3.org/2000/svg','rect');
rect.setAttribute('x',x); rect.setAttribute('y',y);
rect.setAttribute('width',w); rect.setAttribute('height',BAR_H);
rect.setAttribute('rx',3);
rect.setAttribute('class','bar bar-'+d.status);
rect.innerHTML = `<title>${d.model} — ${d.dur.toFixed(1)}s</title>`;
svg.appendChild(rect);
});
document.getElementById('chart').appendChild(svg);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment