Im new in typescript and svg and d3, So I have this code
this.main
.selectAll(this.appCssConstants.sliceLabel.selectorName)
.data(root)
.enter()
.append("text")
.style("fill", "blue")
.classed(this.appCssConstants.sliceLabel.className, true)
// font size + slice padding
.attr("dy", (d, i) => {
return labelshift - d.depth * labelshiftmulti;
})
.append("textPath")
.attr("startOffset", "50%")
.attr("xlink:href", (d, i) => "#sliceLabel_" + i)
.text(dataPoint => dataPoint.data.name)
.attr("textLength")
.each(this.wrapPathText(labelPadding));
...
private wrapPathText(padding?: number): (slice: HierarchyRectangularNode<SunburstDataPoint>, index: number) => void {
const self = this;
return function () {
const selection: Selection<BaseType, any, BaseType, any> = d3Select(this);
const width = (<SVGPathElement>d3Select(selection.attr("xlink:href")).node()).getTotalLength();
self.wrapText(selection, padding, width);
};
}
private wrapText(selection: Selection<BaseType, any, BaseType, any>, padding?: number, width?: number): void {
let node: SVGTextElement = <SVGTextElement>selection.node(),
textLength: number = node.getComputedTextLength(),
text: string = selection.text();
width = width || 0;
padding = padding || 0;
while (textLength > (width - 2 * padding) && text.length > 0) {
text = text.slice(0, -1);
selection.text(text + "\u2026");
textLength = node.getComputedTextLength();
}
if (textLength > (width - 2 * padding)) {
selection.text("");
}
}
I have a loop ".each" in first part of the code that calls method wrapPathText and wrapPathText have a for loop that takes long long time in the loop for slicing text
My question is - Is there a way to optimize this loop? For example removing more than one letter in each loopto fit the string? Another question - Is there a way to fit a string with specific giving length (in my case 'width - 2 * padding') for example by the help of a specific attribute without using the unoptimized for loop?