text-overflow: ellipsis;
}
-/* Efficiency Bar */
-.efficiency-section {
- margin-top: 10px;
- padding-top: 10px;
- border-top: 1px solid var(--border);
-}
+/* --------------------------------------------------------------------------
+ Progress Bars
+ -------------------------------------------------------------------------- */
-.efficiency-header {
+.bar-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 5px;
}
-.efficiency-label {
+.bar-label {
font-size: 9px;
font-weight: 600;
color: var(--text-secondary);
letter-spacing: 0.2px;
}
-.efficiency-value {
+.bar-value {
font-family: var(--font-mono);
font-size: 11px;
font-weight: 700;
color: var(--accent);
}
-.efficiency-bar {
+.bar {
height: 6px;
background: var(--bg-tertiary);
border-radius: 3px;
overflow: hidden;
}
-.efficiency-fill {
+.bar-fill {
height: 100%;
background: linear-gradient(90deg, #28a745 0%, #20c997 50%, #17a2b8 100%);
border-radius: 3px;
overflow: hidden;
}
-.efficiency-fill::after {
+.bar-fill::after {
content: '';
position: absolute;
top: 0;
}
/* --------------------------------------------------------------------------
- Thread Stats Grid (in Sidebar)
+ Efficiency Section Container
+ -------------------------------------------------------------------------- */
+
+.efficiency-section {
+ margin-top: 10px;
+ padding-top: 10px;
+ border-top: 1px solid var(--border);
+}
+
+/* --------------------------------------------------------------------------
+ Thread Stats Progress Bars (in Sidebar)
-------------------------------------------------------------------------- */
.thread-stats-section {
display: block;
}
-.stats-grid {
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: 8px;
+.stats-container {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
}
-.stat-tile {
- background: var(--bg-primary);
- border-radius: 8px;
- padding: 10px;
- text-align: center;
- border: 2px solid var(--border);
- transition: all var(--transition-fast);
+.stat-item {
animation: fadeIn 0.4s ease-out backwards;
animation-delay: calc(var(--i, 0) * 0.05s);
}
-.stat-tile:nth-child(1) { --i: 0; }
-.stat-tile:nth-child(2) { --i: 1; }
-.stat-tile:nth-child(3) { --i: 2; }
-.stat-tile:nth-child(4) { --i: 3; }
+.stat-item:nth-child(1) { --i: 0; }
+.stat-item:nth-child(2) { --i: 1; }
+.stat-item:nth-child(3) { --i: 2; }
+.stat-item:nth-child(4) { --i: 3; }
+.stat-item:nth-child(5) { --i: 4; }
-.stat-tile:hover {
- transform: translateY(-2px);
- box-shadow: var(--shadow-sm);
+/* Color variants for bar-fill */
+.bar-fill--green {
+ background: linear-gradient(90deg, #28a745 0%, #20c997 100%);
}
-.stat-tile-value {
- font-family: var(--font-mono);
- font-size: 16px;
- font-weight: 700;
- color: var(--text-primary);
- line-height: 1.2;
+.bar-fill--yellow {
+ background: linear-gradient(90deg, #ffc107 0%, #ffdb4d 100%);
}
-.stat-tile-label {
- font-size: 9px;
- font-weight: 600;
- text-transform: uppercase;
- letter-spacing: 0.3px;
- color: var(--text-muted);
- margin-top: 2px;
+.bar-fill--purple {
+ background: linear-gradient(90deg, #6f42c1 0%, #9b6dd6 100%);
}
-/* Stat tile color variants */
-.stat-tile--green { --tile-color: 40, 167, 69; --tile-text: #28a745; }
-.stat-tile--red { --tile-color: 220, 53, 69; --tile-text: #dc3545; }
-.stat-tile--yellow { --tile-color: 255, 193, 7; --tile-text: #d39e00; }
-.stat-tile--purple { --tile-color: 111, 66, 193; --tile-text: #6f42c1; }
-
-.stat-tile[class*="--"] {
- border-color: rgba(var(--tile-color), 0.4);
- background: linear-gradient(135deg, rgba(var(--tile-color), 0.08) 0%, var(--bg-primary) 100%);
+.bar-fill--red {
+ background: linear-gradient(90deg, #dc3545 0%, #ff6b7a 100%);
}
-.stat-tile[class*="--"] .stat-tile-value { color: var(--tile-text); }
/* --------------------------------------------------------------------------
Hotspot Cards
.brand-info {
display: none;
}
-
- .stats-grid {
- grid-template-columns: 1fr;
- }
}
/* --------------------------------------------------------------------------
if (gilReleasedStat) gilReleasedStat.style.display = 'block';
if (gilWaitingStat) gilWaitingStat.style.display = 'block';
+ const gilHeldPct = threadStats.has_gil_pct || 0;
const gilHeldPctElem = document.getElementById('gil-held-pct');
- if (gilHeldPctElem) gilHeldPctElem.textContent = `${(threadStats.has_gil_pct || 0).toFixed(1)}%`;
+ if (gilHeldPctElem) gilHeldPctElem.textContent = `${gilHeldPct.toFixed(1)}%`;
+ const gilHeldFill = document.getElementById('gil-held-fill');
+ if (gilHeldFill) gilHeldFill.style.width = `${gilHeldPct}%`;
- const gilReleasedPctElem = document.getElementById('gil-released-pct');
// GIL Released = not holding GIL and not waiting for it
const gilReleasedPct = Math.max(0, 100 - (threadStats.has_gil_pct || 0) - (threadStats.gil_requested_pct || 0));
+ const gilReleasedPctElem = document.getElementById('gil-released-pct');
if (gilReleasedPctElem) gilReleasedPctElem.textContent = `${gilReleasedPct.toFixed(1)}%`;
+ const gilReleasedFill = document.getElementById('gil-released-fill');
+ if (gilReleasedFill) gilReleasedFill.style.width = `${gilReleasedPct}%`;
+ const gilWaitingPct = threadStats.gil_requested_pct || 0;
const gilWaitingPctElem = document.getElementById('gil-waiting-pct');
- if (gilWaitingPctElem) gilWaitingPctElem.textContent = `${(threadStats.gil_requested_pct || 0).toFixed(1)}%`;
+ if (gilWaitingPctElem) gilWaitingPctElem.textContent = `${gilWaitingPct.toFixed(1)}%`;
+ const gilWaitingFill = document.getElementById('gil-waiting-fill');
+ if (gilWaitingFill) gilWaitingFill.style.width = `${gilWaitingPct}%`;
}
+ const gcPct = threadStats.gc_pct || 0;
const gcPctElem = document.getElementById('gc-pct');
- if (gcPctElem) gcPctElem.textContent = `${(threadStats.gc_pct || 0).toFixed(1)}%`;
+ if (gcPctElem) gcPctElem.textContent = `${gcPct.toFixed(1)}%`;
+ const gcFill = document.getElementById('gc-fill');
+ if (gcFill) gcFill.style.width = `${gcPct}%`;
// Exception stats
+ const excPct = threadStats.has_exception_pct || 0;
const excPctElem = document.getElementById('exc-pct');
- if (excPctElem) excPctElem.textContent = `${(threadStats.has_exception_pct || 0).toFixed(1)}%`;
+ if (excPctElem) excPctElem.textContent = `${excPct.toFixed(1)}%`;
+ const excFill = document.getElementById('exc-fill');
+ if (excFill) excFill.style.width = `${excPct}%`;
}
// ============================================================================
</div>
<!-- Efficiency Bar -->
<div class="efficiency-section" id="efficiency-section" style="display: none;">
- <div class="efficiency-header">
- <span class="efficiency-label">Sampling Efficiency</span>
- <span class="efficiency-value" id="stat-efficiency">--</span>
+ <div class="bar-header">
+ <span class="bar-label">Sampling Efficiency</span>
+ <span class="bar-value" id="stat-efficiency">--</span>
</div>
- <div class="efficiency-bar">
- <div class="efficiency-fill" id="efficiency-fill"></div>
+ <div class="bar">
+ <div class="bar-fill" id="efficiency-fill"></div>
</div>
- <div class="missed-samples-header">
- <span class="efficiency-label">Missed samples</span>
- <span class="efficiency-value" id="stat-missed-samples">--</span>
+ <div class="bar-header">
+ <span class="bar-label">Missed samples</span>
+ <span class="bar-value" id="stat-missed-samples">--</span>
</div>
- <div class="efficiency-bar">
- <div class="efficiency-fill" id="missed-samples-fill"></div>
+ <div class="bar">
+ <div class="bar-fill" id="missed-samples-fill"></div>
</div>
-
+
</div>
</div>
</section>
</svg>
</button>
<div class="section-content">
- <div class="stats-grid">
- <div class="stat-tile stat-tile--green" id="gil-held-stat">
- <div class="stat-tile-value" id="gil-held-pct">--</div>
- <div class="stat-tile-label">GIL Held</div>
+ <div class="stats-container">
+ <div class="stat-item" id="gil-held-stat">
+ <div class="bar-header">
+ <span class="bar-label">GIL Held</span>
+ <span class="bar-value" id="gil-held-pct">--</span>
+ </div>
+ <div class="bar">
+ <div class="bar-fill bar-fill--green" id="gil-held-fill"></div>
+ </div>
</div>
- <div class="stat-tile stat-tile--red" id="gil-released-stat">
- <div class="stat-tile-value" id="gil-released-pct">--</div>
- <div class="stat-tile-label">GIL Released</div>
+ <div class="stat-item" id="gil-released-stat">
+ <div class="bar-header">
+ <span class="bar-label">GIL Released</span>
+ <span class="bar-value" id="gil-released-pct">--</span>
+ </div>
+ <div class="bar">
+ <div class="bar-fill bar-fill--red" id="gil-released-fill"></div>
+ </div>
</div>
- <div class="stat-tile stat-tile--yellow" id="gil-waiting-stat">
- <div class="stat-tile-value" id="gil-waiting-pct">--</div>
- <div class="stat-tile-label">Waiting GIL</div>
+ <div class="stat-item" id="gil-waiting-stat">
+ <div class="bar-header">
+ <span class="bar-label">Waiting GIL</span>
+ <span class="bar-value" id="gil-waiting-pct">--</span>
+ </div>
+ <div class="bar">
+ <div class="bar-fill bar-fill--yellow" id="gil-waiting-fill"></div>
+ </div>
</div>
- <div class="stat-tile stat-tile--purple" id="gc-stat">
- <div class="stat-tile-value" id="gc-pct">--</div>
- <div class="stat-tile-label">GC</div>
+ <div class="stat-item" id="gc-stat">
+ <div class="bar-header">
+ <span class="bar-label">GC</span>
+ <span class="bar-value" id="gc-pct">--</span>
+ </div>
+ <div class="bar">
+ <div class="bar-fill bar-fill--purple" id="gc-fill"></div>
+ </div>
</div>
- <div class="stat-tile stat-tile--red" id="exc-stat">
- <div class="stat-tile-value" id="exc-pct">--</div>
- <div class="stat-tile-label">Exception</div>
+ <div class="stat-item" id="exc-stat">
+ <div class="bar-header">
+ <span class="bar-label">Exception</span>
+ <span class="bar-value" id="exc-pct">--</span>
+ </div>
+ <div class="bar">
+ <div class="bar-fill bar-fill--red" id="exc-fill"></div>
+ </div>
</div>
</div>
</div>