Skip to content
This repository was archived by the owner on Dec 17, 2024. It is now read-only.

Commit 0a36892

Browse files
committed
make failure cells more distinct in grid
also fine tune the legend layout Fixes #792
1 parent 32198e7 commit 0a36892

File tree

3 files changed

+67
-104
lines changed

3 files changed

+67
-104
lines changed

app/plugins/modules/activation-visualizations/lib/legend.js

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ exports.drawLegend = (viewName, rightHeader, {statData, errorRate, nFailures}, o
4949
* Render one legend entry
5050
*
5151
*/
52-
const entry = (labelText, labelValue, isFailure, latBucket, { zoom = 1, labelAsTooltip = false, useThisLabelInstead, balloonPos, balloonLength = 'small', onclick }={}) => {
52+
const entry = (labelText, labelValue, isFailure, latBucket, { zoom = 1, labelAsTooltip = false, useThisLabelInstead, balloonPos, balloonLength='small', onclick }={}) => {
5353
const existing3 = wrapper2.querySelector(`.grid[label="${labelText}"]`),
5454
wrapper3 = existing3 || document.createElement('div'),
5555
existingEntry = wrapper3.querySelector('table'),
@@ -61,10 +61,7 @@ exports.drawLegend = (viewName, rightHeader, {statData, errorRate, nFailures}, o
6161
valueRow = entry.insertRow(-1),
6262
gridCellCell = valueRow.insertCell(-1),
6363
cell = document.createElement('div'),
64-
valueCell = valueRow.insertCell(-1)
65-
66-
valueDom = document.createElement('div')
67-
valueCell.classList.add('kind')
64+
valueCell = document.createElement('div')
6865

6966
wrapper2.appendChild(wrapper3)
7067
wrapper3.className = `grid zoom_${zoom}`
@@ -73,14 +70,19 @@ exports.drawLegend = (viewName, rightHeader, {statData, errorRate, nFailures}, o
7370
wrapper3.appendChild(entry)
7471
cell.className = 'grid-cell grid-cell-occupied'
7572

73+
// value for the legend entry
74+
valueDom = document.createElement('div')
75+
valueCell.classList.add('kind')
76+
gridCellCell.appendChild(valueCell)
77+
7678
renderCell('Legend', cell, null, isFailure, 0, latBucket, { zoom }) // null means no activation associated with cell
7779

7880
if (onclick) {
7981
cell.onclick = onclick
8082
}
8183

8284
if (labelAsTooltip) {
83-
const attachTo = gridCellCell
85+
const attachTo = cell
8486
attachTo.setAttribute('data-balloon', labelText)
8587
attachTo.setAttribute('data-balloon-pos', balloonPos)
8688
attachTo.setAttribute('data-balloon-length', balloonLength)
@@ -98,8 +100,8 @@ exports.drawLegend = (viewName, rightHeader, {statData, errorRate, nFailures}, o
98100
labelCell.className = 'activation-viz-legend-label'
99101
}
100102
valueCell.appendChild(valueDom)
101-
valueCell.style.lineHeight = '1em'
102-
gridCellCell.style.paddingRight = '0.5ex'
103+
//valueCell.style.lineHeight = '1em'
104+
//gridCellCell.style.paddingRight = '0.5ex'
103105
} else {
104106
valueDom = entry.querySelector('.kind > div')
105107
}
@@ -135,19 +137,20 @@ exports.drawLegend = (viewName, rightHeader, {statData, errorRate, nFailures}, o
135137
// roughlySame means e.g. 50-100ms versus 500ms-1s; both
136138
// are "close", but the second one splits into a new range
137139

138-
const labelText = last
139-
? `${prettyPrintDuration(latencyRange)}+` // special label for the last latency bucket
140-
: roughlySame ? `${lower}${enDash}${prettyPrintDuration(upper)}`
141-
: `${prettyPrintDuration(lower)}${enDash}${prettyPrintDuration(upper)}`
140+
const labelText = ''
141+
+ (last
142+
? `${prettyPrintDuration(latencyRange)}+` // special label for the last latency bucket
143+
: roughlySame ? `${lower}${enDash}${prettyPrintDuration(upper)}`
144+
: `${prettyPrintDuration(lower)}${enDash}${prettyPrintDuration(upper)}`)
142145

143146
// number of cells with this coloration
144147
const count = statData.latBuckets[idx]
145148

146149
if (count > 0) {
147150
entry(labelText, count, false, idx, // false means not a failure
148151
{ zoom: -1, labelAsTooltip: true,
149-
balloonPos: idx < ~~(nLatencyBuckets / 2) - 1? 'right' : 'left',
150-
useThisLabelInstead: isFirstNonZero ? `fastest` : isLastNonZero ? `slowest` : nbsp,
152+
balloonPos: lastNonZero >= 2 && idx < ~~(nLatencyBuckets / 2) ? 'right' : 'left',
153+
useThisLabelInstead: isFirstNonZero ? `fast` : isLastNonZero ? `slow` : nbsp,
151154
onclick: drilldownWith(viewName, () => repl.pexec(`grid ${optionsToString(options)} --success --latency-bucket ${idx}`))
152155
})
153156
}
@@ -157,10 +160,10 @@ exports.drawLegend = (viewName, rightHeader, {statData, errorRate, nFailures}, o
157160
//
158161
// render the legend entry for failures
159162
//
160-
entry('Failing Invocations',
163+
entry('these cells represent activation failures',
161164
nFailures,
162165
true, 0, // true means render as failure
163-
{ zoom: -1, labelAsTooltip: true, useThisLabelInstead: 'failures', balloonPos: 'up', balloonLength: 'medium',
166+
{ zoom: -1, labelAsTooltip: true, useThisLabelInstead: 'fail', balloonPos: 'left', balloonLength: 'medium',
164167
onclick: drilldownWith(viewName, () => repl.pexec(`grid ${optionsToString(options)} --failure`))
165168
})
166169
}

app/plugins/modules/activation-visualizations/lib/table.js

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ const _drawTable = (options, header, content, groupData, eventBus, sorter=statDa
124124
xAxisLabels = [],
125125
xAxisLeftPad = headerRow.insertCell(-1)
126126
tableHeader.classList.add('table-header')
127-
xAxisLeftPad.className = 'x-axis-left-pad'
127+
xAxisLeftPad.className = 'x-axis-left-pad cell-numeric'
128+
xAxisLeftPad.innerText = 'Action'
128129
if (numTicks === 0) {
129130
// we still need to insert a cell to fill in the bar column
130131
headerRow.insertCell(-1)//.classList.add('x-axis-label')
@@ -154,8 +155,8 @@ const _drawTable = (options, header, content, groupData, eventBus, sorter=statDa
154155
xAxisRightPad1.className = 'cell-numeric cell-successes cell-hide-when-outliers-shown cell-hide-when-focus-shown'
155156
xAxisRightPad2.className = 'cell-numeric cell-failures cell-hide-when-outliers-shown cell-hide-when-focus-shown'
156157
xAxisRightPad3.className = 'cell-numeric cell-failures cell-show-only-when-outliers-shown cell-hide-when-focus-shown'
157-
xAxisRightPad1.innerText = 'Successes'
158-
xAxisRightPad2.innerText = 'Failures'
158+
xAxisRightPad1.innerText = 'Success'
159+
xAxisRightPad2.innerText = 'Fail'
159160
xAxisRightPad3.innerText = 'Outliers'
160161

161162
// set the focus range to be in the middle so we get some animation on first hover
@@ -318,10 +319,6 @@ const _drawTable = (options, header, content, groupData, eventBus, sorter=statDa
318319
label.setAttribute('data-balloon-length', nameWithoutNamespace.length < 20 ? 'fit' : 'large')
319320
}
320321

321-
// drill down to grid view; note how we pass through a --name
322-
// query, to filter based on the clicked-upon row
323-
//row.onclick = drilldownWith(viewName, `grid ${optionsToString(options)} --zoom 1 --name "${group.path}" ${splitOptions}`)
324-
325322
if (options.split) {
326323
const version = row.insertCell(-1)
327324
version.className = 'cell-version'
@@ -350,6 +347,10 @@ const _drawTable = (options, header, content, groupData, eventBus, sorter=statDa
350347
indicators.forEach(indicator => barWrapper.removeChild(indicator))
351348
}
352349

350+
// drill down to grid view; note how we pass through a name filter
351+
// query, to filter based on the clicked-upon row
352+
cell.onclick = drilldownWith(viewName, `grid "${group.path}" ${optionsToString(options)} ${splitOptions}`)
353+
353354
const this25 = group.statData.n[stat25],
354355
thisMedian = group.statData.n['50'],
355356
this75 = group.statData.n[stat75],
@@ -452,6 +453,13 @@ const _drawTable = (options, header, content, groupData, eventBus, sorter=statDa
452453

453454
// an element to show the median of this bar
454455
medianDot.style.left = percent(medianLeft)
456+
457+
// check to see if the median dot is flush right; if
458+
// so, then we'll need to make a little room for it
459+
if (medianLeft === 1) {
460+
content.classList.add('median-dot-flush-right')
461+
}
462+
455463
medianDot.setAttribute('data-balloon', `median: ${prettyPrintDuration(thisMedian)}`)
456464
medianDot.setAttribute('data-balloon-length', 'medium')
457465
medianDot.setAttribute('data-balloon-pos', 'right')

app/plugins/modules/activation-visualizations/web/css/table.css

Lines changed: 33 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@
8181
padding: 0.6rem 0.75rem;
8282
transition: all 150ms ease-in-out;
8383
}
84+
.data-table:not(.table-header) tr:nth-child(2n + 1) td {
85+
/* zebra striping of rows */
86+
background: var(--color-ui-02);
87+
}
8488
.activation-viz-plugin:not(.x-axis-focus) .data-table.table-header td:not(.x-axis-focus-label-cell) {
8589
border-right: 1px dotted var(--color-ui-04);
8690
}
@@ -112,10 +116,13 @@
112116
}
113117

114118
/* action name column, and range selector padding for that label column */
115-
.activation-viz-plugin table td.cell-label, .activation-viz-plugin .x-axis-left-pad {
119+
.activation-viz-plugin table td.cell-label, .activation-viz-plugin .data-table .x-axis-left-pad.cell-numeric {
116120
width: 30%;
117121
max-width: 50em;
118122
}
123+
.activation-viz-plugin .data-table .x-axis-left-pad {
124+
text-align: left;
125+
}
119126
.activation-viz-plugin.wide-label table td.cell-label, .activation-viz-plugin.wide-label .x-axis-left-pad, .sidecar-full-screen .activation-viz-plugin table td.cell-label, .sidecar-full-screen .activation-viz-plugin .x-axis-left-pad {
120127
/* -w option, or sidecar full screen */
121128
width: 25%;
@@ -225,10 +232,16 @@
225232
display: flex;
226233
align-items: center;
227234
}
235+
.activation-viz-plugin.median-dot-flush-right .data-table td.cell-stats .stat-bar-wrapper {
236+
/* then some median dot is flush to the right of its cell; we'll need
237+
make room on the right it, so that it doesn't overflow to the right
238+
*/
239+
width: calc(100% - 0.6125em);
240+
}
228241
.activation-viz-plugin .data-table td.cell-stats .stat-median-dot, .activation-viz-plugin.show-outliers .outlier-dot {
229242
position: absolute;
230-
width: 0.25em;
231-
height: 1.75em;
243+
width: 0.6125em;
244+
height: 1.25em;
232245
background: #fdbf6f; /* colorbrewer, to match grid theme */
233246
border: 1px solid rgba(0,0,0,0.2);
234247
transition: all 150ms ease-in-out;
@@ -299,7 +312,7 @@
299312
filter: grayscale(1) opacity(0.6);
300313
}
301314
.activation-viz-plugin .data-table .cell-numeric,.activation-viz-plugin .data-table .cell-version {
302-
width: 6rem;
315+
width: 5rem;
303316
}
304317
.activation-viz-plugin .data-table .cell-numeric.cell-extra-wide {
305318
width: 5.25rem;
@@ -536,8 +549,8 @@
536549
left: 0;
537550
width: 100%;
538551
height: 100%;
539-
background-image: repeating-linear-gradient(-45deg, transparent, transparent 10%, rgba(255,255,255,.5) 10%, rgba(255,255,255,.5) 15%);
540-
background-color: var(--color-support-01);
552+
background-image: repeating-linear-gradient(-45deg, transparent, transparent 10%, rgba(255,255,255,.5) 10%, rgba(255,255,255,.5) 15%), repeating-linear-gradient(45deg, transparent, transparent 10%, rgba(255,255,255,.5) 10%, rgba(255,255,255,.5) 21%);
553+
background-color: #b15928;
541554
}
542555

543556
.activation-viz-plugin iframe {
@@ -548,26 +561,28 @@
548561
paddingLeft = '1ex'
549562
}
550563
.activation-viz-plugin.grid-header-key {
551-
max-width: 15em;
564+
height: 8em;
565+
width: 16em;
552566
font-size: 0.875em;
553567
padding: 0;
554568
}
555569
.activation-viz-plugin.grid-header-key .grid {
556570
flex-direction: row;
557571
padding: 0;
558-
padding-right: 0.5ex;
559-
padding-top: 0.75ex;
560572
}
561573
.activation-viz-plugin.grid-header-key .grid:last-child {
562574
padding-right: 0;
563575
}
564576
.activation-viz-plugin.grid-header-key .grid-grid {
577+
flex: 1;
578+
justify-content: flex-end;
579+
align-items: center;
565580
flex-wrap: wrap;
566581
padding-top: 0;
567582
overflow-y: hidden; /* we don't want the table in the header to have scrollies */
568583
}
569584
.activation-viz-plugin.grid-header-key table {
570-
border-spacing: 1px;
585+
border-spacing: 0;
571586
}
572587
.activation-viz-plugin.grid-header-key .zoom_-1 .activation-viz-legend-label {
573588
font-size: 0.875em;
@@ -577,12 +592,13 @@
577592
.activation-viz-plugin.grid-header-key .zoom_-1 .kind {
578593
/* value text for the legend in the sidecar header */
579594
font-size: 0.875em;
580-
font-weight: 400;
595+
font-weight: 300;
596+
text-align: center;
581597
}
582598
.activation-viz-plugin.grid-header-key .grid-cell {
583599
/* size of squares in legend */
584-
width: 1.5vw;
585-
height: 1.5vw;
600+
width: 2.5vw;
601+
height: 2.5vw;
586602
}
587603

588604
/* tooltip */
@@ -722,78 +738,14 @@ body:not(.theme-dark) .activation-viz-plugin .activation-viz-timeline.cell-conta
722738
border-bottom: none;
723739
}
724740

725-
726-
/* picture in picture */
727-
.picture-in-picture.activation-viz-plugin .activation-viz-timeline-vertical-axis, .picture-in-picture.activation-viz-plugin .activation-viz-timeline-horizontal-axis {
728-
display: none;
729-
}
730-
731-
body.subwindow .activation-viz-timeline-horizontal-axis {
732-
-webkit-app-region: drag;
733-
}
734-
body.subwindow .grid-grid:not(.activation-viz-timeline) {
735-
-webkit-app-region: drag;
736-
}
737-
738-
739741
/* timeline range dragging */
740742
.activation-viz-timeline-column.grid.mousedown {
741743
background: rgba(198, 198, 200, 0.25);
742744
}
743745

744-
/* range selector for summary */
745-
.activation-summary-range-selector {
746-
display: flex;
747-
justify-content: center;
748-
align-items: center;
749-
margin: 2em 1em 0;
746+
.main .activation-viz-plugin.grid-header-key [data-balloon]:after {
747+
font-size: 0.875em !important;
750748
}
751-
.activation-summary-range-selector .activation-summary-range-selector-label {
752-
text-transform: uppercase;
753-
font-weight: 400;
754-
font-size: 0.75em;
755-
text-align: right;
756-
}
757-
.activation-summary-range-selector ul {
758-
display: flex;
759-
padding-left: 1ex;
760-
margin: 0;
761-
height: 2.5em;
762-
}
763-
.activation-summary-range-selector li {
764-
list-style: none;
765-
border: 1px solid var(--color-text-02);
766-
padding: 0 2em;
767-
font-weight: 400;
768-
font-size: 0.75em;
769-
display: flex;
770-
color: var(--color-text-02);
771-
align-items: center;
772-
transition: all 150ms ease-in-out;
773-
-webkit-font-smoothing: antialiased; /* fonts a bit too bold otherwise */
774-
}
775-
.activation-summary-range-selector li:not(:first-child):not(:last-child) {
776-
border-right: none;
777-
}
778-
.activation-summary-range-selector li:first-child {
779-
border-right: none;
780-
border-top-left-radius: 8px;
781-
border-bottom-left-radius: 8px;
782-
}
783-
.activation-summary-range-selector li:last-child {
784-
border-top-right-radius: 8px;
785-
border-bottom-right-radius: 8px;
786-
}
787-
.activation-summary-range-selector li:hover {
788-
background: var(--color-text-01);
789-
color: white;
790-
cursor: pointer;
791-
}
792-
.activation-summary-range-selector li.selected {
793-
background: var(--color-text-02);
794-
color: white;
795-
}
796-
.activation-summary-range-selector li.partially-selected {
797-
background: var(--color-text-01);
798-
color: white;
749+
.main .activation-viz-plugin.grid-header-key [data-balloon][data-balloon-length="small"]:after {
750+
width: 60px;
799751
}

0 commit comments

Comments
 (0)