Two things about the same chart, both of which made it a different picture depending on what it was drawing. The columns were given a pixel of daylight between them once they were wide enough to spare it. A hundred-step run packs to about a pixel a column, so it never was: it came out as a solid falling mass, which is a shape you take in at a glance. A fourteen-step run had room, so it opened out into fourteen tally marks -- the same descent, read as a set of unrelated measurements rather than as one continuous thing. The mass is the one worth having, so the columns meet now. What separates them is the step in the top edge where the distance actually changed, which is the only separation the data has, and it survives at any width: a ragged ridge at one pixel a column, a staircase at ten, the same picture in both. And its height was a fraction of the plate, which is the *board's* plate. A five-wide set gets a wide short one and a three-wide set a narrow tall one, so an identical run was drawn at a different size on every family -- and on the square plates a third of the height left the ridge stranded in the middle of the window with a hand's width of nothing underneath it. There is nothing else on that screen. The chart is what it is for, so it takes everything between the set's name and the caption, on every board, and the caption is measured before the chart is placed rather than after.
- commit
- d4b2941f042440f011e7da02cf109d47b38c4f68
- parent
- e56203e45ddf65f2dbbd59b3076d9963df297df8
- author
- Dami <dami.etoile@gmail.com>
| M | README.md | 18 | +++++++++++- |
| M | mockup/ | 42 | ++++++++++++++++++++++++++---- |
| M | mockup/ | 2 | +- |
@@ -416,8 +416,22 @@ rather than derived, because the history log is a capped ring buffer — it is e
416416 not enough to answer "how many have I ever solved".417417 418418 The perfect-solver reference on the descent chart is gold and painted after the threshold, like the419-trophy: drawn into the scene it was ink on ink, and the bars of your own run covered the very line420-they are meant to be read against.419+trophy: drawn into the scene it was ink on ink, and the mass of your own run covered the very line420+it is meant to be read against.421+422+The descent itself is one silhouette rather than a row of bars, at every length. The columns used to423+be given a pixel of daylight once they were wide enough to spare it, which made the chart two424+different pictures: a hundred-step run packed to a pixel a column and read as a solid falling mass,425+and a fourteen-step one opened out into fourteen tally marks. The mass is the one worth having — a426+run of play is a continuous thing, not fourteen unrelated measurements — so the columns meet, and427+what separates them is the step in the top edge where the distance actually changed. At one pixel a428+column that is a ragged ridge and at ten it is a staircase; it is the same picture either way.429+430+Its height is the room, not a fraction of it. It was a share of the plate, and the plate is the431+*board's* — a five-wide set gets a wide short one and a three-wide set a narrow tall one, so the same432+run was drawn at a different size on every family, and on the square plates the ridge sat stranded in433+the middle of the window with a hand's width of nothing under it. There is nothing else in that434+window: the chart takes everything between the set's name and the caption, on every board.421435 422436 The record screen shows level and XP, lifetime solved / efficiency / time / day streak, a per-family423437 table of rung, solves and deepest board, a chart of recent depths, and the total number of@@ -1487,8 +1487,25 @@ function drawWon(c) {
14871487 // line a perfect solver draws -- straight down. The ridge is what actually14881488 // happened, and every place it climbs is a stretch where the board took you14891489 // further from the answer than you already were.1490+1491+ // The caption is measured before the chart is placed, because the chart is1492+ // now given the room rather than a fraction of it.1493+ const capSize = fitSize('DISTANCE TO GOAL', LY.cell * 0.36, 'SilkR', 1, P.w - 18);1494+ const capY = plate.y + plate.h - Math.round(LY.padBottom * 0.34);1495+1496+ /* The chart takes everything between the set's name and that caption.1497+ *1498+ * Its height used to be a fraction of the plate, and the plate is the1499+ * *board's* -- a five-wide set gets a wide short one and a three-wide set a1500+ * narrow tall one, so the same run of play was drawn at a different size on1501+ * every family, and on the square plates a third of the height left the ridge1502+ * stranded in the middle of the window with a hand's width of nothing under1503+ * it. There is nothing else in this window: the chart is what the screen is1504+ * for, and it should be as big as the frame allows on every board. */14901505 const gx = plate.x + Math.round(P.w * 0.13), gw = Math.round(P.w * 0.74);1491- const gy = solvedY + Math.round(U * 0.13), gh = Math.round(P.h * 0.34);1506+ const gy = solvedY + Math.round(U * 0.13);1507+ // Room for the baseline rule and a breath under it before the caption's caps.1508+ const gh = Math.max(24, capY - capSize - Math.round(U * 0.075) - gy);14921509 const tr = App.trace, n = Math.max(1, tr.length);14931510 const d0 = Math.max(1, tr[0] || 1);14941511 // Scaled to the furthest you ever got, not to where you started. Going@@ -1502,19 +1519,32 @@ function drawWon(c) {
15021519 const ref = topOf(d0);15031520 goldLine(gx, ref, gx + gw, gy + gh);15041521 1522+ /* Drawn as one silhouette, never as separate bars.1523+ *1524+ * The columns used to be given a pixel of daylight between them once they1525+ * were wide enough to spare it, which meant the chart was two different1526+ * pictures depending on how long the run was: a hundred-step descent packed1527+ * to a pixel a column and read as a solid falling mass, and a fourteen-step1528+ * one opened out into fourteen tally marks. The mass is the one worth having1529+ * -- it is a shape you take in at a glance, and a run of play is a continuous1530+ * thing rather than fourteen unrelated measurements.1531+ *1532+ * So the columns meet. What separates them is the step in the top edge where1533+ * the distance changed, which is the only separation the data actually has,1534+ * and it survives at any width: at one pixel a column it is a ragged ridge,1535+ * at ten it is a staircase, and it is the same picture in both. */15051536 c.fillStyle = grey(T.rule);15061537 for (let i = 0; i < n; i++) {1507- const h = Math.round(gh * (tr[i] / peak));1538+ const h = Math.max(1, Math.round(gh * (tr[i] / peak)));15081539 const x0 = gx + Math.round(i * bw), x1 = gx + Math.round((i + 1) * bw);1509- c.fillRect(x0, gy + gh - h, Math.max(1, x1 - x0 - (bw > 3 ? 1 : 0)), Math.max(1, h));1540+ c.fillRect(x0, gy + gh - h, Math.max(1, x1 - x0), h);15101541 }15111542 c.fillRect(gx, gy + gh + 1, gw, 1);15121543 15131544 // Sized off the plate, not off the cell: a three-wide board gets big cells,15141545 // and a caption scaled to them runs straight out through the frame.1515- label('DISTANCE TO GOAL', cx, plate.y + plate.h - Math.round(LY.padBottom * 0.34),1516- { size: fitSize('DISTANCE TO GOAL', LY.cell * 0.36, 'SilkR', 1, P.w - 18),1517- face: 'SilkR', track: 1, align: 'center' });1546+ label('DISTANCE TO GOAL', cx, capY,1547+ { size: capSize, face: 'SilkR', track: 1, align: 'center' });15181548 15191549 }15201550