@domoinc/multiline-chart
Version:
MultiLineChart - Domo Widget
227 lines (196 loc) • 9.13 kB
JavaScript
// d3.domoStrings is an object of functions that will alter strings with font shrinking and truncating.
// trunc(string, characters, useWordBoundary): The string to modify and the characters you want to truncate to.
// Ex: .text(function(d){ return d3.domoStrings.trunc(d.name, 25)
// truncToFit(textElement, width): textElement is the d3 selection of the text element and width is the width that you want the element to fit inside after truncating.
// Ex: d3.selectAll("text").each(function(){ return d3.domoStrings.truncToFit(d3.select(this), 45); });
// shrinkToFit(textElement, width, height, size): textElement is the d3 selection of the text element, width is the target width to shrink to, height is the target height, size is the starting size of the font.
// Ex: Ex: d3.selectAll("text").each(function(){ return d3.domoStrings.shrinkToFit(d3.select(this), 45, 25, 10); });
// shrinkToTrunc(textElement, width, size): textElement is the d3 selection of the text element, width is the target width to shrink to and size is used if you want to define a starting font size to shrink from. If size is null sizes start at 14
// Ex: d3.selectAll("text").each(function(){ return d3.domoStrings.truncToFit(d3.select(this), 45, 18); });
d3.domoStrings = {
'trunc': function(str, chars, useWordBoundary) {
var toLong = str.length > chars,
s_ = toLong ? str.substr(0, chars - 1) : str;
s_ = useWordBoundary && toLong ? s_.substr(0, s_.lastIndexOf(' ')) : s_;
s_ = toLong ? s_ + '...' : s_;
return s_;
},
'truncToFitVertical': function(textElement, height) {
padding = 5;
var wasEdited = false;
str = textElement.text();
tempBox = textElement.node()
.getBoundingClientRect();
for (var i = str.length; i >= 0; i--) {
textElement
.text(str)
tempbox = textElement.node()
.getBoundingClientRect();
if (height - padding < tempbox.height) {
str = str.substr(0, str.length - 1)
wasEdited = true;
} else {
break;
}
}
if (wasEdited === true) {
str = str.substr(0, str.length - 1) + '...';
textElement.text(str);
} else {
return;
}
},
'truncToFit': function(textElement, width) {
padding = 5;
var wasEdited = false;
str = textElement.text();
tempBox = textElement.node()
.getBoundingClientRect();
for (var i = str.length; i >= 0; i--) {
textElement
.text(str)
tempbox = textElement.node()
.getBoundingClientRect();
if (width - padding < tempbox.width) {
str = str.substr(0, str.length - 1)
wasEdited = true;
} else {
break;
}
}
if (wasEdited === true) {
str = str.substr(0, str.length - 1) + '...';
textElement.text(str);
} else {
return;
}
},
'shrinkToFit': function(textElement, width, height, size) {
var padding = 5,
tempBox;
if (size) {
while (size > 6) {
//Try a font size
textElement.style("font-size", size + "px");
tempBox = textElement.node()
.getBoundingClientRect();
//Check if it fits
if (tempBox.width < width - padding &&
tempBox.height < height - padding)
break;
else
size = size - 2;
}
if (size < 8) {
textElement.style("font-size", "0px");
}
} else {
var possibleTextSizes = ["14px", "12px", "10px", "8px", "0px"];
var pTextIndex = 0;
while (pTextIndex !== possibleTextSizes.length - 1) {
//Try a font size
textElement.style("font-size", possibleTextSizes[pTextIndex] + 'px');
tempBox = textElement.node()
.getBoundingClientRect();
//Check if it fits
if (tempBox.width < width - padding &&
tempBox.height < height - padding)
break; //Got it
else
pTextIndex++; //Try the next smaller size.
}
if (pTextIndex === possibleTextSizes.length - 1) {
textElement.style("font-size", "0px");
}
}
},
'shrinkToTrunc': function(textElement, width, height, size, useWordBoundary) {
str = textElement.text();
var tempBox,
padding = 5;
if (size) {
while (size > 6) {
//Try a font size
textElement.style("font-size", size + "px");
tempBox = textElement.node()
.getBoundingClientRect();
//Check if it fits
if (tempBox.width < width - padding &&
tempBox.height < height - padding)
break;
else
size = size - 2;
}
if (size < 8) //still doesnt fit with just font shrinking, now to truncate
{
textElement.style("font-size", "8px");
d3.domoStrings.truncToFit(textElement, width)
}
} else {
var possibleTextSizes = ["14px", "12px", "10px", "8px", "0px"];
var pTextIndex = 0;
while (pTextIndex !== possibleTextSizes.length - 1) {
//Try a font size
textElement.style("font-size", possibleTextSizes[pTextIndex] + 'px');
tempBox = textElement.node()
.getBoundingClientRect();
//Check if it fits
if (tempBox.width < width - padding &&
tempBox.height < height - padding)
break; //Got it
else
pTextIndex++; //Try the next smaller size.
}
//Once we hit the end of our array of sizes, start truncating
if (pTextIndex === possibleTextSizes.length - 1) {
//once again set font size to 8 to begin with
textElement.style("font-size", "8px");
d3.domoStrings.truncToFit(textElement, width)
}
}
},
'wrapText': function(textElement, width) {
var padding = 5;
var str = textElement.text();
var dy = textElement.node()
.getBoundingClientRect()
.height;
var words = str.split(' ');
if (words.length <= 1) {
return;
}
var lines = [];
var curLine = words[0];
var testLine = curLine;
for (var i = 1; i < words.length; i++) {
testLine += ' ' + words[i];
textElement.text(testLine);
var testBox = textElement.node()
.getBoundingClientRect();
if (testBox.width <= width - padding) {
curLine = testLine;
} else {
lines.push(curLine);
curLine = words[i];
testLine = curLine;
}
if (i === words.length - 1) {
lines.push(curLine);
}
}
textElement.text('');
for (i = 0; i < lines.length; i++) {
var tspan = textElement.append('tspan')
.text(lines[i]);
if (i > 0) {
tspan.attr({
'x': 0 + 'px',
'dy': dy + 'px'
})
}
}
},
'help': function() {
console.log('d3.domoStrings is an object of functions that will alter strings with font shrinking and truncating.\n\ntrunc(string, characters, useWordBoundary): The string to modify and the characters you want to truncate to.\nEx: .text(function(d){ return d3.domoStrings.trunc(d.name, 25)\n\ntruncToFit(textElement, width): textElement is the d3 selection of the text element and width is the width that you want the element to fit inside after truncating.\nEx: d3.selectAll("text").each(function(){ return d3.domoStrings.truncToFit(d3.select(this), 45); });\n\nshrinkToFit(textElement, width, height, size): textElement is the d3 selection of the text element, width is the target width to shrink to, height is the target height, size is the starting size of the font.\nEx: Ex: d3.selectAll("text").each(function(){ return d3.domoStrings.shrinkToFit(d3.select(this), 45, 25, 10); });\n\nshrinkToTrunc(textElement, width, size): textElement is the d3 selection of the text element, width is the target width to shrink to and size is used if you want to define a starting font size to shrink from. If size is null sizes start at 14\nEx: d3.selectAll("text").each(function(){ return d3.domoStrings.truncToFit(d3.select(this), 45, 18); });')
}
}