Fix axis label/title collisions in Element Attention Analysis chart
Browse filesThe rotated Y-axis title sat too close to the plot's left edge (a wide
first column would butt right up against it), and the rotated X-axis
labels' diagonal tails could reach into the X-axis title text below
them. Grows the canvas by the same amount the margins grow (so the
plotted area itself doesn't shrink), widens padLeft/padBottom, and
trims the label truncation length slightly for extra safety margin.
Verified pixel-level on a 46-element session: 9px+ clear gap on both
axes, no overlap in either Line or Column mode.
- analysis.py +16 -7
analysis.py
CHANGED
|
@@ -1363,14 +1363,22 @@ function showToast(message, isError, onRetry){
|
|
| 1363 |
|
| 1364 |
function layout(){
|
| 1365 |
const containerW = scrollBox.clientWidth || 320;
|
| 1366 |
-
const needed =
|
| 1367 |
cv.width = Math.max(containerW, needed);
|
| 1368 |
-
cv.height = inFullscreen() ? Math.max(
|
| 1369 |
hint.style.display = needed > containerW ? 'block' : 'none';
|
| 1370 |
}
|
| 1371 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1372 |
function geometry(){
|
| 1373 |
-
const padLeft =
|
| 1374 |
const plotW = cv.width - padLeft - padRight;
|
| 1375 |
const plotH = cv.height - padTop - padBottom;
|
| 1376 |
const dataMax = Math.max.apply(null, points.map(p => p.seconds)) || 1;
|
|
@@ -1493,7 +1501,7 @@ function showToast(message, isError, onRetry){
|
|
| 1493 |
ctx.fillStyle = isHover ? strong : dim;
|
| 1494 |
ctx.font = isHover ? '600 10.5px -apple-system, Arial' : '10.5px -apple-system, Arial';
|
| 1495 |
ctx.textAlign = 'right';
|
| 1496 |
-
const label = pt.p.name.length >
|
| 1497 |
ctx.fillText(label, 0, 0);
|
| 1498 |
ctx.restore();
|
| 1499 |
});
|
|
@@ -1505,13 +1513,14 @@ function showToast(message, isError, onRetry){
|
|
| 1505 |
ctx.lineTo(cv.width - g.padRight, g.padTop + g.plotH);
|
| 1506 |
ctx.stroke();
|
| 1507 |
|
| 1508 |
-
// axis titles
|
|
|
|
| 1509 |
ctx.fillStyle = faint;
|
| 1510 |
ctx.font = '600 10px -apple-system, Arial';
|
| 1511 |
ctx.textAlign = 'center';
|
| 1512 |
-
ctx.fillText('WEBPAGE ELEMENTS (' + pts.length + ')', g.padLeft + g.plotW / 2, cv.height -
|
| 1513 |
ctx.save();
|
| 1514 |
-
ctx.translate(
|
| 1515 |
ctx.rotate(-Math.PI / 2);
|
| 1516 |
ctx.fillText('GAZE ATTENTION (SEC)', 0, 0);
|
| 1517 |
ctx.restore();
|
|
|
|
| 1363 |
|
| 1364 |
function layout(){
|
| 1365 |
const containerW = scrollBox.clientWidth || 320;
|
| 1366 |
+
const needed = 120 + points.length * MIN_SLOT;
|
| 1367 |
cv.width = Math.max(containerW, needed);
|
| 1368 |
+
cv.height = inFullscreen() ? Math.max(460, Math.round(window.innerHeight * 0.6)) : 400;
|
| 1369 |
hint.style.display = needed > containerW ? 'block' : 'none';
|
| 1370 |
}
|
| 1371 |
|
| 1372 |
+
// Padding is dedicated margin *around* the plot, not carved out of it —
|
| 1373 |
+
// cv.height/width already grew by the same amount (see layout()) so the
|
| 1374 |
+
// plotted area itself doesn't shrink. padLeft needs enough room for the
|
| 1375 |
+
// rotated Y-axis title + tick labels before the first point; padBottom
|
| 1376 |
+
// needs enough room for the diagonally-rotated X-axis labels *and* a
|
| 1377 |
+
// clear gap before the X-axis title below them — otherwise the title and
|
| 1378 |
+
// the longest labels' diagonal tails collide, and a wide first column
|
| 1379 |
+
// butts right up against the Y-axis title.
|
| 1380 |
function geometry(){
|
| 1381 |
+
const padLeft = 84, padRight = 34, padTop = 30, padBottom = 108;
|
| 1382 |
const plotW = cv.width - padLeft - padRight;
|
| 1383 |
const plotH = cv.height - padTop - padBottom;
|
| 1384 |
const dataMax = Math.max.apply(null, points.map(p => p.seconds)) || 1;
|
|
|
|
| 1501 |
ctx.fillStyle = isHover ? strong : dim;
|
| 1502 |
ctx.font = isHover ? '600 10.5px -apple-system, Arial' : '10.5px -apple-system, Arial';
|
| 1503 |
ctx.textAlign = 'right';
|
| 1504 |
+
const label = pt.p.name.length > 20 ? pt.p.name.slice(0, 19) + '…' : pt.p.name;
|
| 1505 |
ctx.fillText(label, 0, 0);
|
| 1506 |
ctx.restore();
|
| 1507 |
});
|
|
|
|
| 1513 |
ctx.lineTo(cv.width - g.padRight, g.padTop + g.plotH);
|
| 1514 |
ctx.stroke();
|
| 1515 |
|
| 1516 |
+
// axis titles — drawn last, in their own dedicated margin below/left of
|
| 1517 |
+
// everything else (see the padLeft/padBottom comment on geometry())
|
| 1518 |
ctx.fillStyle = faint;
|
| 1519 |
ctx.font = '600 10px -apple-system, Arial';
|
| 1520 |
ctx.textAlign = 'center';
|
| 1521 |
+
ctx.fillText('WEBPAGE ELEMENTS (' + pts.length + ')', g.padLeft + g.plotW / 2, cv.height - 14);
|
| 1522 |
ctx.save();
|
| 1523 |
+
ctx.translate(20, g.padTop + g.plotH / 2);
|
| 1524 |
ctx.rotate(-Math.PI / 2);
|
| 1525 |
ctx.fillText('GAZE ATTENTION (SEC)', 0, 0);
|
| 1526 |
ctx.restore();
|