From 7f6bea20bedcb0d4478a3702a67b03d828c0227d Mon Sep 17 00:00:00 2001 From: Anish Athalye Date: Tue, 12 May 2020 18:17:28 -0400 Subject: [PATCH] update --- src/porcupine/visualization.go | 68 ++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 8 deletions(-) diff --git a/src/porcupine/visualization.go b/src/porcupine/visualization.go index fb764d5..f3e1402 100644 --- a/src/porcupine/visualization.go +++ b/src/porcupine/visualization.go @@ -113,7 +113,17 @@ html { } #legend { - margin-bottom: 10px; + position: fixed; + left: 10px; + top: 10px; + background-color: rgba(255, 255, 255, 0.5); + backdrop-filter: blur(3px); + padding: 5px 2px 1px 2px; + border-radius: 4px; +} + +#canvas { + margin-top: 45px; } #calc { @@ -139,6 +149,11 @@ html { ry: 4; } +.link { + fill: #206475; + cursor: pointer; +} + .selected { stroke-width: 5; } @@ -185,11 +200,15 @@ html { padding: 5px; font-size: 0.8rem; } + +.inactive { + display: none; +}
- + Clients Time @@ -199,6 +218,7 @@ html { Valid LP Invalid LP + [ jump to first error ]
@@ -572,11 +592,12 @@ html { // draw partial linearizations const illegalLast = data.map(partition => { - return partition['PartialLinearizations'].map(_ => new Set()) + return partition['PartialLinearizations'].map(() => new Set()) }) const largestIllegal = data.map(() => {return {}}) const largestIllegalLength = data.map(() => {return {}}) const partialLayers = [] + const errorPoints = [] data.forEach((partition, partitionIndex) => { const l = [] partialLayers.push(l) @@ -639,13 +660,19 @@ html { 'class': 'linearization-invalid linearization-line', }) // current line - svgadd(g, 'line', { + const point = svgadd(g, 'line', { 'x1': x, 'x2': x, 'y1': y, 'y2': y + BOX_HEIGHT + 2*LINE_BLEED, 'class': 'linearization-invalid linearization-point', }) + errorPoints.push({ + x: x, + partition: partitionIndex, + index: lin[lin.length-1]['Index'], // NOTE not index + element: point + }) illegalLast[partitionIndex][linIndex].add(index) if (!Object.prototype.hasOwnProperty.call(largestIllegalLength[partitionIndex], index) || largestIllegalLength[partitionIndex][index] < lin.length) { largestIllegalLength[partitionIndex][index] = lin.length @@ -655,6 +682,7 @@ html { }) }) }) + errorPoints.sort((a, b) => a.x - b.x) // attach targetRects svgattach(svg, targetRects) @@ -702,6 +730,7 @@ html { if (maxIndex !== null) { partialLayers[partition][maxIndex].classList.remove('hidden') } + updateJump() } let lastTooltip = [null, null, null, null, null] @@ -791,6 +820,25 @@ html { } }) }) + updateJump() + } + + function updateJump() { + const jump = document.getElementById('jump-link') + // find first non-hidden point + // feels a little hacky, but it works + const point = errorPoints.find(pt => !pt.element.parentElement.classList.contains('hidden')) + if (point) { + jump.classList.remove('inactive') + jump.onclick = () => { + point.element.scrollIntoView({behavior: 'smooth', inline: 'center', block: 'center'}) + if (!selected) { + select(point.partition, point.index) + } + } + } else { + jump.classList.add('inactive') + } } function handleClick() { @@ -805,16 +853,20 @@ html { historyRects[sPartition][sIndex].classList.remove('selected') } } - selected = true - selectedIndex = [partition, index] - highlight(partition, index) - historyRects[partition][index].classList.add('selected') + select(partition, index) } function handleBgClick() { deselect() } + function select(partition, index) { + selected = true + selectedIndex = [partition, index] + highlight(partition, index) + historyRects[partition][index].classList.add('selected') + } + function deselect() { if (!selected) { return