-
Notifications
You must be signed in to change notification settings - Fork 168
Handle cell text overflow with ellipsis or clipping #341
base: master
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,7 @@ class TextRenderer extends CellRenderer { | |
this.backgroundColor = options.backgroundColor || ''; | ||
this.verticalAlignment = options.verticalAlignment || 'center'; | ||
this.horizontalAlignment = options.horizontalAlignment || 'left'; | ||
this.overflow = options.overflow || 'ellipsis'; | ||
this.format = options.format || TextRenderer.formatGeneric(); | ||
} | ||
|
||
|
@@ -59,6 +60,11 @@ class TextRenderer extends CellRenderer { | |
*/ | ||
readonly horizontalAlignment: CellRenderer.ConfigOption<TextRenderer.HorizontalAlignment>; | ||
|
||
/** | ||
* The overflow behavior for the cell text. | ||
*/ | ||
readonly overflow: CellRenderer.ConfigOption<TextRenderer.Overflow>; | ||
|
||
/** | ||
* The format function for the cell value. | ||
*/ | ||
|
@@ -186,6 +192,7 @@ class TextRenderer extends CellRenderer { | |
// Set up the text position variables. | ||
let textX: number; | ||
let textY: number; | ||
let boxWidth: number; | ||
|
||
// Compute the Y position for the text. | ||
switch (vAlign) { | ||
|
@@ -205,13 +212,16 @@ class TextRenderer extends CellRenderer { | |
// Compute the X position for the text. | ||
switch (hAlign) { | ||
case 'left': | ||
textX = config.x + 2; | ||
textX = config.x + 8; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why the change to the original padding? Should we make that configurable? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably should be configurable. I found a slightly larger padding led to better white space balancing and made the grid much easier to scan and read when using it with real data. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IIRC I got the original padding values from Excel on Windows. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, I'll change it back, or add it as an option. |
||
boxWidth = config.width - 14; | ||
break; | ||
case 'center': | ||
textX = config.x + config.width / 2; | ||
boxWidth = config.width; | ||
break; | ||
case 'right': | ||
textX = config.x + config.width - 3; | ||
textX = config.x + config.width - 8; | ||
boxWidth = config.width - 14; | ||
break; | ||
default: | ||
throw 'unreachable'; | ||
|
@@ -224,6 +234,25 @@ class TextRenderer extends CellRenderer { | |
gc.clip(); | ||
} | ||
|
||
let overflow = CellRenderer.resolveOption(this.overflow, config); | ||
|
||
if (overflow === 'ellipsis') { | ||
let elide = '\u2026'; | ||
let textWidth = gc.measureText(text).width; | ||
|
||
// Compute elided text | ||
while ((textWidth > boxWidth) && (text.length > 1)) { | ||
if (text.length > 4 && textWidth >= 2 * boxWidth) { | ||
// If text width is substantially bigger, take half the string | ||
text = text.substr(0, (text.length / 2) + 1) + elide; | ||
} else { | ||
// Otherwise incrementally remove the last character | ||
text = text.substr(0, text.length - 2) + elide; | ||
} | ||
textWidth = gc.measureText(text).width; | ||
} | ||
} | ||
|
||
// Set the gc state. | ||
gc.font = font; | ||
gc.fillStyle = color; | ||
|
@@ -253,6 +282,12 @@ namespace TextRenderer { | |
export | ||
type HorizontalAlignment = 'left' | 'center' | 'right'; | ||
|
||
/** | ||
* A type alias for the supported overflow modes. | ||
*/ | ||
export | ||
type Overflow = 'clip' | 'ellipsis'; | ||
|
||
/** | ||
* An options object for initializing a text renderer. | ||
*/ | ||
|
@@ -293,6 +328,13 @@ namespace TextRenderer { | |
*/ | ||
horizontalAlignment?: CellRenderer.ConfigOption<HorizontalAlignment>; | ||
|
||
/** | ||
* The overflow behavior for text. | ||
* | ||
* The default is `'clip'`. | ||
*/ | ||
overflow?: CellRenderer.ConfigOption<Overflow>; | ||
|
||
/** | ||
* The format function for the renderer. | ||
* | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the default be
'clip'
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From an efficiency/cost perspective, it should be clip, but from a default UX experience I feel ellipsis are more user friendly. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was going based on what line 334 says.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah sorry, I was saying that either value as default makes sense, depending
on whether you want to optimize the speed or the UX.