Skip to content
This repository has been archived by the owner on Nov 6, 2019. It is now read-only.

Handle cell text overflow with ellipsis or clipping #341

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 44 additions & 2 deletions packages/datagrid/src/textrenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 || 'clip';
this.format = options.format || TextRenderer.formatGeneric();
}

Expand Down Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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) {
Expand All @@ -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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the change to the original padding? Should we make that configurable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC I got the original padding values from Excel on Windows.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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';
Expand All @@ -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;
Expand Down Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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.
*
Expand Down