@deephaven/grid 0.6.1-beta.0 → 0.6.3-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -78,7 +78,7 @@ class GridRenderer {
78
78
  var hi = Math.min(str.length - 1, end);
79
79
  var result = str;
80
80
 
81
- while (hi > lo) {
81
+ while (hi >= lo) {
82
82
  var mid = Math.ceil((hi + lo) / 2);
83
83
  var truncatedStr = GridRenderer.truncate(str, mid);
84
84
 
@@ -90,6 +90,10 @@ class GridRenderer {
90
90
  }
91
91
 
92
92
  lo = mid;
93
+ } else if (mid === 0) {
94
+ // We already truncated to zero chars and it still doesn't fit, no need to keep looking
95
+ result = truncatedStr;
96
+ break;
93
97
  } else {
94
98
  hi = mid - 1;
95
99
  }
@@ -105,6 +109,7 @@ class GridRenderer {
105
109
  * @param {string} str The string to calculate max length for
106
110
  * @param {number} width The width to truncate within
107
111
  * @param {number} fontWidth The estimated width of each character
112
+ * @returns {string} The truncated string that fits within the width provided
108
113
  */
109
114
 
110
115
 
@@ -112,10 +117,13 @@ class GridRenderer {
112
117
  var fontWidth = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : GridRenderer.DEFAULT_FONT_WIDTH;
113
118
 
114
119
  if (width <= 0 || str.length <= 0) {
115
- return null;
116
- }
120
+ return '';
121
+ } // Estimate the possible low and high boundaries for truncating the text
122
+ // Use the width of the space divided by the estimated width of each character,
123
+ // and take half that as the low (minus 5 just to be extra safe), and double that as the high.
124
+
117
125
 
118
- var lo = Math.min(Math.floor(width / fontWidth / 2), str.length);
126
+ var lo = Math.min(Math.max(0, Math.floor(width / fontWidth / 2) - 5), str.length);
119
127
  var hi = Math.min(Math.ceil(width / fontWidth * 2), str.length);
120
128
  return GridRenderer.binaryTruncateToWidth(context, str, width, lo, hi);
121
129
  }
@@ -262,7 +270,8 @@ class GridRenderer {
262
270
  visibleRows,
263
271
  visibleColumnXs,
264
272
  visibleColumnWidths,
265
- width
273
+ width,
274
+ height
266
275
  } = metrics;
267
276
 
268
277
  if (floatingColumns.length === 0) {
@@ -276,16 +285,21 @@ class GridRenderer {
276
285
 
277
286
  if (draggingRow == null && draggingColumn == null) {
278
287
  this.drawFloatingMouseRowHover(context, state);
279
- }
288
+ } // Clip floated column grid lines.
280
289
 
290
+
291
+ context.save();
292
+ context.beginPath();
293
+ context.rect(0, 0, floatingLeftWidth, height);
294
+ context.clip();
281
295
  this.drawGridLinesForItems(context, state, floatingColumns, visibleRows, theme.floatingGridColumnColor, theme.floatingGridRowColor);
296
+ context.restore();
282
297
  this.drawCellBackgroundsForItems(context, state, floatingColumns, visibleRows);
283
298
  this.drawFloatingBorders(context, state); // Draw the floating column selection...
284
299
 
285
300
  if (floatingLeftColumnCount > 0) {
286
301
  this.drawSelectedRanges(context, state, {
287
302
  left: 0,
288
- right: floatingLeftColumnCount,
289
303
  maxX: visibleColumnXs.get(floatingLeftColumnCount - 1) + visibleColumnWidths.get(floatingLeftColumnCount - 1)
290
304
  }, true);
291
305
  }
@@ -738,8 +752,9 @@ class GridRenderer {
738
752
  } = state;
739
753
  var {
740
754
  visibleRowYs,
741
- maxX
742
- } = metrics; // Draw row lines
755
+ maxX: metricsMaxX
756
+ } = metrics;
757
+ var maxX = metricsMaxX; // Draw row lines
743
758
 
744
759
  for (var i = 0; i < rows.length; i += 1) {
745
760
  var row = rows[i];
@@ -913,7 +928,7 @@ class GridRenderer {
913
928
  var fontWidth = fontWidths.get(context.font);
914
929
  var truncatedText = this.getCachedTruncatedString(context, text, textWidth - cellHorizontalPadding * 2, fontWidth);
915
930
 
916
- if (truncatedText != null) {
931
+ if (truncatedText) {
917
932
  context.fillText(truncatedText, textX, textY);
918
933
  }
919
934
  }
@@ -1054,11 +1069,13 @@ class GridRenderer {
1054
1069
  } = state;
1055
1070
  var {
1056
1071
  columnHeaderHeight,
1072
+ floatingColumns,
1057
1073
  gridX,
1058
1074
  width,
1059
1075
  visibleColumns,
1060
1076
  visibleColumnWidths,
1061
- visibleColumnXs
1077
+ visibleColumnXs,
1078
+ floatingLeftColumnCount
1062
1079
  } = metrics;
1063
1080
 
1064
1081
  if (columnHeaderHeight <= 0) {
@@ -1075,31 +1092,88 @@ class GridRenderer {
1075
1092
  } = theme;
1076
1093
  var hiddenSeparatorHeight = columnHeaderHeight * 0.5;
1077
1094
  var hiddenY = columnHeaderHeight * 0.5 - hiddenSeparatorHeight * 0.5;
1095
+ var containsFrozenColumns = floatingLeftColumnCount > 0;
1096
+ var floatingLeftColumnsWidth = 0;
1078
1097
  context.save();
1079
1098
  context.beginPath(); // Fill in the background
1080
1099
 
1081
1100
  context.fillStyle = headerBackgroundColor;
1082
- context.fillRect(0, 0, width, columnHeaderHeight); // Draw the separators
1101
+ context.fillRect(0, 0, width, columnHeaderHeight);
1102
+ context.fillStyle = headerColor; // Visible columns.
1103
+
1104
+ for (var i = 0; i < visibleColumns.length; i += 1) {
1105
+ var column = visibleColumns[i];
1106
+ var columnWidth = visibleColumnWidths.get(column);
1107
+ var x = visibleColumnXs.get(column) + gridX;
1108
+ this.drawColumnHeader(context, state, column, x, columnWidth);
1109
+ }
1110
+
1111
+ if (containsFrozenColumns) {
1112
+ floatingLeftColumnsWidth = visibleColumnXs.get(floatingLeftColumnCount - 1) + visibleColumnWidths.get(floatingLeftColumnCount - 1); // Frozen columns' background
1113
+
1114
+ context.fillStyle = headerBackgroundColor;
1115
+ context.fillRect(gridX, 0, floatingLeftColumnsWidth, columnHeaderHeight); // Frozen columns.
1116
+
1117
+ context.fillStyle = headerColor;
1118
+
1119
+ for (var _i5 = 0; _i5 < floatingColumns.length; _i5 += 1) {
1120
+ var _column = floatingColumns[_i5];
1121
+
1122
+ var _columnWidth = visibleColumnWidths.get(_column);
1123
+
1124
+ var _x4 = visibleColumnXs.get(_column) + gridX;
1125
+
1126
+ this.drawColumnHeader(context, state, _column, _x4, _columnWidth);
1127
+ }
1128
+ } // Draw the separators, visible columns then floating columns.
1129
+
1083
1130
 
1084
1131
  if (headerSeparatorColor) {
1085
1132
  context.strokeStyle = headerSeparatorColor;
1086
1133
  context.beginPath();
1087
- var hiddenColumns = [];
1134
+ var hiddenColumns = []; // Draw visible column separators.
1135
+
1088
1136
  var isPreviousColumnHidden = false;
1089
1137
 
1090
- for (var i = 0; i < visibleColumns.length; i += 1) {
1091
- var column = visibleColumns[i];
1092
- var columnX = visibleColumnXs.get(column);
1093
- var columnWidth = visibleColumnWidths.get(column);
1138
+ for (var _i6 = 0; _i6 < visibleColumns.length; _i6 += 1) {
1139
+ var _column2 = visibleColumns[_i6];
1140
+ var columnX = visibleColumnXs.get(_column2);
1141
+
1142
+ var _columnWidth2 = visibleColumnWidths.get(_column2);
1143
+
1144
+ if (!(columnX < floatingLeftColumnsWidth - _columnWidth2)) {
1145
+ if (_columnWidth2 > 0) {
1146
+ var _x5 = gridX + columnX + _columnWidth2 + 0.5;
1147
+
1148
+ context.moveTo(_x5, 0);
1149
+ context.lineTo(_x5, columnHeaderHeight - 0.5);
1150
+ isPreviousColumnHidden = false;
1151
+ } else if (!isPreviousColumnHidden) {
1152
+ isPreviousColumnHidden = true;
1153
+ hiddenColumns.push(_column2);
1154
+ }
1155
+ }
1156
+ } // Draw floating column separators.
1157
+
1094
1158
 
1095
- if (columnWidth > 0) {
1096
- var x = gridX + columnX + columnWidth + 0.5;
1097
- context.moveTo(x, 0);
1098
- context.lineTo(x, columnHeaderHeight - 0.5);
1159
+ isPreviousColumnHidden = false;
1160
+
1161
+ for (var _i7 = 0; _i7 < floatingColumns.length; _i7 += 1) {
1162
+ var _column3 = floatingColumns[_i7];
1163
+
1164
+ var _columnX = visibleColumnXs.get(_column3);
1165
+
1166
+ var _columnWidth3 = visibleColumnWidths.get(_column3);
1167
+
1168
+ if (_columnWidth3 > 0) {
1169
+ var _x6 = gridX + _columnX + _columnWidth3 + 0.5;
1170
+
1171
+ context.moveTo(_x6, 0);
1172
+ context.lineTo(_x6, columnHeaderHeight - 0.5);
1099
1173
  isPreviousColumnHidden = false;
1100
1174
  } else if (!isPreviousColumnHidden) {
1101
1175
  isPreviousColumnHidden = true;
1102
- hiddenColumns.push(column);
1176
+ hiddenColumns.push(_column3);
1103
1177
  }
1104
1178
  } // Bottom Border, should be interior to the header height
1105
1179
 
@@ -1111,14 +1185,14 @@ class GridRenderer {
1111
1185
  context.beginPath();
1112
1186
  context.fillStyle = headerSeparatorColor;
1113
1187
 
1114
- for (var _i5 = 0; _i5 < hiddenColumns.length; _i5 += 1) {
1115
- var _column = hiddenColumns[_i5];
1188
+ for (var _i8 = 0; _i8 < hiddenColumns.length; _i8 += 1) {
1189
+ var _column4 = hiddenColumns[_i8];
1116
1190
 
1117
- var _columnX = visibleColumnXs.get(_column);
1191
+ var _columnX2 = visibleColumnXs.get(_column4);
1118
1192
 
1119
- var _columnWidth = visibleColumnWidths.get(_column);
1193
+ var _columnWidth4 = visibleColumnWidths.get(_column4);
1120
1194
 
1121
- var minX = gridX + _columnX + _columnWidth + 0.5 - headerHiddenSeparatorSize * 0.5;
1195
+ var minX = gridX + _columnX2 + _columnWidth4 + 0.5 - headerHiddenSeparatorSize * 0.5;
1122
1196
  context.rect(minX, hiddenY, headerHiddenSeparatorSize, hiddenSeparatorHeight);
1123
1197
  }
1124
1198
 
@@ -1135,47 +1209,35 @@ class GridRenderer {
1135
1209
  if (highlightedSeparator != null && (!isDragging || draggingColumnSeparator != null)) {
1136
1210
  context.strokeStyle = headerSeparatorHoverColor;
1137
1211
 
1138
- var _columnX2 = visibleColumnXs.get(highlightedSeparator);
1212
+ var _columnX3 = visibleColumnXs.get(highlightedSeparator);
1139
1213
 
1140
- var _columnWidth2 = visibleColumnWidths.get(highlightedSeparator);
1214
+ var _columnWidth5 = visibleColumnWidths.get(highlightedSeparator);
1141
1215
 
1142
- var _x4 = gridX + _columnX2 + _columnWidth2 + 0.5;
1216
+ var _x7 = gridX + _columnX3 + _columnWidth5 + 0.5;
1143
1217
 
1144
1218
  var visibleColumnIndex = visibleColumns.indexOf(highlightedSeparator);
1145
1219
  var nextColumn = visibleColumnIndex < visibleColumns.length - 1 ? visibleColumns[visibleColumnIndex + 1] : null;
1146
1220
  var nextColumnWidth = nextColumn != null ? visibleColumnWidths.get(nextColumn) : null;
1147
- var isColumnHidden = _columnWidth2 === 0;
1221
+ var isColumnHidden = _columnWidth5 === 0;
1148
1222
  var isNextColumnHidden = nextColumnWidth != null && nextColumnWidth === 0;
1149
1223
 
1150
1224
  if (isColumnHidden) {
1151
1225
  context.strokeStyle = headerHiddenSeparatorHoverColor;
1152
1226
  context.fillStyle = headerHiddenSeparatorHoverColor;
1153
- context.fillRect(_x4, hiddenY, headerHiddenSeparatorSize * 0.5, hiddenSeparatorHeight);
1227
+ context.fillRect(_x7, hiddenY, headerHiddenSeparatorSize * 0.5, hiddenSeparatorHeight);
1154
1228
  } else if (isNextColumnHidden) {
1155
1229
  context.fillStyle = headerSeparatorHoverColor;
1156
- context.fillRect(_x4 - headerHiddenSeparatorSize * 0.5, hiddenY, headerHiddenSeparatorSize * 0.5, hiddenSeparatorHeight);
1230
+ context.fillRect(_x7 - headerHiddenSeparatorSize * 0.5, hiddenY, headerHiddenSeparatorSize * 0.5, hiddenSeparatorHeight);
1157
1231
  } // column seperator hover line
1158
1232
 
1159
1233
 
1160
1234
  context.beginPath();
1161
- context.moveTo(_x4, 0);
1162
- context.lineTo(_x4, columnHeaderHeight - 1);
1235
+ context.moveTo(_x7, 0);
1236
+ context.lineTo(_x7, columnHeaderHeight - 1);
1163
1237
  context.stroke();
1164
1238
  }
1165
1239
  }
1166
1240
 
1167
- context.fillStyle = headerColor;
1168
-
1169
- for (var _i6 = 0; _i6 < visibleColumns.length; _i6 += 1) {
1170
- var _column2 = visibleColumns[_i6];
1171
-
1172
- var _columnWidth3 = visibleColumnWidths.get(_column2);
1173
-
1174
- var _x5 = visibleColumnXs.get(_column2) + gridX;
1175
-
1176
- this.drawColumnHeader(context, state, _column2, _x5, _columnWidth3);
1177
- }
1178
-
1179
1241
  context.restore();
1180
1242
  }
1181
1243
 
@@ -1194,11 +1256,6 @@ class GridRenderer {
1194
1256
  } = metrics;
1195
1257
  var modelColumn = modelColumns.get(column);
1196
1258
  var text = model.textForColumnHeader(modelColumn);
1197
-
1198
- if (!text) {
1199
- return;
1200
- }
1201
-
1202
1259
  var {
1203
1260
  headerHorizontalPadding
1204
1261
  } = theme;
@@ -1225,12 +1282,12 @@ class GridRenderer {
1225
1282
  context.textAlign = 'left';
1226
1283
  context.fillText(text, x, y);
1227
1284
  } else {
1228
- var _x6 = columnX + columnWidth * 0.5;
1285
+ var _x8 = columnX + columnWidth * 0.5;
1229
1286
 
1230
1287
  var _y5 = columnHeaderHeight * 0.5;
1231
1288
 
1232
1289
  context.textAlign = 'center';
1233
- context.fillText(text, _x6, _y5);
1290
+ context.fillText(text, _x8, _y5);
1234
1291
  }
1235
1292
 
1236
1293
  context.restore();
@@ -1305,8 +1362,8 @@ class GridRenderer {
1305
1362
  context.beginPath();
1306
1363
  context.fillStyle = headerSeparatorColor;
1307
1364
 
1308
- for (var _i7 = 0; _i7 < hiddenRows.length; _i7 += 1) {
1309
- var _row4 = hiddenRows[_i7];
1365
+ for (var _i9 = 0; _i9 < hiddenRows.length; _i9 += 1) {
1366
+ var _row4 = hiddenRows[_i9];
1310
1367
 
1311
1368
  var _rowY = visibleRowYs.get(_row4);
1312
1369
 
@@ -1364,8 +1421,8 @@ class GridRenderer {
1364
1421
  context.fillStyle = headerColor;
1365
1422
  context.textAlign = 'right';
1366
1423
 
1367
- for (var _i8 = 0; _i8 < visibleRows.length; _i8 += 1) {
1368
- var _row5 = visibleRows[_i8];
1424
+ for (var _i10 = 0; _i10 < visibleRows.length; _i10 += 1) {
1425
+ var _row5 = visibleRows[_i10];
1369
1426
 
1370
1427
  var _rowHeight3 = visibleRowHeights.get(_row5);
1371
1428
 
@@ -1474,8 +1531,8 @@ class GridRenderer {
1474
1531
  context.beginPath();
1475
1532
  context.fillStyle = headerSeparatorColor;
1476
1533
 
1477
- for (var _i9 = 0; _i9 < hiddenRows.length; _i9 += 1) {
1478
- var _row6 = hiddenRows[_i9];
1534
+ for (var _i11 = 0; _i11 < hiddenRows.length; _i11 += 1) {
1535
+ var _row6 = hiddenRows[_i11];
1479
1536
 
1480
1537
  var _rowY3 = visibleRowYs.get(_row6);
1481
1538
 
@@ -1534,8 +1591,8 @@ class GridRenderer {
1534
1591
  context.textAlign = 'left';
1535
1592
  var textX = x + cellHorizontalPadding;
1536
1593
 
1537
- for (var _i10 = 0; _i10 < visibleRows.length; _i10 += 1) {
1538
- var _row7 = visibleRows[_i10];
1594
+ for (var _i12 = 0; _i12 < visibleRows.length; _i12 += 1) {
1595
+ var _row7 = visibleRows[_i12];
1539
1596
 
1540
1597
  var _rowHeight6 = visibleRowHeights.get(_row7);
1541
1598
 
@@ -1614,25 +1671,25 @@ class GridRenderer {
1614
1671
 
1615
1672
  if (endRow >= top && bottom >= startRow && endColumn >= left && right >= startColumn) {
1616
1673
  // Need to offset the x/y coordinates so that the line draws nice and crisp
1617
- var _x7 = startColumn >= left && visibleColumnXs.has(startColumn) ? Math.round(visibleColumnXs.get(startColumn)) + 0.5 : minX;
1674
+ var _x9 = startColumn >= left && visibleColumnXs.has(startColumn) ? Math.round(visibleColumnXs.get(startColumn)) + 0.5 : minX;
1618
1675
 
1619
1676
  var _y9 = startRow >= top && visibleRowYs.has(startRow) ? Math.max(Math.round(visibleRowYs.get(startRow)) + 0.5, 0.5) : minY;
1620
1677
 
1621
1678
  var endX = endColumn <= right && visibleColumnXs.has(endColumn) ? Math.round(visibleColumnXs.get(endColumn) + visibleColumnWidths.get(endColumn)) - 0.5 : maxX;
1622
1679
  var endY = endRow <= bottom && visibleRowYs.has(endRow) ? Math.round(visibleRowYs.get(endRow) + visibleRowHeights.get(endRow)) - 0.5 : maxY;
1623
- context.rect(_x7, _y9, endX - _x7, endY - _y9);
1680
+ context.rect(_x9, _y9, endX - _x9, endY - _y9);
1624
1681
  } // draw the inner transparent fill
1625
1682
 
1626
1683
 
1627
1684
  context.fillStyle = theme.selectionColor;
1628
1685
  context.fill();
1629
- /*
1630
- draw an "inner stroke" that's clipped to just inside of the rects
1631
- to act as a casing to the outer stroke. 3px width because 1px is outside
1632
- the rect (but clipped), 1px is "on" the rect (technically this pixel is
1633
- a half pixel clip as well due to rects offset, but we are immediately painting
1634
- over it), and then the 1px inside (which is the desired pixel).
1635
- */
1686
+ /**
1687
+ * draw an "inner stroke" that's clipped to just inside of the rects
1688
+ * to act as a casing to the outer stroke. 3px width because 1px is outside
1689
+ * the rect (but clipped), 1px is "on" the rect (technically this pixel is
1690
+ * a half pixel clip as well due to rects offset, but we are immediately painting
1691
+ * over it), and then the 1px inside (which is the desired pixel).
1692
+ */
1636
1693
 
1637
1694
  context.save();
1638
1695
  context.clip();
@@ -1914,15 +1971,15 @@ class GridRenderer {
1914
1971
  }
1915
1972
 
1916
1973
  if (hasVerticalBar) {
1917
- var _x8 = width - rowHeaderWidth - vScrollBarSize;
1974
+ var _x10 = width - rowHeaderWidth - vScrollBarSize;
1918
1975
 
1919
1976
  var _y10 = scrollY; // scrollbar casing
1920
1977
 
1921
1978
  context.fillStyle = scrollBarCasingColor;
1922
- context.fillRect(_x8, 0, vScrollBarSize - scrollBarCasingWidth, barHeight); // scrollbar track
1979
+ context.fillRect(_x10, 0, vScrollBarSize - scrollBarCasingWidth, barHeight); // scrollbar track
1923
1980
 
1924
1981
  context.fillStyle = isVerticalBarHover ? scrollBarHoverBackgroundColor : scrollBarBackgroundColor;
1925
- context.fillRect(_x8 + scrollBarCasingWidth, 0, vScrollBarSize - scrollBarCasingWidth, barHeight); // scrollbar thumb
1982
+ context.fillRect(_x10 + scrollBarCasingWidth, 0, vScrollBarSize - scrollBarCasingWidth, barHeight); // scrollbar thumb
1926
1983
 
1927
1984
  if (isDraggingVerticalScrollBar) {
1928
1985
  context.fillStyle = scrollBarActiveColor;
@@ -1932,7 +1989,7 @@ class GridRenderer {
1932
1989
  context.fillStyle = scrollBarColor;
1933
1990
  }
1934
1991
 
1935
- context.fillRect(_x8 + scrollBarCasingWidth, _y10, vScrollBarSize - scrollBarCasingWidth, handleHeight);
1992
+ context.fillRect(_x10 + scrollBarCasingWidth, _y10, vScrollBarSize - scrollBarCasingWidth, handleHeight);
1936
1993
  }
1937
1994
 
1938
1995
  context.translate(-rowHeaderWidth, -columnHeaderHeight);