Skip to content

Commit 0c5df04

Browse files
committed
Add some useful comments about the same widths drawing
1 parent 393ef2e commit 0c5df04

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

src/components/stack-chart/Canvas.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,13 @@ class StackChartCanvasImpl extends React.PureComponent<Props> {
108108
// When the user checks the "use same widths for each stack" checkbox, some
109109
// expensive computation happens when the canvas is drawn. These computations
110110
// can be reused for hit testing, and therefore are saved in these variables.
111+
//
112+
// The index at viewport start is the index of the first visible block inside
113+
// the viewport (the margins excluded). It's used for hit testing as the
114+
// start offset.
111115
_sameWidthsIndexAtViewportStart: null | number;
116+
// The range length is how many "blocks" are present in the viewport
117+
// (excluding the margins).
112118
_sameWidthsRangeLength: null | number;
113119

114120
componentDidUpdate(prevProps) {
@@ -258,6 +264,54 @@ class StackChartCanvasImpl extends React.PureComponent<Props> {
258264
let sameWidthsIndexAtCanvasStart = null;
259265
let sameWidthsIndexAtCanvasEnd = null;
260266
if (useStackChartSameWidths) {
267+
// The canvas looks like this:
268+
// | LEFT MARGIN | -- VIEWPORT -- | RIGHT MARGIN |
269+
// In this part we need to compute the "same width index" at the start of
270+
// the left margin.
271+
// We do that by first calculating the indexes at the start of the
272+
// viewport, then substracting how many "same width blocks" we can fit in
273+
// the left margin.
274+
// The same operation is done for the right margin.
275+
// If we aren't drawing in the margin, the behavior doesn't feel quite right.
276+
//
277+
// If the start of the canvas isn't just on a block edge, we want to get
278+
// the previous index (the start of the block where the start of the
279+
// canvas is). If it is on a block edge, we want to get _that_ block
280+
// start.
281+
// Similarly for the end, if it's not on a block edge, we want to get the
282+
// end of the block where the canvas end is. If it is on a block edge,
283+
// we want to get the end of the block that ends here, that is the start
284+
// of the next block.
285+
//
286+
// Below we're using "bisectionRight - 1" for the start index, and "bisectionLeft"
287+
// for the end index for these reasons. Let's use an example to understand this.
288+
//
289+
// 0 1 2 3 4 5 <- same width indexes
290+
// | | | | | |
291+
// 5 7 8 10 11 15 <- time values
292+
//
293+
// Start 4 => index 0 End 4 => N/A
294+
// Start 5 => index 0 End 5 => index 0
295+
// Start 6 => index 0 End 6 => index 1
296+
// Start 7 => index 1 End 7 => index 1
297+
// Start 9 => index 2 End 9 => index 3
298+
// Start 15 => index 5 End 15 => index 5
299+
// Start 16 => N/A End 16 => index 5
300+
//
301+
// As a reminder these bisection functions return the same index when the
302+
// searched value isn't in the array (the index of the first greater
303+
// value), but a different index when the searched value is present:
304+
// `bisectionRight` returns the index just after the value, while
305+
// `bisectionLeft` returns the index of the value itself.
306+
//
307+
// Note that this case should happen very rarely in the context here (it's
308+
// not common that the range starts or ends _exactly_ on a sample time),
309+
// and even if this happens it wouldn't be such a problem is this wasn't
310+
// 100% correct. But it's easy to get it right, so we did it.
311+
//
312+
// Note that in this mode we always draw whole blocks between the viewport
313+
// start and end. (of course we can display just a part of a block in the
314+
// start of the left margin or the end of the right margin).
261315
const sameWidthsIndexAtViewportStart = Math.max(
262316
0,
263317
bisectionRight(sameWidthsIndexToTimestampMap, timeAtViewportStart) - 1

0 commit comments

Comments
 (0)