{"ScriptPreparationCode":null,"TestCases":[{"Name":"progressively","Code":"var approxMeasure = (a) =\u003E\r\n a.length * 0.6 * 26;\r\n\r\nvar getLine = ({\r\n str,\r\n lineStartIndex,\r\n lineEndIndex,\r\n standardCharWidth,\r\n maxWidth,\r\n measure,\r\n}) =\u003E {\r\n const line = str.slice(lineStartIndex, lineEndIndex);\r\n const lineWidth = measure(line);\r\n\r\n // in the current code something seems to be adjusting the max width based on the label width, but it is not in scope of the string wrapping\r\n // so I floor the delta for now. which is impresice but avoids wrapping the string based on sub-pixel discrepancies\r\n const delta = Math.floor(maxWidth - lineWidth);\r\n\r\n if (lineEndIndex \u002B 1 \u003E str.length \u0026\u0026 delta \u003E= 0) {\r\n // string fits into max width completely\r\n return line;\r\n }\r\n\r\n const numberOfCharsDeviating = Math.floor(\r\n Math.abs(delta / standardCharWidth)\r\n );\r\n\r\n if (delta \u003C 0) {\r\n // do not exceed the maximum width, even if the dela is less than the standard char width\r\n return getLine({\r\n str,\r\n lineStartIndex,\r\n lineEndIndex: lineEndIndex - Math.max(numberOfCharsDeviating, 1),\r\n standardCharWidth,\r\n maxWidth,\r\n measure,\r\n });\r\n } else if (numberOfCharsDeviating \u003E 0) {\r\n // add chars only if the delta is greater than the standard char width\r\n return getLine({\r\n str,\r\n lineStartIndex,\r\n lineEndIndex: lineEndIndex \u002B numberOfCharsDeviating - 1,\r\n standardCharWidth,\r\n maxWidth,\r\n measure,\r\n });\r\n }\r\n\r\n // If there is a space within 3 chars at the end of the line, move the word to a next line\r\n const lastSpaceIndex = line.lastIndexOf(\u0027 \u0027);\r\n if (lastSpaceIndex !== -1 \u0026\u0026 line.length - lastSpaceIndex \u003C= 3) {\r\n return line.slice(0, lastSpaceIndex \u002B 1);\r\n }\r\n\r\n // If there is no space in the whole current line, break it regardless of the next 3 chars\r\n // but if there is a space within the current line:\r\n // - move the word to a next line if there is a space within the next 3 chars\r\n // - move the word to a next line the remaining chars are less than 4\r\n\r\n const remainingTextLength = str.length - lineEndIndex - 1;\r\n if (\r\n lastSpaceIndex !== -1 \u0026\u0026\r\n (remainingTextLength \u003C 3 ||\r\n str.slice(lineEndIndex, lineEndIndex \u002B 4).includes(\u0027 \u0027))\r\n ) {\r\n return line.slice(0, lastSpaceIndex \u002B 1);\r\n } else if (remainingTextLength \u003C 3) {\r\n // If ther remaining text is too short for a line and there is no space in the current line,\r\n // the the word should be truncated ideally, but I am making up the requirements here.\r\n // So for now we will simply break so that there are at least 4 chars on the next line (e.g. \u0022Applica\u0022 -\u003E \u0022tion\u0022)\r\n\r\n return line.slice(0, line.length - (3 - remainingTextLength));\r\n }\r\n\r\n return line;\r\n};\r\n\r\nfunction wrapString(\r\n str,\r\n maxWidth,\r\n measure\r\n) {\r\n if (str.length \u003C 7) {\r\n return [str];\r\n }\r\n\r\n const standardCharWidth = measure(\u0027a\u0027);\r\n\r\n const numberOfStandardCharsInLine = Math.floor(maxWidth / standardCharWidth);\r\n\r\n const lines = [];\r\n let lineStartIndex = 0;\r\n let lineEndIndex = numberOfStandardCharsInLine;\r\n while (lineStartIndex \u003C str.length) {\r\n const line = getLine({\r\n str,\r\n lineStartIndex,\r\n lineEndIndex,\r\n standardCharWidth,\r\n maxWidth,\r\n measure,\r\n });\r\n\r\n lines.push(line);\r\n lineStartIndex = lineStartIndex \u002B line.length;\r\n lineEndIndex = lineStartIndex \u002B numberOfStandardCharsInLine;\r\n }\r\n\r\n return lines;\r\n};\r\n\r\nconst ws = new RegExp(\u0027[ \\\\t\\\\n]\u002B\u0027); // should include all whitespace characters as defined by Ardoq\r\n\r\n// or possibly change \u0022measure\u0022 to work thusly\r\n// measure(str, a, b) returns the length of the substring\r\n\r\nfunction wrapString_2(\r\n str,\r\n width,\r\n measure\r\n) {\r\n const tokens = str.split(ws, 100);\r\n const output = [];\r\n\r\n const wrapWord = (word) =\u003E {\r\n if (measure(word) \u003E width) {\r\n // str contains no line breaks but must be fit to width\r\n // this implementation can break anywhere, although in\r\n // practice it should not break in all sorts of clever\r\n // circumstances such as after a currency symbol\r\n\r\n let a = 0;\r\n\r\n while (a \u003C word.length) {\r\n let b = word.length;\r\n\r\n while (measure(word.slice(a, b)) \u003E width) {\r\n b = b - 1;\r\n }\r\n\r\n if (b === word.length) {\r\n break;\r\n }\r\n\r\n output.push(word.slice(a, b));\r\n a = b;\r\n }\r\n\r\n return word.slice(a);\r\n }\r\n\r\n return word;\r\n };\r\n\r\n for (let i = 0; i \u003C tokens.length;) {\r\n let line = wrapWord(tokens[i\u002B\u002B]);\r\n\r\n while (i \u003C tokens.length \u0026\u0026 measure(line.concat(\u0027 \u0027, tokens[i])) \u003C width) {\r\n line = line.concat(\u0027 \u0027, tokens[i\u002B\u002B]);\r\n }\r\n\r\n output.push(line);\r\n }\r\n\r\n return output;\r\n};\r\n\r\nvar testString = \u0022djf sjdbfsd sdkfjsdfsj dh shd djd d d dkskdfsdjkdj.sfks\u0022\r\n\r\nconst result = wrapString(testString, 500, approxMeasure)","IsDeferred":false},{"Name":"split and wrap worsds","Code":"var approxMeasure = (a) =\u003E\r\n a.length * 0.6 * 26;\r\n\r\nvar getLine = ({\r\n str,\r\n lineStartIndex,\r\n lineEndIndex,\r\n standardCharWidth,\r\n maxWidth,\r\n measure,\r\n}) =\u003E {\r\n const line = str.slice(lineStartIndex, lineEndIndex);\r\n const lineWidth = measure(line);\r\n\r\n // in the current code something seems to be adjusting the max width based on the label width, but it is not in scope of the string wrapping\r\n // so I floor the delta for now. which is impresice but avoids wrapping the string based on sub-pixel discrepancies\r\n const delta = Math.floor(maxWidth - lineWidth);\r\n\r\n if (lineEndIndex \u002B 1 \u003E str.length \u0026\u0026 delta \u003E= 0) {\r\n // string fits into max width completely\r\n return line;\r\n }\r\n\r\n const numberOfCharsDeviating = Math.floor(\r\n Math.abs(delta / standardCharWidth)\r\n );\r\n\r\n if (delta \u003C 0) {\r\n // do not exceed the maximum width, even if the dela is less than the standard char width\r\n return getLine({\r\n str,\r\n lineStartIndex,\r\n lineEndIndex: lineEndIndex - Math.max(numberOfCharsDeviating, 1),\r\n standardCharWidth,\r\n maxWidth,\r\n measure,\r\n });\r\n } else if (numberOfCharsDeviating \u003E 0) {\r\n // add chars only if the delta is greater than the standard char width\r\n return getLine({\r\n str,\r\n lineStartIndex,\r\n lineEndIndex: lineEndIndex \u002B numberOfCharsDeviating - 1,\r\n standardCharWidth,\r\n maxWidth,\r\n measure,\r\n });\r\n }\r\n\r\n // If there is a space within 3 chars at the end of the line, move the word to a next line\r\n const lastSpaceIndex = line.lastIndexOf(\u0027 \u0027);\r\n if (lastSpaceIndex !== -1 \u0026\u0026 line.length - lastSpaceIndex \u003C= 3) {\r\n return line.slice(0, lastSpaceIndex \u002B 1);\r\n }\r\n\r\n // If there is no space in the whole current line, break it regardless of the next 3 chars\r\n // but if there is a space within the current line:\r\n // - move the word to a next line if there is a space within the next 3 chars\r\n // - move the word to a next line the remaining chars are less than 4\r\n\r\n const remainingTextLength = str.length - lineEndIndex - 1;\r\n if (\r\n lastSpaceIndex !== -1 \u0026\u0026\r\n (remainingTextLength \u003C 3 ||\r\n str.slice(lineEndIndex, lineEndIndex \u002B 4).includes(\u0027 \u0027))\r\n ) {\r\n return line.slice(0, lastSpaceIndex \u002B 1);\r\n } else if (remainingTextLength \u003C 3) {\r\n // If ther remaining text is too short for a line and there is no space in the current line,\r\n // the the word should be truncated ideally, but I am making up the requirements here.\r\n // So for now we will simply break so that there are at least 4 chars on the next line (e.g. \u0022Applica\u0022 -\u003E \u0022tion\u0022)\r\n\r\n return line.slice(0, line.length - (3 - remainingTextLength));\r\n }\r\n\r\n return line;\r\n};\r\n\r\nfunction wrapString(\r\n str,\r\n maxWidth,\r\n measure\r\n) {\r\n if (str.length \u003C 7) {\r\n return [str];\r\n }\r\n\r\n const standardCharWidth = measure(\u0027a\u0027);\r\n\r\n const numberOfStandardCharsInLine = Math.floor(maxWidth / standardCharWidth);\r\n\r\n const lines = [];\r\n let lineStartIndex = 0;\r\n let lineEndIndex = numberOfStandardCharsInLine;\r\n while (lineStartIndex \u003C str.length) {\r\n const line = getLine({\r\n str,\r\n lineStartIndex,\r\n lineEndIndex,\r\n standardCharWidth,\r\n maxWidth,\r\n measure,\r\n });\r\n\r\n lines.push(line);\r\n lineStartIndex = lineStartIndex \u002B line.length;\r\n lineEndIndex = lineStartIndex \u002B numberOfStandardCharsInLine;\r\n }\r\n\r\n return lines;\r\n};\r\n\r\nconst ws = new RegExp(\u0027[ \\\\t\\\\n]\u002B\u0027); // should include all whitespace characters as defined by Ardoq\r\n\r\n// or possibly change \u0022measure\u0022 to work thusly\r\n// measure(str, a, b) returns the length of the substring\r\n\r\nfunction wrapString_2(\r\n str,\r\n width,\r\n measure\r\n) {\r\n const tokens = str.split(ws, 100);\r\n const output = [];\r\n\r\n const wrapWord = (word) =\u003E {\r\n if (measure(word) \u003E width) {\r\n // str contains no line breaks but must be fit to width\r\n // this implementation can break anywhere, although in\r\n // practice it should not break in all sorts of clever\r\n // circumstances such as after a currency symbol\r\n\r\n let a = 0;\r\n\r\n while (a \u003C word.length) {\r\n let b = word.length;\r\n\r\n while (measure(word.slice(a, b)) \u003E width) {\r\n b = b - 1;\r\n }\r\n\r\n if (b === word.length) {\r\n break;\r\n }\r\n\r\n output.push(word.slice(a, b));\r\n a = b;\r\n }\r\n\r\n return word.slice(a);\r\n }\r\n\r\n return word;\r\n };\r\n\r\n for (let i = 0; i \u003C tokens.length;) {\r\n let line = wrapWord(tokens[i\u002B\u002B]);\r\n\r\n while (i \u003C tokens.length \u0026\u0026 measure(line.concat(\u0027 \u0027, tokens[i])) \u003C width) {\r\n line = line.concat(\u0027 \u0027, tokens[i\u002B\u002B]);\r\n }\r\n\r\n output.push(line);\r\n }\r\n\r\n return output;\r\n};\r\n\r\nvar testString = \u0022djf sjdbfsd sdkfjsdfsj dh shd djd d d dkskdfsdjkdj.sfks\u0022\r\n\r\nconst result = wrapString_2(testString, 500, approxMeasure)","IsDeferred":false}]}