Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow wrapping text in cells. #482

Open
joseberlines opened this issue Dec 2, 2022 · 4 comments
Open

Allow wrapping text in cells. #482

joseberlines opened this issue Dec 2, 2022 · 4 comments
Labels
enhancement New feature or request

Comments

@joseberlines
Copy link

joseberlines commented Dec 2, 2022

Lumino is behind ipydatagrid.
It would be very positive that Lumino allows multi lines cells in ipydatagrid.

This issue in ipydatagrid shows the situation:

jupyter-widgets/ipydatagrid#355

@joseberlines joseberlines added the enhancement New feature or request label Dec 2, 2022
@welcome
Copy link

welcome bot commented Dec 2, 2022

Thank you for opening your first issue in this project! Engagement like this is essential for open source projects! 🤗

If you haven't done so already, check out Jupyter's Code of Conduct. Also, please try to follow the issue template as it helps other other community members to contribute more effectively.
welcome
You can meet the other Jovyans by joining our Discourse forum. There is also an intro thread there where you can stop by and say Hi! 👋

Welcome to the Jupyter community! 🎉

@krassowski
Copy link
Member

krassowski commented Dec 22, 2022

@martinRenou I am a bit confused as I see that text wrapping is implemented in text renderer:

// The current text width in pixels.
let textWidth = gc.measureText(text).width;
// Apply text wrapping if enabled.
if (wrapText && textWidth > boxWidth) {
// Make sure box clipping happens.
gc.beginPath();
gc.rect(config.x, config.y, config.width, config.height - 1);
gc.clip();
// Split column name to words based on
// whitespace preceding a word boundary.
// "Hello world" --> ["Hello ", "world"]
const wordsInColumn = text.split(/\s(?=\b)/);
// Y-coordinate offset for any additional lines
let curY = textY;
let textInCurrentLine = wordsInColumn.shift()!;
// Single word. Applying text wrap on word by splitting
// it into characters and fitting the maximum number of
// characters possible per line (box width).
if (wordsInColumn.length === 0) {
let curLineTextWidth = gc.measureText(textInCurrentLine).width;
while (curLineTextWidth > boxWidth && textInCurrentLine !== '') {
// Iterating from the end of the string until we find a
// substring (0,i) which has a width less than the box width.
for (let i = textInCurrentLine.length; i > 0; i--) {
const curSubString = textInCurrentLine.substring(0, i);
const curSubStringWidth = gc.measureText(curSubString).width;
if (curSubStringWidth < boxWidth || curSubString.length === 1) {
// Found a substring which has a width less than the current
// box width. Rendering that substring on the current line
// and setting the remainder of the parent string as the next
// string to iterate on for the next line.
const nextLineText = textInCurrentLine.substring(
i,
textInCurrentLine.length
);
textInCurrentLine = nextLineText;
curLineTextWidth = gc.measureText(textInCurrentLine).width;
gc.fillText(curSubString, textX, curY);
curY += textHeight;
// No need to continue iterating after we identified
// an index to break the string on.
break;
}
}
}
}
// Multiple words in column header. Fitting maximum
// number of words possible per line (box width).
else {
while (wordsInColumn.length !== 0) {
// Processing the next word in the queue.
const curWord = wordsInColumn.shift();
// Joining that word with the existing text for
// the current line.
const incrementedText = [textInCurrentLine, curWord].join(' ');
const incrementedTextWidth = gc.measureText(incrementedText).width;
if (incrementedTextWidth > boxWidth) {
// If the newly combined text has a width larger than
// the box width, we render the line before the current
// word was added. We set the current word as the next
// line.
gc.fillText(textInCurrentLine, textX, curY);
curY += textHeight;
textInCurrentLine = curWord!;
} else {
// The combined text hasd a width less than the box width. We
// set the the current line text to be the new combined text.
textInCurrentLine = incrementedText;
}
}
}
gc.fillText(textInCurrentLine!, textX, curY);
// Terminating the call here as we don't want
// to apply text eliding when wrapping is active.
return;
}

what specifically is missing on lumino side?

@joseberlines
Copy link
Author

Thanks for follow this up. My understanding is that wrapping text in ipydatagrid is not possible because this is an issue in Lumino. If this is not the case (I am not at all a JAVA coder and can not really follow the code above) I might open again the issue in ipydatagrid regarding wrapping text in cells.

@vidartf
Copy link
Member

vidartf commented Mar 8, 2023

I think the issue as outlined on the datagrid repo is the automatic sizing of rows dependent on the number of lines that are in a cell. See: jupyter-widgets/ipydatagrid#294 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants