diff --git a/README.md b/README.md index e5e7a54..72a5616 100644 --- a/README.md +++ b/README.md @@ -157,7 +157,7 @@ To get the size of a given text * } * If detailedCalculationFlag is set to false the returned object wont have the detailObj prop. */ -size = sl.getOriSize(text, detailedCalculationFlag); +size = sl.getSize(text, detailedCalculationFlag); ``` To dispose the components diff --git a/dist/fusioncharts-smartlabel.js b/dist/fusioncharts-smartlabel.js index 4d712a2..15d5c3d 100644 --- a/dist/fusioncharts-smartlabel.js +++ b/dist/fusioncharts-smartlabel.js @@ -104,7 +104,7 @@ return /******/ (function(modules) { // webpackBootstrap /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lib */ \"./src/lib.js\");\n/* harmony import */ var _container_manager__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./container-manager */ \"./src/container-manager.js\");\n\n\nvar slLib = _lib__WEBPACK_IMPORTED_MODULE_0__[\"default\"].init(window),\n doc = slLib.win.document,\n M = slLib.win.Math,\n max = M.max,\n round = M.round,\n htmlSplCharSpace = {\n ' ': ' '\n},\n documentSupport = slLib.getDocumentSupport(),\n SVG_BBOX_CORRECTION = documentSupport.isWebKit ? 0 : 4.5;\n/*\n * @constrcutor\n * SmartLabelManager controls the lifetime of the execution space where the text's metrics will be calculated.\n * This takes a string for a given style and returns the height, width.\n * If a bound box is defined it wraps the text and returns the wrapped height and width.\n * It allows to append ellipsis at the end if the text is truncated.\n *\n * @param {String | HTMLElement} container - The id or the instance of the container where the intermediate dom\n * elements are to be attached. If not passed, it appends in div\n *\n * @param {Boolean} useEllipses - This decides if a ellipses to be appended if the text is truncated.\n * @param {Object} options - Control options\n * {\n * maxCacheLimit: No of letter to be cached. Default: 500.\n * }\n */\n\nfunction SmartLabelManager(container, useEllipses, options) {\n var wrapper,\n prop,\n max,\n isBrowserLess = false,\n canvas = window.document.createElement('canvas');\n options = options || {};\n options.maxCacheLimit = isFinite(max = options.maxCacheLimit) ? max : slLib.maxDefaultCacheLimit;\n\n if (typeof container === 'string') {\n container = doc.getElementById(container);\n }\n\n wrapper = slLib.createContainer(container);\n wrapper.innerHTML = slLib.testStrAvg;\n\n if (documentSupport.isHeadLess || !documentSupport.isIE && !wrapper.offsetHeight && !wrapper.offsetWidth) {\n isBrowserLess = true;\n }\n\n wrapper.innerHTML = '';\n\n for (prop in slLib.parentContainerStyle) {\n wrapper.style[prop] = slLib.parentContainerStyle[prop];\n }\n\n this.parentContainer = wrapper; // Get a context of canvas\n\n this.ctx = canvas && canvas.getContext && canvas.getContext('2d');\n this._containerManager = new _container_manager__WEBPACK_IMPORTED_MODULE_1__[\"default\"](wrapper, isBrowserLess, 10);\n this._showNoEllipses = !useEllipses;\n this._init = true;\n this.style = {};\n this.oldStyle = {};\n this.options = options;\n this.setStyle();\n}\n/*\n * getSmartText returns the text separated by
whenever a break is necessary. This is to recgonize one\n * generalized format independent of the implementation (canvas based solution, svg based solution). This method\n * converts the output of getSmartText().text to array of lines if the text is wrapped. It sets a named property\n * `lines` on the object passed as parameter.\n *\n * @param {Object} smartlabel - the object returned by getSmartText based on which line arr which to be formed.\n *\n * @return {Object} - The same object which was passed in the arguments. Also a named property `lines` is set.\n */\n\n\nSmartLabelManager.textToLines = function (smartlabel) {\n smartlabel = smartlabel || {};\n\n if (!smartlabel.text) {\n smartlabel.text = '';\n } else if (typeof smartlabel.text !== 'string') {\n smartlabel.text = smartlabel.text.toString();\n }\n\n smartlabel.lines = smartlabel.text.split(/\\n|/ig);\n return smartlabel;\n}; // Calculates space taken by a character with an approximation value which is calculated by repeating the\n// character by string length times.\n\n\nSmartLabelManager.prototype._calCharDimWithCache = function () {\n var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n var calculateDifference = arguments.length > 1 ? arguments[1] : undefined;\n var length = arguments.length > 2 ? arguments[2] : undefined;\n\n if (!this._init) {\n return false;\n }\n\n var size,\n tw,\n twi,\n cachedStyle,\n asymmetricDifference,\n maxAdvancedCacheLimit = this.options.maxCacheLimit,\n style = this.style || {},\n cache,\n advancedCacheKey,\n cacheName,\n cacheInitName;\n cache = this._advancedCache = this._advancedCache || (this._advancedCache = {});\n advancedCacheKey = this._advancedCacheKey || (this._advancedCacheKey = []);\n cacheName = text + style.fontSize + style.fontFamily + style.fontWeight + style.fontStyle;\n cacheInitName = text + 'init' + style.fontSize + style.fontFamily + style.fontWeight + style.fontStyle;\n\n if (!this.ctx && htmlSplCharSpace[text]) {\n text = htmlSplCharSpace[text];\n }\n\n if (!calculateDifference) {\n asymmetricDifference = 0;\n } else {\n if ((asymmetricDifference = cache[cacheInitName]) === undefined) {\n tw = this._getDimention(text.repeat ? text.repeat(length) : Array(length + 1).join(text)).width;\n twi = this._getDimention(text).width;\n asymmetricDifference = cache[cacheInitName] = (tw - length * twi) / (length + 1);\n advancedCacheKey.push(cacheInitName);\n\n if (advancedCacheKey.length > maxAdvancedCacheLimit) {\n delete cache[advancedCacheKey.shift()];\n }\n }\n }\n\n if (cachedStyle = cache[cacheName]) {\n return {\n width: cachedStyle.width,\n height: cachedStyle.height\n };\n }\n\n size = this._getDimention(text);\n size.width += asymmetricDifference;\n cache[cacheName] = {\n width: size.width,\n height: size.height\n };\n advancedCacheKey.push(cacheName);\n\n if (advancedCacheKey.length > maxAdvancedCacheLimit) {\n delete cache[advancedCacheKey.shift()];\n }\n\n return size;\n};\n\nSmartLabelManager.prototype._getDimention = function (text) {\n if (this.requireDiv || !this.ctx) {\n return slLib._getDimentionUsingDiv(text, this);\n } else {\n return slLib._getDimentionUsingCanvas(text, this);\n }\n}; // Provide function to calculate the height and width based on the environment and available support from dom.\n\n\nSmartLabelManager.prototype._getWidthFn = function () {\n var sl = this,\n contObj = sl._containerObj,\n svgText = contObj.svgText;\n\n if (svgText) {\n return function (str) {\n var bbox, width;\n svgText.textContent = str;\n bbox = svgText.getBBox();\n width = bbox.width - SVG_BBOX_CORRECTION;\n\n if (width < 1) {\n width = bbox.width;\n }\n\n return width;\n };\n } else {\n return function (str) {\n if (sl.requireDiv || !sl.ctx) {\n return slLib._getDimentionUsingDiv(str, sl).width;\n } else {\n return slLib._getDimentionUsingCanvas(str, sl).width;\n }\n };\n }\n};\n/**\n * Checks if two style object contains the same properties from the following list\n * - font-size\n * - font-family\n * - font-style\n * - font-weight\n * - font-variant\n */\n\n\nSmartLabelManager.prototype._isSameStyle = function () {\n var sl = this,\n oldStyle = sl.oldStyle || {},\n style = sl.style;\n\n if (style.fontSize !== oldStyle.fontSize || style.fontFamily !== oldStyle.fontFamily || style.fontStyle !== oldStyle.fontStyle || style.fontWeight !== oldStyle.fontWeight || style.fontVariant !== oldStyle.fontVariant) {\n return false;\n }\n\n return true;\n};\n/**\n * Sets font property of canvas context based on which the width of text is calculated.\n * \n * @param {any} style style configuration which affects the text size\n * {\n * fontSize / 'font-size' : MUST BE FOLLOWED BY PX (10px, 11px)\n * fontFamily / 'font-family'\n * fontWeight / 'font-weight'\n * fontStyle / 'font-style'\n * }\n */\n\n\nSmartLabelManager.prototype._setStyleOfCanvas = function () {\n if (this._isSameStyle()) {\n return;\n }\n\n var sl = this,\n style = sl.style,\n hashString,\n sCont,\n fontStyle = style.fontStyle,\n fontVariant = style.fontVariant,\n fontWeight = style.fontWeight,\n fontSize = style.fontSize,\n fontFamily = style.fontFamily;\n fontSize += fontSize.indexOf('px') === -1 ? 'px' : '';\n hashString = fontStyle + ' ' + fontVariant + ' ' + fontWeight + ' ' + fontSize + ' ' + fontFamily;\n sl.ctx.font = hashString;\n sCont = this._containerObj = this._containerManager.get(style);\n\n if (this._containerObj) {\n this._container = sCont.node;\n this._context = sCont.context;\n this._cache = sCont.charCache;\n this._lineHeight = sCont.lineHeight;\n this._styleNotSet = false;\n } else {\n this._styleNotSet = true;\n }\n\n sCont.ellipsesWidth = sl._calCharDimWithCache('...', false).width;\n sCont.dotWidth = sl._calCharDimWithCache('.', false).width;\n sCont.lineHeight = this._lineHeight = sCont.lineHeight || slLib._getCleanHeight(style.lineHeight);\n this.oldStyle = style;\n};\n\nSmartLabelManager.prototype._setStyleOfDiv = function () {\n var sCont,\n style = this.style;\n this._containerObj = sCont = this._containerManager.get(style);\n\n if (!sCont.node) {\n this._containerManager._makeDivNode(this._containerObj);\n }\n\n if (this._containerObj) {\n this._container = sCont.node;\n this._context = sCont.context;\n this._cache = sCont.charCache;\n this._lineHeight = sCont.lineHeight;\n this._styleNotSet = false;\n } else {\n this._styleNotSet = true;\n }\n};\n\nSmartLabelManager.prototype._updateStyle = function () {\n return this.requireDiv || !this.ctx ? this._setStyleOfDiv() : this._setStyleOfCanvas();\n};\n/*\n * Sets the style based on which the text's metrics to be calculated.\n *\n * @param {Object} style - The style object which affects the text size\n * {\n * fontSize / 'font-size' : MUST BE FOLLOWED BY PX (10px, 11px)\n * fontFamily / 'font-family'\n * fontWeight / 'font-weight'\n * fontStyle / 'font-style'\n * }\n *\n * @return {SmartLabelManager} - Current instance of SmartLabelManager\n */\n\n\nSmartLabelManager.prototype.setStyle = function (style) {\n this.style = slLib.parseStyle(style);\n slLib.setLineHeight(this.style);\n return this;\n};\n/*\n * Decides whether ellipses to be shown if the node is truncated\n *\n * @param {Boolean} useEllipses - decides if a ellipses to be appended if the text is truncated. Default: false\n *\n * @return {SmartLabelManager} - Current instance of SmartLabelManager\n */\n\n\nSmartLabelManager.prototype.useEllipsesOnOverflow = function (useEllipses) {\n if (!this._init) {\n return this;\n }\n\n this._showNoEllipses = !useEllipses;\n return this;\n};\n/*\n * Get wrapped or truncated text if a bound box is defined around it. The result text would be separated by
\n * if wrapped\n *\n * @param {String} text - the subject text\n * @param {Number} maxWidth - width in px of the the bound box\n * @param {Number} maxHeight - height in px of the the bound box\n * @param {Boolean} noWrap - whether the text to be wrapped. Default false.\n *\n * @return {Object} - The metrics of the text bounded by the box\n * {\n * height : height of the wrapped text\n * width : width of the wrapped text\n * isTruncated : whether the text is truncated\n * maxHeight : Maximum height given\n * maxWidth : Maximum width given\n * oriText : Original text sent\n * oriTextHeight : Original text height\n * oriTextWidth : Original text width\n * text : SMART TEXT\n * }\n */\n\n\nSmartLabelManager.prototype.getSmartText = function (text, maxWidth, maxHeight, noWrap) {\n if (!this._init) {\n return false;\n }\n\n if (text === undefined || text === null) {\n text = '';\n } else if (typeof text !== 'string') {\n text = text.toString();\n }\n\n var len,\n trimStr,\n tempArr,\n tmpText,\n maxWidthWithEll,\n toolText,\n oriWidth,\n oriHeight,\n newCharIndex,\n nearestChar,\n tempChar,\n getWidth,\n initialLeft,\n initialTop,\n getOriSizeImproveObj,\n spanArr,\n x,\n y,\n minWidth,\n elem,\n chr,\n elemRightMostPoint,\n elemLowestPoint,\n lastBR,\n removeFromIndex,\n removeFromIndexForEllipses,\n hasHTMLTag = false,\n maxStrWidth = 0,\n lastDash = -1,\n lastSpace = -1,\n lastIndexBroken = -1,\n strWidth = 0,\n strHeight = 0,\n oriTextArr = [],\n i = 0,\n ellipsesStr = this._showNoEllipses ? '' : '...',\n lineHeight,\n context,\n container,\n sCont,\n ellipsesWidth,\n dotWidth,\n canvas = this.ctx,\n characterArr = [],\n dashIndex = -1,\n spaceIndex = -1,\n lastLineBreak = -1,\n hasOnlyBrTag,\n dimentionObj,\n fastTrim = function fastTrim(str) {\n str = str.replace(/^\\s\\s*/, '');\n var ws = /\\s/,\n i = str.length;\n\n while (ws.test(str.charAt(i -= 1))) {\n /* jshint noempty:false */\n }\n\n return str.slice(0, i + 1);\n },\n smartLabel = {\n text: text,\n maxWidth: maxWidth,\n maxHeight: maxHeight,\n width: null,\n height: null,\n oriTextWidth: null,\n oriTextHeight: null,\n oriText: text,\n isTruncated: false\n };\n\n hasHTMLTag = slLib.xmlTagRegEx.test(text) || slLib.nbspRegex.test(text);\n hasOnlyBrTag = slLib._hasOnlyBRTag(text);\n this.requireDiv = hasHTMLTag && !hasOnlyBrTag;\n\n this._updateStyle();\n\n lineHeight = this._lineHeight;\n context = this._context;\n container = this._container;\n sCont = this._containerObj;\n ellipsesWidth = sCont.ellipsesWidth;\n dotWidth = sCont.dotWidth;\n toolText = text.replace(slLib.spanAdditionRegx, '$2');\n getWidth = this._getWidthFn(); // In some browsers, offsetheight of a single-line text is getting little (1 px) heigher value of the\n // lineheight. As a result, smartLabel is unable to return single-line text.\n // To fix this, increase the maxHeight a little amount. Hence maxHeight = lineHeight * 1.2\n\n /**\n * For canvas lineHeight is directly used. In some cases, lineHeight can be 0.x pixels greater than\n * maxHeight. Previously, div was used to calculate lineHeight and it used to return a rounded number.\n * \n * Adding a buffer of 1px, maxheight will be increased by a factor of 1.2 only when \n * 0 <= (lineHeight - maxHeight) <= 1\n */\n\n if (lineHeight - maxHeight <= 1 && lineHeight - maxHeight >= 0) {\n maxHeight *= 1.2;\n }\n\n if (canvas || container) {\n if (!documentSupport.isBrowserLess) {\n if (!hasHTMLTag) {\n // Due to support of <,> for xml we convert <, > to <,> respectively so to get the correct\n // width it is required to convert the same before calculation for the new improve version of the\n // get text width.\n tmpText = text = text.replace(slLib.ltgtRegex, function (match) {\n return match === '<' ? '<' : '>';\n });\n getOriSizeImproveObj = this.getOriSize(tmpText, true, {\n hasHTMLTag: hasHTMLTag,\n hasOnlyBrTag: hasOnlyBrTag,\n cleanText: true\n });\n smartLabel.oriTextWidth = oriWidth = getOriSizeImproveObj.width;\n smartLabel.oriTextHeight = oriHeight = getOriSizeImproveObj.height;\n } else if (hasOnlyBrTag) {\n text = text.replace(slLib.brRegex, '
');\n dimentionObj = slLib._getDimentionOfMultiLineText(text, this);\n smartLabel.oriTextWidth = oriWidth = dimentionObj.width;\n smartLabel.oriTextHeight = oriHeight = dimentionObj.height;\n } else {\n container.innerHTML = text;\n smartLabel.oriTextWidth = oriWidth = container.offsetWidth;\n smartLabel.oriTextHeight = oriHeight = container.offsetHeight;\n }\n\n if (oriHeight <= maxHeight && oriWidth <= maxWidth) {\n smartLabel.width = smartLabel.oriTextWidth = oriWidth;\n smartLabel.height = smartLabel.oriTextHeight = oriHeight;\n return smartLabel;\n }\n\n if (lineHeight > maxHeight) {\n smartLabel.text = '';\n smartLabel.width = smartLabel.oriTextWidth = 0;\n smartLabel.height = smartLabel.oriTextHeight = 0;\n return smartLabel;\n }\n } // Calculate width with ellipses\n\n\n text = fastTrim(text).replace(/(\\s+)/g, ' ');\n maxWidthWithEll = this._showNoEllipses ? maxWidth : maxWidth - ellipsesWidth; // Checks if any html tag is present. This if block is executed for all normal texts and \n // all texts containing only
tag.\n\n if (!hasHTMLTag || hasOnlyBrTag) {\n // Gets splitted array\n oriTextArr = slLib._getTextArray(text);\n len = oriTextArr.length;\n trimStr = '';\n tempArr = [];\n tempChar = oriTextArr[0];\n\n if (this._cache[tempChar]) {\n minWidth = this._cache[tempChar].width;\n } else {\n minWidth = getWidth(tempChar);\n this._cache[tempChar] = {\n width: minWidth\n };\n }\n\n if (maxWidthWithEll > minWidth && !hasOnlyBrTag) {\n tempArr = text.substr(0, slLib.getNearestBreakIndex(text, maxWidthWithEll, this)).split('');\n } else if (minWidth > maxWidth) {\n smartLabel.text = '';\n smartLabel.width = smartLabel.oriTextWidth = smartLabel.height = smartLabel.oriTextHeight = 0;\n return smartLabel;\n } else if (ellipsesStr) {\n maxWidthWithEll = maxWidth - 2 * dotWidth;\n\n if (maxWidthWithEll > minWidth) {\n ellipsesStr = '..';\n } else {\n maxWidthWithEll = maxWidth - dotWidth;\n\n if (maxWidthWithEll > minWidth) {\n ellipsesStr = '.';\n } else {\n maxWidthWithEll = 0;\n ellipsesStr = '';\n }\n }\n }\n\n i = tempArr.length;\n strWidth = getWidth(tempArr.join(''));\n strHeight = this._lineHeight;\n\n if (noWrap) {\n for (; i < len; i += 1) {\n tempChar = tempArr[i] = oriTextArr[i]; // In case of
, reset width to 0 and increase line height\n\n if (tempArr[i] === '
') {\n strHeight += this._lineHeight;\n lastIndexBroken = i;\n maxStrWidth = max(maxStrWidth, strWidth);\n strWidth = 0;\n trimStr = null;\n continue;\n }\n\n if (this._cache[tempChar]) {\n minWidth = this._cache[tempChar].width;\n } else {\n if (!getOriSizeImproveObj || !(minWidth = getOriSizeImproveObj.detailObj[tempChar])) {\n minWidth = getWidth(tempChar);\n }\n\n this._cache[tempChar] = {\n width: minWidth\n };\n }\n\n strWidth += minWidth;\n\n if (strWidth > maxWidthWithEll) {\n if (!trimStr) {\n trimStr = tempArr.slice(0, -1).join('');\n }\n\n if (strWidth > maxWidth) {\n smartLabel.text = fastTrim(trimStr) + ellipsesStr;\n smartLabel.tooltext = smartLabel.oriText;\n smartLabel.width = max(maxStrWidth, strWidth);\n smartLabel.height = strHeight;\n return smartLabel;\n }\n }\n }\n\n smartLabel.text = tempArr.join('');\n smartLabel.width = max(maxStrWidth, strWidth);\n smartLabel.height = strHeight;\n return smartLabel;\n } else {\n for (; i < len; i += 1) {\n tempChar = tempArr[i] = oriTextArr[i];\n\n if (tempChar === ' ' && !context) {\n tempChar = this.ctx ? ' ' : ' ';\n } // In case of
, reset width to 0 and increase line height\n\n\n if (tempArr[i] === '
') {\n maxStrWidth = max(maxStrWidth, strWidth);\n strHeight += this._lineHeight;\n\n if (strHeight <= maxHeight) {\n // If the totalHeight is less than allowed height, continue.\n lastIndexBroken = i;\n strWidth = 0;\n trimStr = null;\n continue;\n } else if (strHeight > maxHeight) {\n // Else return by truncating the text and attaching ellipses.\n trimStr = tempArr.slice(0, -1).join('');\n smartLabel.text = fastTrim(trimStr) + ellipsesStr;\n smartLabel.tooltext = toolText;\n smartLabel.width = maxStrWidth;\n smartLabel.height = strHeight - this._lineHeight;\n return smartLabel;\n }\n }\n\n if (this._cache[tempChar]) {\n minWidth = this._cache[tempChar].width;\n } else {\n if (!getOriSizeImproveObj || !(minWidth = getOriSizeImproveObj.detailObj[tempChar])) {\n minWidth = getWidth(tempChar);\n }\n\n this._cache[tempChar] = {\n width: minWidth\n };\n }\n\n strWidth += minWidth;\n\n if (strWidth > maxWidthWithEll) {\n if (!trimStr) {\n trimStr = tempArr.slice(0, -1).join('');\n }\n\n if (strWidth > maxWidth) {\n // do not perform any line break operation if next character is a break tag\n if (oriTextArr[i + 1] === '
') {\n continue;\n }\n /** @todo use regular expressions for better performance. */\n\n\n lastSpace = slLib._findLastIndex(oriTextArr.slice(0, tempArr.length), ' ');\n lastDash = slLib._findLastIndex(oriTextArr.slice(0, tempArr.length), '-');\n\n if (lastSpace > lastIndexBroken) {\n strWidth = getWidth(tempArr.slice(lastIndexBroken + 1, lastSpace).join(''));\n tempArr.splice(lastSpace, 1, '
');\n lastIndexBroken = lastSpace;\n newCharIndex = lastSpace + 1;\n } else if (lastDash > lastIndexBroken) {\n if (lastDash === tempArr.length - 1) {\n strWidth = getWidth(tempArr.slice(lastIndexBroken + 1, lastSpace).join(''));\n tempArr.splice(lastDash, 1, '
-');\n } else {\n strWidth = getWidth(tempArr.slice(lastIndexBroken + 1, lastSpace).join(''));\n tempArr.splice(lastDash, 1, '-
');\n }\n\n lastIndexBroken = lastDash;\n newCharIndex = lastDash + 1;\n } else {\n tempArr.splice(tempArr.length - 1, 1, '
' + oriTextArr[i]);\n lastLineBreak = tempArr.length - 2;\n strWidth = getWidth(tempArr.slice(lastIndexBroken + 1, lastLineBreak + 1).join(''));\n lastIndexBroken = lastLineBreak;\n newCharIndex = i;\n }\n\n strHeight += this._lineHeight;\n\n if (strHeight > maxHeight) {\n smartLabel.text = fastTrim(trimStr) + ellipsesStr;\n smartLabel.tooltext = smartLabel.oriText; // The max width among all the lines will be the width of the string.\n\n smartLabel.width = maxWidth;\n smartLabel.height = strHeight - this._lineHeight;\n return smartLabel;\n } else {\n maxStrWidth = max(maxStrWidth, strWidth);\n trimStr = null;\n\n if (!hasOnlyBrTag) {\n nearestChar = slLib.getNearestBreakIndex(text.substr(newCharIndex), maxWidthWithEll, this);\n strWidth = getWidth(text.substr(newCharIndex, nearestChar || 1));\n\n if (tempArr.length < newCharIndex + nearestChar) {\n tempArr = tempArr.concat(text.substr(tempArr.length, newCharIndex + nearestChar - tempArr.length).split(''));\n i = tempArr.length - 1;\n }\n } else {\n // take the width already taken in the new line.\n strWidth = slLib._getDimentionOfMultiLineText(tempArr.slice(lastIndexBroken + 1).join(''), this).width;\n }\n }\n }\n }\n }\n\n maxStrWidth = max(maxStrWidth, strWidth);\n smartLabel.text = tempArr.join('');\n smartLabel.width = maxStrWidth;\n smartLabel.height = strHeight;\n return smartLabel;\n }\n } else {\n toolText = text.replace(slLib.spanAdditionRegx, '$2');\n text = text.replace(slLib.spanAdditionRegx, slLib.spanAdditionReplacer);\n text = text.replace(/()/g, '$1');\n container.innerHTML = text;\n spanArr = container[documentSupport.childRetriverFn](documentSupport.childRetriverString);\n\n for (x = 0, y = spanArr.length; x < y; x += 1) {\n elem = spanArr[x]; //chech whether this span is temporary inserted span from it's class\n\n if (documentSupport.noClassTesting || slLib.classNameReg.test(elem.className)) {\n chr = elem.innerHTML;\n\n if (chr !== '') {\n if (chr === ' ') {\n spaceIndex = characterArr.length;\n } else if (chr === '-') {\n dashIndex = characterArr.length;\n }\n\n characterArr.push({\n spaceIdx: spaceIndex,\n dashIdx: dashIndex,\n elem: elem\n });\n oriTextArr.push(chr);\n }\n }\n }\n\n i = 0;\n len = characterArr.length; // if character array is not generated\n\n minWidth = len && characterArr[0].elem.offsetWidth;\n\n if (minWidth > maxWidth || !len) {\n smartLabel.text = '';\n smartLabel.width = smartLabel.oriTextWidth = smartLabel.height = smartLabel.oriTextHeight = 0;\n return smartLabel;\n } else if (minWidth > maxWidthWithEll && !this._showNoEllipses) {\n maxWidthWithEll = maxWidth - 2 * dotWidth;\n\n if (maxWidthWithEll > minWidth) {\n ellipsesStr = '..';\n } else {\n maxWidthWithEll = maxWidth - dotWidth;\n\n if (maxWidthWithEll > minWidth) {\n ellipsesStr = '.';\n } else {\n maxWidthWithEll = 0;\n ellipsesStr = '';\n }\n }\n }\n\n initialLeft = characterArr[0].elem.offsetLeft;\n initialTop = characterArr[0].elem.offsetTop;\n\n if (noWrap) {\n for (; i < len; i += 1) {\n elem = characterArr[i].elem;\n elemRightMostPoint = elem.offsetLeft - initialLeft + elem.offsetWidth;\n\n if (elemRightMostPoint > maxWidthWithEll) {\n if (!removeFromIndexForEllipses) {\n removeFromIndexForEllipses = i;\n }\n\n if (container.offsetWidth > maxWidth) {\n removeFromIndex = i;\n i = len;\n }\n }\n }\n } else {\n for (; i < len; i += 1) {\n elem = characterArr[i].elem;\n elemLowestPoint = elem.offsetHeight + (elem.offsetTop - initialTop);\n elemRightMostPoint = elem.offsetLeft - initialLeft + elem.offsetWidth;\n lastBR = null;\n\n if (elemRightMostPoint > maxWidthWithEll) {\n if (!removeFromIndexForEllipses) {\n removeFromIndexForEllipses = i;\n }\n\n if (elemRightMostPoint > maxWidth) {\n lastSpace = characterArr[i].spaceIdx;\n lastDash = characterArr[i].dashIdx;\n\n if (lastSpace > lastIndexBroken) {\n characterArr[lastSpace].elem.innerHTML = '
';\n lastIndexBroken = lastSpace;\n } else if (lastDash > lastIndexBroken) {\n if (lastDash === i) {\n // in case the overflowing character itself is the '-'\n characterArr[lastDash].elem.innerHTML = '
-';\n } else {\n characterArr[lastDash].elem.innerHTML = '-
';\n }\n\n lastIndexBroken = lastDash;\n } else {\n elem.parentNode.insertBefore(lastBR = doc.createElement('br'), elem);\n } //check whether this break made current element outside the area height\n\n\n if (elem.offsetHeight + elem.offsetTop > maxHeight) {\n //remove the lastly inserted line break\n if (lastBR) {\n lastBR.parentNode.removeChild(lastBR);\n } else if (lastIndexBroken === lastDash) {\n characterArr[lastDash].elem.innerHTML = '-';\n } else {\n characterArr[lastSpace].elem.innerHTML = ' ';\n }\n\n removeFromIndex = i; //break the looping condition\n\n i = len;\n } else {\n removeFromIndexForEllipses = null;\n }\n }\n } else {\n //check whether this break made current element outside the area height\n if (elemLowestPoint > maxHeight) {\n removeFromIndex = i;\n i = len;\n }\n }\n }\n }\n\n if (removeFromIndex < len) {\n //set the trancated property of the smartlabel\n smartLabel.isTruncated = true;\n /** @todo is this really needed? */\n\n removeFromIndexForEllipses = removeFromIndexForEllipses ? removeFromIndexForEllipses : removeFromIndex;\n\n for (i = len - 1; i >= removeFromIndexForEllipses; i -= 1) {\n elem = characterArr[i].elem; //chech whether this span is temporary inserted span from it's class\n\n elem.parentNode.removeChild(elem);\n }\n\n for (; i >= 0; i -= 1) {\n elem = characterArr[i].elem;\n\n if (slLib.classNameBrReg.test(elem.className)) {\n //chech whether this span is temporary inserted span from it's class\n elem.parentNode.removeChild(elem);\n } else {\n i = 0;\n }\n }\n } //get the smart text\n\n\n smartLabel.text = container.innerHTML.replace(slLib.spanRemovalRegx, '$1').replace(/\\&\\;/g, '&');\n\n if (smartLabel.isTruncated) {\n smartLabel.text += ellipsesStr;\n smartLabel.tooltext = toolText;\n }\n }\n\n smartLabel.height = container.offsetHeight;\n smartLabel.width = container.offsetWidth;\n return smartLabel;\n } else {\n smartLabel.error = new Error('Body Tag Missing!');\n return smartLabel;\n }\n};\n/*\n * Get the height and width of a text.\n *\n * @param {String} text - Text whose metrics to be measured\n * @param {Boolean} Optional detailedCalculationFlag - this flag if set it calculates per letter position\n * information and returns it. Ideally you dont need it unless you want to post process the\n * string. And its an EXPENSIVE OPERATION.\n *\n * @return {Object} - If detailedCalculationFlag is set to true the returned object would be\n * {\n * height: height of the text\n * width: width of the text\n * detailObj: detail calculation of letters in the format {lettername: width}\n * }\n * If detailedCalculationFlag is set to false the returned object wont have the detailObj prop.\n */\n\n\nSmartLabelManager.prototype.getOriSize = function () {\n var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n var detailedCalculationFlag = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n var config = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n if (!this._init) {\n return false;\n }\n\n if (text === undefined || text === null) {\n text = '';\n } else if (typeof text !== 'string') {\n text = text.toString();\n }\n\n var textArr,\n letter,\n lSize,\n i,\n l,\n cumulativeSize = 0,\n height = 0,\n container,\n indiSizeStore = {},\n hasHTMLTag = config.hasHTMLTag,\n hasOnlyBrTag = config.hasOnlyBrTag;\n\n if (typeof hasHTMLTag === 'undefined') {\n hasHTMLTag = slLib.xmlTagRegEx.test(text) || slLib.nbspRegex.test(text);\n }\n\n if (typeof hasOnlyBrTag === 'undefined') {\n hasOnlyBrTag = slLib._hasOnlyBRTag(text);\n }\n\n this.requireDiv = hasHTMLTag && !hasOnlyBrTag;\n\n if (!config.cleanText) {\n text = text.replace(slLib.ltgtRegex, function (match) {\n return match === '<' ? '<' : '>';\n });\n }\n\n this._updateStyle();\n\n container = this._container; // If text has br tag, return the width and height with proper calculations\n\n if (hasOnlyBrTag) {\n return slLib._getDimentionOfMultiLineText(text, this);\n } // When text is normal text\n\n\n if (!detailedCalculationFlag) {\n return this._calCharDimWithCache(text);\n } // text contains html tags other than br\n\n\n if (hasHTMLTag) {\n container.innerHTML = text;\n return {\n width: container.offsetWidth,\n height: container.offsetHeight\n };\n } // Calculate the width of every letter with an approximation\n\n\n textArr = text.split('');\n\n for (i = 0, l = textArr.length; i < l; i++) {\n letter = textArr[i];\n lSize = this._calCharDimWithCache(letter, false, textArr.length);\n height = max(height, lSize.height);\n cumulativeSize += lSize.width;\n indiSizeStore[letter] = lSize.width;\n }\n\n return {\n width: round(cumulativeSize),\n height: height,\n detailObj: indiSizeStore\n };\n};\n/*\n * Dispose the container and object allocated by the smartlabel\n */\n\n\nSmartLabelManager.prototype.dispose = function () {\n if (!this._init) {\n return this;\n }\n\n if (this._containerManager && this._containerManager.dispose) {\n this._containerManager.dispose();\n }\n\n delete this._container;\n delete this._context;\n delete this._cache;\n delete this._containerManager;\n delete this._containerObj;\n delete this.id;\n delete this.style;\n delete this.parentContainer;\n delete this._showNoEllipses;\n return this;\n};\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (SmartLabelManager);\n\n//# sourceURL=webpack://SmartLabel/./src/SmartlabelManager.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lib */ \"./src/lib.js\");\n/* harmony import */ var _container_manager__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./container-manager */ \"./src/container-manager.js\");\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n\n\nvar slLib = _lib__WEBPACK_IMPORTED_MODULE_0__[\"default\"].init(window),\n doc = slLib.win.document,\n M = slLib.win.Math,\n max = M.max,\n round = M.round,\n htmlSplCharSpace = {\n ' ': ' '\n},\n documentSupport = slLib.getDocumentSupport(),\n SVG_BBOX_CORRECTION = documentSupport.isWebKit ? 0 : 4.5;\n/*\n * @constrcutor\n * SmartLabelManager controls the lifetime of the execution space where the text's metrics will be calculated.\n * This takes a string for a given style and returns the height, width.\n * If a bound box is defined it wraps the text and returns the wrapped height and width.\n * It allows to append ellipsis at the end if the text is truncated.\n *\n * @param {String | HTMLElement} container - The id or the instance of the container where the intermediate dom\n * elements are to be attached. If not passed, it appends in div\n *\n * @param {Boolean} useEllipses - This decides if a ellipses to be appended if the text is truncated.\n * @param {Object} options - Control options\n * {\n * maxCacheLimit: No of letter to be cached. Default: 500.\n * }\n */\n\nfunction SmartLabelManager(container, useEllipses, options) {\n var wrapper,\n prop,\n max,\n isBrowserLess = false,\n canvas = window.document.createElement('canvas');\n options = options || {};\n options.maxCacheLimit = isFinite(max = options.maxCacheLimit) ? max : slLib.maxDefaultCacheLimit;\n\n if (typeof container === 'string') {\n container = doc.getElementById(container);\n }\n\n wrapper = slLib.createContainer(container);\n wrapper.innerHTML = slLib.testStrAvg;\n\n if (documentSupport.isHeadLess || !documentSupport.isIE && !wrapper.offsetHeight && !wrapper.offsetWidth) {\n isBrowserLess = true;\n }\n\n wrapper.innerHTML = '';\n\n for (prop in slLib.parentContainerStyle) {\n wrapper.style[prop] = slLib.parentContainerStyle[prop];\n }\n\n this.parentContainer = wrapper; // Get a context of canvas\n\n this.ctx = canvas && canvas.getContext && canvas.getContext('2d');\n this._containerManager = new _container_manager__WEBPACK_IMPORTED_MODULE_1__[\"default\"](wrapper, isBrowserLess, 10);\n this._showNoEllipses = !useEllipses;\n this._init = true;\n this.style = {};\n this.oldStyle = {};\n this.options = options;\n this.setStyle();\n}\n/*\n * getSmartText returns the text separated by
whenever a break is necessary. This is to recgonize one\n * generalized format independent of the implementation (canvas based solution, svg based solution). This method\n * converts the output of getSmartText().text to array of lines if the text is wrapped. It sets a named property\n * `lines` on the object passed as parameter.\n *\n * @param {Object} smartlabel - the object returned by getSmartText based on which line arr which to be formed.\n *\n * @return {Object} - The same object which was passed in the arguments. Also a named property `lines` is set.\n */\n\n\nSmartLabelManager.textToLines = function (smartlabel) {\n smartlabel = smartlabel || {};\n\n if (!smartlabel.text) {\n smartlabel.text = '';\n } else if (typeof smartlabel.text !== 'string') {\n smartlabel.text = smartlabel.text.toString();\n }\n\n smartlabel.lines = smartlabel.text.split(/\\n|/ig);\n return smartlabel;\n}; // Calculates space taken by a character with an approximation value which is calculated by repeating the\n// character by string length times.\n\n\nSmartLabelManager.prototype._calCharDimWithCache = function () {\n var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n var calculateDifference = arguments.length > 1 ? arguments[1] : undefined;\n var length = arguments.length > 2 ? arguments[2] : undefined;\n\n if (!this._init) {\n return false;\n }\n\n var size,\n tw,\n twi,\n cachedStyle,\n asymmetricDifference,\n maxAdvancedCacheLimit = this.options.maxCacheLimit,\n style = this.style || {},\n cache,\n advancedCacheKey,\n cacheName,\n cacheInitName;\n cache = this._advancedCache = this._advancedCache || (this._advancedCache = {});\n advancedCacheKey = this._advancedCacheKey || (this._advancedCacheKey = []);\n cacheName = text + style.fontSize + style.fontFamily + style.fontWeight + style.fontStyle;\n cacheInitName = text + 'init' + style.fontSize + style.fontFamily + style.fontWeight + style.fontStyle;\n\n if (!this.ctx && htmlSplCharSpace[text]) {\n text = htmlSplCharSpace[text];\n }\n\n if (!calculateDifference) {\n asymmetricDifference = 0;\n } else {\n if ((asymmetricDifference = cache[cacheInitName]) === undefined) {\n tw = this._getDimention(text.repeat ? text.repeat(length) : Array(length + 1).join(text)).width;\n twi = this._getDimention(text).width;\n asymmetricDifference = cache[cacheInitName] = (tw - length * twi) / (length + 1);\n advancedCacheKey.push(cacheInitName);\n\n if (advancedCacheKey.length > maxAdvancedCacheLimit) {\n delete cache[advancedCacheKey.shift()];\n }\n }\n }\n\n if (cachedStyle = cache[cacheName]) {\n return {\n width: cachedStyle.width,\n height: cachedStyle.height\n };\n }\n\n size = this._getDimention(text);\n size.width += asymmetricDifference;\n cache[cacheName] = {\n width: size.width,\n height: size.height\n };\n advancedCacheKey.push(cacheName);\n\n if (advancedCacheKey.length > maxAdvancedCacheLimit) {\n delete cache[advancedCacheKey.shift()];\n }\n\n return size;\n};\n\nSmartLabelManager.prototype._getDimention = function (text) {\n if (this.requireDiv || !this.ctx) {\n return slLib._getDimentionUsingDiv(text, this);\n } else {\n return slLib._getDimentionUsingCanvas(text, this);\n }\n}; // Provide function to calculate the height and width based on the environment and available support from dom.\n\n\nSmartLabelManager.prototype._getWidthFn = function () {\n var sl = this,\n contObj = sl._containerObj,\n svgText = contObj.svgText;\n\n if (svgText) {\n return function (str) {\n var bbox, width;\n svgText.textContent = str;\n bbox = svgText.getBBox();\n width = bbox.width - SVG_BBOX_CORRECTION;\n\n if (width < 1) {\n width = bbox.width;\n }\n\n return width;\n };\n } else {\n return function (str) {\n if (sl.requireDiv || !sl.ctx) {\n return slLib._getDimentionUsingDiv(str, sl).width;\n } else {\n return slLib._getDimentionUsingCanvas(str, sl).width;\n }\n };\n }\n};\n/**\n * Checks if two style object contains the same properties from the following list\n * - font-size\n * - font-family\n * - font-style\n * - font-weight\n * - font-variant\n */\n\n\nSmartLabelManager.prototype._isSameStyle = function () {\n var sl = this,\n oldStyle = sl.oldStyle || {},\n style = sl.style;\n\n if (style.fontSize !== oldStyle.fontSize || style.fontFamily !== oldStyle.fontFamily || style.fontStyle !== oldStyle.fontStyle || style.fontWeight !== oldStyle.fontWeight || style.fontVariant !== oldStyle.fontVariant) {\n return false;\n }\n\n return true;\n};\n/**\n * Sets font property of canvas context based on which the width of text is calculated.\n * \n * @param {any} style style configuration which affects the text size\n * {\n * fontSize / 'font-size' : MUST BE FOLLOWED BY PX (10px, 11px)\n * fontFamily / 'font-family'\n * fontWeight / 'font-weight'\n * fontStyle / 'font-style'\n * }\n */\n\n\nSmartLabelManager.prototype._setStyleOfCanvas = function () {\n if (this._isSameStyle()) {\n return;\n }\n\n var sl = this,\n style = sl.style,\n hashString,\n sCont,\n fontStyle = style.fontStyle,\n fontVariant = style.fontVariant,\n fontWeight = style.fontWeight,\n fontSize = style.fontSize,\n fontFamily = style.fontFamily;\n fontSize += fontSize.indexOf('px') === -1 ? 'px' : '';\n hashString = fontStyle + ' ' + fontVariant + ' ' + fontWeight + ' ' + fontSize + ' ' + fontFamily;\n sl.ctx.font = hashString;\n sCont = this._containerObj = this._containerManager.get(style);\n\n if (this._containerObj) {\n this._container = sCont.node;\n this._context = sCont.context;\n this._cache = sCont.charCache;\n this._lineHeight = sCont.lineHeight;\n this._styleNotSet = false;\n } else {\n this._styleNotSet = true;\n }\n\n sCont.ellipsesWidth = sl._calCharDimWithCache('...', false).width;\n sCont.dotWidth = sl._calCharDimWithCache('.', false).width;\n sCont.lineHeight = this._lineHeight = sCont.lineHeight || slLib._getCleanHeight(style.lineHeight);\n this.oldStyle = style;\n};\n\nSmartLabelManager.prototype._setStyleOfDiv = function () {\n var sCont,\n style = this.style;\n this._containerObj = sCont = this._containerManager.get(style);\n\n if (!sCont.node) {\n this._containerManager._makeDivNode(this._containerObj);\n }\n\n if (this._containerObj) {\n this._container = sCont.node;\n this._context = sCont.context;\n this._cache = sCont.charCache;\n this._lineHeight = sCont.lineHeight;\n this._styleNotSet = false;\n } else {\n this._styleNotSet = true;\n }\n};\n\nSmartLabelManager.prototype._updateStyle = function () {\n return this.requireDiv || !this.ctx ? this._setStyleOfDiv() : this._setStyleOfCanvas();\n};\n/*\n * Sets the style based on which the text's metrics to be calculated.\n *\n * @param {Object} style - The style object which affects the text size\n * {\n * fontSize / 'font-size' : MUST BE FOLLOWED BY PX (10px, 11px)\n * fontFamily / 'font-family'\n * fontWeight / 'font-weight'\n * fontStyle / 'font-style'\n * }\n *\n * @return {SmartLabelManager} - Current instance of SmartLabelManager\n */\n\n\nSmartLabelManager.prototype.setStyle = function (style) {\n this.style = slLib.parseStyle(style);\n slLib.setLineHeight(this.style);\n return this;\n};\n/*\n * Decides whether ellipses to be shown if the node is truncated\n *\n * @param {Boolean} useEllipses - decides if a ellipses to be appended if the text is truncated. Default: false\n *\n * @return {SmartLabelManager} - Current instance of SmartLabelManager\n */\n\n\nSmartLabelManager.prototype.useEllipsesOnOverflow = function (useEllipses) {\n if (!this._init) {\n return this;\n }\n\n this._showNoEllipses = !useEllipses;\n return this;\n};\n/*\n * Get wrapped or truncated text if a bound box is defined around it. The result text would be separated by
\n * if wrapped\n *\n * @param {String} text - the subject text\n * @param {Number} maxWidth - width in px of the the bound box\n * @param {Number} maxHeight - height in px of the the bound box\n * @param {Boolean} noWrap - whether the text to be wrapped. Default false.\n *\n * @return {Object} - The metrics of the text bounded by the box\n * {\n * height : height of the wrapped text\n * width : width of the wrapped text\n * isTruncated : whether the text is truncated\n * maxHeight : Maximum height given\n * maxWidth : Maximum width given\n * oriText : Original text sent\n * oriTextHeight : Original text height\n * oriTextWidth : Original text width\n * text : SMART TEXT\n * }\n */\n\n\nSmartLabelManager.prototype.getSmartText = function (text, maxWidth, maxHeight, noWrap) {\n if (!this._init) {\n return false;\n }\n\n if (text === undefined || text === null) {\n text = '';\n } else if (typeof text !== 'string') {\n text = text.toString();\n }\n\n var len,\n trimStr,\n tempArr,\n tmpText,\n maxWidthWithEll,\n toolText,\n oriWidth,\n oriHeight,\n newCharIndex,\n nearestChar,\n tempChar,\n getWidth,\n initialLeft,\n initialTop,\n getOriSizeImproveObj,\n spanArr,\n x,\n y,\n minWidth,\n elem,\n chr,\n elemRightMostPoint,\n elemLowestPoint,\n lastBR,\n removeFromIndex,\n removeFromIndexForEllipses,\n hasHTMLTag = false,\n maxStrWidth = 0,\n lastDash = -1,\n lastSpace = -1,\n lastIndexBroken = -1,\n strWidth = 0,\n strHeight = 0,\n oriTextArr = [],\n i = 0,\n ellipsesStr = this._showNoEllipses ? '' : '...',\n lineHeight,\n context,\n container,\n sCont,\n ellipsesWidth,\n dotWidth,\n canvas = this.ctx,\n characterArr = [],\n dashIndex = -1,\n spaceIndex = -1,\n lastLineBreak = -1,\n hasOnlyBrTag,\n dimentionObj,\n fastTrim = function fastTrim(str) {\n str = str.replace(/^\\s\\s*/, '');\n var ws = /\\s/,\n i = str.length;\n\n while (ws.test(str.charAt(i -= 1))) {\n /* jshint noempty:false */\n }\n\n return str.slice(0, i + 1);\n },\n smartLabel = {\n text: text,\n maxWidth: maxWidth,\n maxHeight: maxHeight,\n width: null,\n height: null,\n oriTextWidth: null,\n oriTextHeight: null,\n oriText: text,\n isTruncated: false\n };\n\n hasHTMLTag = slLib.xmlTagRegEx.test(text) || slLib.nbspRegex.test(text);\n hasOnlyBrTag = slLib._hasOnlyBRTag(text);\n this.requireDiv = hasHTMLTag && !hasOnlyBrTag;\n\n this._updateStyle();\n\n lineHeight = this._lineHeight;\n context = this._context;\n container = this._container;\n sCont = this._containerObj;\n ellipsesWidth = sCont.ellipsesWidth;\n dotWidth = sCont.dotWidth;\n toolText = text.replace(slLib.spanAdditionRegx, '$2');\n getWidth = this._getWidthFn(); // In some browsers, offsetheight of a single-line text is getting little (1 px) heigher value of the\n // lineheight. As a result, smartLabel is unable to return single-line text.\n // To fix this, increase the maxHeight a little amount. Hence maxHeight = lineHeight * 1.2\n\n /**\n * For canvas lineHeight is directly used. In some cases, lineHeight can be 0.x pixels greater than\n * maxHeight. Previously, div was used to calculate lineHeight and it used to return a rounded number.\n * \n * Adding a buffer of 1px, maxheight will be increased by a factor of 1.2 only when \n * 0 <= (lineHeight - maxHeight) <= 1\n */\n\n if (lineHeight - maxHeight <= 1 && lineHeight - maxHeight >= 0) {\n maxHeight *= 1.2;\n }\n\n if (canvas || container) {\n if (!documentSupport.isBrowserLess) {\n if (!hasHTMLTag) {\n // Due to support of <,> for xml we convert <, > to <,> respectively so to get the correct\n // width it is required to convert the same before calculation for the new improve version of the\n // get text width.\n tmpText = text = text.replace(slLib.ltgtRegex, function (match) {\n return match === '<' ? '<' : '>';\n });\n getOriSizeImproveObj = this.getSize(tmpText, true, {\n hasHTMLTag: hasHTMLTag,\n hasOnlyBrTag: hasOnlyBrTag,\n cleanText: true\n });\n smartLabel.oriTextWidth = oriWidth = getOriSizeImproveObj.width;\n smartLabel.oriTextHeight = oriHeight = getOriSizeImproveObj.height;\n } else if (hasOnlyBrTag) {\n text = text.replace(slLib.brRegex, '
');\n dimentionObj = slLib._getDimentionOfMultiLineText(text, this);\n smartLabel.oriTextWidth = oriWidth = dimentionObj.width;\n smartLabel.oriTextHeight = oriHeight = dimentionObj.height;\n } else {\n container.innerHTML = text;\n smartLabel.oriTextWidth = oriWidth = container.offsetWidth;\n smartLabel.oriTextHeight = oriHeight = container.offsetHeight;\n }\n\n if (oriHeight <= maxHeight && oriWidth <= maxWidth) {\n smartLabel.width = smartLabel.oriTextWidth = oriWidth;\n smartLabel.height = smartLabel.oriTextHeight = oriHeight;\n return smartLabel;\n }\n\n if (lineHeight > maxHeight) {\n smartLabel.text = '';\n smartLabel.width = smartLabel.oriTextWidth = 0;\n smartLabel.height = smartLabel.oriTextHeight = 0;\n return smartLabel;\n }\n } // Calculate width with ellipses\n\n\n text = fastTrim(text).replace(/(\\s+)/g, ' ');\n maxWidthWithEll = this._showNoEllipses ? maxWidth : maxWidth - ellipsesWidth; // Checks if any html tag is present. This if block is executed for all normal texts and \n // all texts containing only
tag.\n\n if (!hasHTMLTag || hasOnlyBrTag) {\n // Gets splitted array\n oriTextArr = slLib._getTextArray(text);\n len = oriTextArr.length;\n trimStr = '';\n tempArr = [];\n tempChar = oriTextArr[0];\n\n if (this._cache[tempChar]) {\n minWidth = this._cache[tempChar].width;\n } else {\n minWidth = getWidth(tempChar);\n this._cache[tempChar] = {\n width: minWidth\n };\n }\n\n if (maxWidthWithEll > minWidth && !hasOnlyBrTag) {\n tempArr = text.substr(0, slLib.getNearestBreakIndex(text, maxWidthWithEll, this)).split('');\n } else if (minWidth > maxWidth) {\n smartLabel.text = '';\n smartLabel.width = smartLabel.oriTextWidth = smartLabel.height = smartLabel.oriTextHeight = 0;\n return smartLabel;\n } else if (ellipsesStr) {\n maxWidthWithEll = maxWidth - 2 * dotWidth;\n\n if (maxWidthWithEll > minWidth) {\n ellipsesStr = '..';\n } else {\n maxWidthWithEll = maxWidth - dotWidth;\n\n if (maxWidthWithEll > minWidth) {\n ellipsesStr = '.';\n } else {\n maxWidthWithEll = 0;\n ellipsesStr = '';\n }\n }\n }\n\n i = tempArr.length;\n strWidth = getWidth(tempArr.join(''));\n strHeight = this._lineHeight;\n\n if (noWrap) {\n for (; i < len; i += 1) {\n tempChar = tempArr[i] = oriTextArr[i]; // In case of
, reset width to 0 and increase line height\n\n if (tempArr[i] === '
') {\n strHeight += this._lineHeight;\n lastIndexBroken = i;\n maxStrWidth = max(maxStrWidth, strWidth);\n strWidth = 0;\n trimStr = null;\n continue;\n }\n\n if (this._cache[tempChar]) {\n minWidth = this._cache[tempChar].width;\n } else {\n if (!getOriSizeImproveObj || !(minWidth = getOriSizeImproveObj.detailObj[tempChar])) {\n minWidth = getWidth(tempChar);\n }\n\n this._cache[tempChar] = {\n width: minWidth\n };\n }\n\n strWidth += minWidth;\n\n if (strWidth > maxWidthWithEll) {\n if (!trimStr) {\n trimStr = tempArr.slice(0, -1).join('');\n }\n\n if (strWidth > maxWidth) {\n smartLabel.text = fastTrim(trimStr) + ellipsesStr;\n smartLabel.tooltext = smartLabel.oriText;\n smartLabel.width = max(maxStrWidth, strWidth);\n smartLabel.height = strHeight;\n return smartLabel;\n }\n }\n }\n\n smartLabel.text = tempArr.join('');\n smartLabel.width = max(maxStrWidth, strWidth);\n smartLabel.height = strHeight;\n return smartLabel;\n } else {\n for (; i < len; i += 1) {\n tempChar = tempArr[i] = oriTextArr[i];\n\n if (tempChar === ' ' && !context) {\n tempChar = this.ctx ? ' ' : ' ';\n } // In case of
, reset width to 0 and increase line height\n\n\n if (tempArr[i] === '
') {\n maxStrWidth = max(maxStrWidth, strWidth);\n strHeight += this._lineHeight;\n\n if (strHeight <= maxHeight) {\n // If the totalHeight is less than allowed height, continue.\n lastIndexBroken = i;\n strWidth = 0;\n trimStr = null;\n continue;\n } else if (strHeight > maxHeight) {\n // Else return by truncating the text and attaching ellipses.\n trimStr = tempArr.slice(0, -1).join('');\n smartLabel.text = fastTrim(trimStr) + ellipsesStr;\n smartLabel.tooltext = toolText;\n smartLabel.width = maxStrWidth;\n smartLabel.height = strHeight - this._lineHeight;\n return smartLabel;\n }\n }\n\n if (this._cache[tempChar]) {\n minWidth = this._cache[tempChar].width;\n } else {\n if (!getOriSizeImproveObj || !(minWidth = getOriSizeImproveObj.detailObj[tempChar])) {\n minWidth = getWidth(tempChar);\n }\n\n this._cache[tempChar] = {\n width: minWidth\n };\n }\n\n strWidth += minWidth;\n\n if (strWidth > maxWidthWithEll) {\n if (!trimStr) {\n trimStr = tempArr.slice(0, -1).join('');\n }\n\n if (strWidth > maxWidth) {\n // do not perform any line break operation if next character is a break tag\n if (oriTextArr[i + 1] === '
') {\n continue;\n }\n /** @todo use regular expressions for better performance. */\n\n\n lastSpace = slLib._findLastIndex(oriTextArr.slice(0, tempArr.length), ' ');\n lastDash = slLib._findLastIndex(oriTextArr.slice(0, tempArr.length), '-');\n\n if (lastSpace > lastIndexBroken) {\n strWidth = getWidth(tempArr.slice(lastIndexBroken + 1, lastSpace).join(''));\n tempArr.splice(lastSpace, 1, '
');\n lastIndexBroken = lastSpace;\n newCharIndex = lastSpace + 1;\n } else if (lastDash > lastIndexBroken) {\n if (lastDash === tempArr.length - 1) {\n strWidth = getWidth(tempArr.slice(lastIndexBroken + 1, lastSpace).join(''));\n tempArr.splice(lastDash, 1, '
-');\n } else {\n strWidth = getWidth(tempArr.slice(lastIndexBroken + 1, lastSpace).join(''));\n tempArr.splice(lastDash, 1, '-
');\n }\n\n lastIndexBroken = lastDash;\n newCharIndex = lastDash + 1;\n } else {\n tempArr.splice(tempArr.length - 1, 1, '
' + oriTextArr[i]);\n lastLineBreak = tempArr.length - 2;\n strWidth = getWidth(tempArr.slice(lastIndexBroken + 1, lastLineBreak + 1).join(''));\n lastIndexBroken = lastLineBreak;\n newCharIndex = i;\n }\n\n strHeight += this._lineHeight;\n\n if (strHeight > maxHeight) {\n smartLabel.text = fastTrim(trimStr) + ellipsesStr;\n smartLabel.tooltext = smartLabel.oriText; // The max width among all the lines will be the width of the string.\n\n smartLabel.width = maxWidth;\n smartLabel.height = strHeight - this._lineHeight;\n return smartLabel;\n } else {\n maxStrWidth = max(maxStrWidth, strWidth);\n trimStr = null;\n\n if (!hasOnlyBrTag) {\n nearestChar = slLib.getNearestBreakIndex(text.substr(newCharIndex), maxWidthWithEll, this);\n strWidth = getWidth(text.substr(newCharIndex, nearestChar || 1));\n\n if (tempArr.length < newCharIndex + nearestChar) {\n tempArr = tempArr.concat(text.substr(tempArr.length, newCharIndex + nearestChar - tempArr.length).split(''));\n i = tempArr.length - 1;\n }\n } else {\n // take the width already taken in the new line.\n strWidth = slLib._getDimentionOfMultiLineText(tempArr.slice(lastIndexBroken + 1).join(''), this).width;\n }\n }\n }\n }\n }\n\n maxStrWidth = max(maxStrWidth, strWidth);\n smartLabel.text = tempArr.join('');\n smartLabel.width = maxStrWidth;\n smartLabel.height = strHeight;\n return smartLabel;\n }\n } else {\n toolText = text.replace(slLib.spanAdditionRegx, '$2');\n text = text.replace(slLib.spanAdditionRegx, slLib.spanAdditionReplacer);\n text = text.replace(/()/g, '$1');\n container.innerHTML = text;\n spanArr = container[documentSupport.childRetriverFn](documentSupport.childRetriverString);\n\n for (x = 0, y = spanArr.length; x < y; x += 1) {\n elem = spanArr[x]; //chech whether this span is temporary inserted span from it's class\n\n if (documentSupport.noClassTesting || slLib.classNameReg.test(elem.className)) {\n chr = elem.innerHTML;\n\n if (chr !== '') {\n if (chr === ' ') {\n spaceIndex = characterArr.length;\n } else if (chr === '-') {\n dashIndex = characterArr.length;\n }\n\n characterArr.push({\n spaceIdx: spaceIndex,\n dashIdx: dashIndex,\n elem: elem\n });\n oriTextArr.push(chr);\n }\n }\n }\n\n i = 0;\n len = characterArr.length; // if character array is not generated\n\n minWidth = len && characterArr[0].elem.offsetWidth;\n\n if (minWidth > maxWidth || !len) {\n smartLabel.text = '';\n smartLabel.width = smartLabel.oriTextWidth = smartLabel.height = smartLabel.oriTextHeight = 0;\n return smartLabel;\n } else if (minWidth > maxWidthWithEll && !this._showNoEllipses) {\n maxWidthWithEll = maxWidth - 2 * dotWidth;\n\n if (maxWidthWithEll > minWidth) {\n ellipsesStr = '..';\n } else {\n maxWidthWithEll = maxWidth - dotWidth;\n\n if (maxWidthWithEll > minWidth) {\n ellipsesStr = '.';\n } else {\n maxWidthWithEll = 0;\n ellipsesStr = '';\n }\n }\n }\n\n initialLeft = characterArr[0].elem.offsetLeft;\n initialTop = characterArr[0].elem.offsetTop;\n\n if (noWrap) {\n for (; i < len; i += 1) {\n elem = characterArr[i].elem;\n elemRightMostPoint = elem.offsetLeft - initialLeft + elem.offsetWidth;\n\n if (elemRightMostPoint > maxWidthWithEll) {\n if (!removeFromIndexForEllipses) {\n removeFromIndexForEllipses = i;\n }\n\n if (container.offsetWidth > maxWidth) {\n removeFromIndex = i;\n i = len;\n }\n }\n }\n } else {\n for (; i < len; i += 1) {\n elem = characterArr[i].elem;\n elemLowestPoint = elem.offsetHeight + (elem.offsetTop - initialTop);\n elemRightMostPoint = elem.offsetLeft - initialLeft + elem.offsetWidth;\n lastBR = null;\n\n if (elemRightMostPoint > maxWidthWithEll) {\n if (!removeFromIndexForEllipses) {\n removeFromIndexForEllipses = i;\n }\n\n if (elemRightMostPoint > maxWidth) {\n lastSpace = characterArr[i].spaceIdx;\n lastDash = characterArr[i].dashIdx;\n\n if (lastSpace > lastIndexBroken) {\n characterArr[lastSpace].elem.innerHTML = '
';\n lastIndexBroken = lastSpace;\n } else if (lastDash > lastIndexBroken) {\n if (lastDash === i) {\n // in case the overflowing character itself is the '-'\n characterArr[lastDash].elem.innerHTML = '
-';\n } else {\n characterArr[lastDash].elem.innerHTML = '-
';\n }\n\n lastIndexBroken = lastDash;\n } else {\n elem.parentNode.insertBefore(lastBR = doc.createElement('br'), elem);\n } //check whether this break made current element outside the area height\n\n\n if (elem.offsetHeight + elem.offsetTop > maxHeight) {\n //remove the lastly inserted line break\n if (lastBR) {\n lastBR.parentNode.removeChild(lastBR);\n } else if (lastIndexBroken === lastDash) {\n characterArr[lastDash].elem.innerHTML = '-';\n } else {\n characterArr[lastSpace].elem.innerHTML = ' ';\n }\n\n removeFromIndex = i; //break the looping condition\n\n i = len;\n } else {\n removeFromIndexForEllipses = null;\n }\n }\n } else {\n //check whether this break made current element outside the area height\n if (elemLowestPoint > maxHeight) {\n removeFromIndex = i;\n i = len;\n }\n }\n }\n }\n\n if (removeFromIndex < len) {\n //set the trancated property of the smartlabel\n smartLabel.isTruncated = true;\n /** @todo is this really needed? */\n\n removeFromIndexForEllipses = removeFromIndexForEllipses ? removeFromIndexForEllipses : removeFromIndex;\n\n for (i = len - 1; i >= removeFromIndexForEllipses; i -= 1) {\n elem = characterArr[i].elem; //chech whether this span is temporary inserted span from it's class\n\n elem.parentNode.removeChild(elem);\n }\n\n for (; i >= 0; i -= 1) {\n elem = characterArr[i].elem;\n\n if (slLib.classNameBrReg.test(elem.className)) {\n //chech whether this span is temporary inserted span from it's class\n elem.parentNode.removeChild(elem);\n } else {\n i = 0;\n }\n }\n } //get the smart text\n\n\n smartLabel.text = container.innerHTML.replace(slLib.spanRemovalRegx, '$1').replace(/\\&\\;/g, '&');\n\n if (smartLabel.isTruncated) {\n smartLabel.text += ellipsesStr;\n smartLabel.tooltext = toolText;\n }\n }\n\n smartLabel.height = container.offsetHeight;\n smartLabel.width = container.offsetWidth;\n return smartLabel;\n } else {\n smartLabel.error = new Error('Body Tag Missing!');\n return smartLabel;\n }\n};\n/*\n * Get the height and width of a text.\n *\n * @param {String} text - Text whose metrics to be measured\n * @param {Boolean} Optional detailedCalculationFlag - this flag if set it calculates per letter position\n * information and returns it. Ideally you dont need it unless you want to post process the\n * string. And its an EXPENSIVE OPERATION.\n *\n * @return {Object} - If detailedCalculationFlag is set to true the returned object would be\n * {\n * height: height of the text\n * width: width of the text\n * detailObj: detail calculation of letters in the format {lettername: width}\n * }\n * If detailedCalculationFlag is set to false the returned object wont have the detailObj prop.\n */\n\n\nSmartLabelManager.prototype.getSize = function () {\n var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n var detailedCalculationFlag = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n var config = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n if (!this._init) {\n return false;\n }\n\n if (text === undefined || text === null) {\n text = '';\n } else if (typeof text !== 'string') {\n text = text.toString();\n }\n\n var textArr,\n letter,\n lSize,\n i,\n l,\n cumulativeSize = 0,\n height = 0,\n container,\n indiSizeStore = {},\n hasHTMLTag = config.hasHTMLTag,\n hasOnlyBrTag = config.hasOnlyBrTag;\n\n if (typeof hasHTMLTag === 'undefined') {\n hasHTMLTag = slLib.xmlTagRegEx.test(text) || slLib.nbspRegex.test(text);\n }\n\n if (typeof hasOnlyBrTag === 'undefined') {\n hasOnlyBrTag = slLib._hasOnlyBRTag(text);\n }\n\n this.requireDiv = hasHTMLTag && !hasOnlyBrTag;\n\n if (!config.cleanText) {\n text = text.replace(slLib.ltgtRegex, function (match) {\n return match === '<' ? '<' : '>';\n });\n }\n\n this._updateStyle();\n\n container = this._container; // When text is normal text\n\n if (!detailedCalculationFlag) {\n return this._calCharDimWithCache(text);\n } else {\n // Calculate the width of every letter with an approximation\n textArr = text.split('');\n\n for (i = 0, l = textArr.length; i < l; i++) {\n letter = textArr[i];\n lSize = this._calCharDimWithCache(letter, false, textArr.length);\n height = max(height, lSize.height);\n cumulativeSize += lSize.width;\n indiSizeStore[letter] = lSize.width;\n }\n } // If text has br tag, return the width and height with proper calculations\n\n\n if (hasOnlyBrTag) {\n return _objectSpread({}, slLib._getDimentionOfMultiLineText(text, this), {\n detailObj: indiSizeStore\n });\n } // text contains html tags other than br\n\n\n if (hasHTMLTag) {\n container.innerHTML = text;\n return {\n width: container.offsetWidth,\n height: container.offsetHeight,\n detailObj: indiSizeStore\n };\n }\n\n return {\n width: round(cumulativeSize),\n height: height,\n detailObj: indiSizeStore\n };\n};\n/**\n * getOriSize API will eventually be deprecated and will be renamed to getSize API. For the next two versions,\n * both getOriSize and getSize API will be supported.\n */\n\n\nSmartLabelManager.prototype.getOriSize = function () {\n var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n var detailedCalculationFlag = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n var config = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n return this.getSize(text, detailedCalculationFlag, config);\n};\n/*\n * Dispose the container and object allocated by the smartlabel\n */\n\n\nSmartLabelManager.prototype.dispose = function () {\n if (!this._init) {\n return this;\n }\n\n if (this._containerManager && this._containerManager.dispose) {\n this._containerManager.dispose();\n }\n\n delete this._container;\n delete this._context;\n delete this._cache;\n delete this._containerManager;\n delete this._containerObj;\n delete this.id;\n delete this.style;\n delete this.parentContainer;\n delete this._showNoEllipses;\n return this;\n};\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (SmartLabelManager);\n\n//# sourceURL=webpack://SmartLabel/./src/SmartlabelManager.js?"); /***/ }), @@ -128,7 +128,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _lib /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\nvar lib = {\n init: function init(win) {\n var doc = win.document,\n nav = win.navigator,\n userAgent = nav.userAgent,\n DIV = 'DIV',\n ceil = Math.ceil,\n floor = Math.floor,\n clsNameSpace = 'fusioncharts-smartlabel-',\n containerClass = clsNameSpace + 'container',\n classNameWithTag = clsNameSpace + 'tag',\n classNameWithTagBR = clsNameSpace + 'br';\n lib = {\n win: win,\n containerClass: containerClass,\n classNameWithTag: classNameWithTag,\n classNameWithTagBR: classNameWithTagBR,\n maxDefaultCacheLimit: 1000,\n // The regex we get from new RegExp does not perform the work as intended\n // classNameReg: new RegExp('\\b' + classNameWithTag + '\\b'),\n // classNameBrReg: new RegExp('\\b' + classNameWithTagBR + '\\b'),\n classNameReg: /\\bfusioncharts-smartlabel-tag\\b/,\n classNameBrReg: /\\bfusioncharts-smartlabel-br\\b/,\n spanAdditionRegx: /(<[^<\\>]+?\\>)|(&(?:[a-z]+|#[0-9]+);|.)/ig,\n spanAdditionReplacer: '$1$2',\n spanRemovalRegx: new RegExp('\\\\]+?' + classNameWithTag + '[^\\\\>]{0,}\\\\>(.*?)\\\\<\\\\/span\\\\>', 'ig'),\n xmlTagRegEx: new RegExp('<[^>][^<]*[^>]+>', 'i'),\n brRegex: new RegExp('({br[ ]*})|()|()|()|()', 'g'),\n ltgtRegex: /<|>/g,\n nbspRegex: / /g,\n htmlSpecialEntityRegex: /&|"|<|>/g,\n brReplaceRegex: //ig,\n testStrAvg: 'WgI',\n // This style is applied over the parent smartlabel container. The container is kept hidden from the viewport\n parentContainerStyle: {\n position: 'absolute',\n top: '-9999em',\n whiteSpace: 'nowrap',\n padding: '0px',\n width: '1px',\n height: '1px',\n overflow: 'hidden'\n },\n // All the style which might affect the text metrics\n supportedStyle: {\n font: 'font',\n fontFamily: 'font-family',\n 'font-family': 'font-family',\n fontWeight: 'font-weight',\n 'font-weight': 'font-weight',\n fontSize: 'font-size',\n 'font-size': 'font-size',\n lineHeight: 'line-height',\n 'line-height': 'line-height',\n fontStyle: 'font-style',\n 'font-style': 'font-style'\n },\n // Get the support list for html the document where the text calcution is to be done.\n getDocumentSupport: function getDocumentSupport() {\n var childRetriverFn, childRetriverString, noClassTesting;\n\n if (doc.getElementsByClassName) {\n childRetriverFn = 'getElementsByClassName';\n childRetriverString = classNameWithTag;\n noClassTesting = true;\n } else {\n childRetriverFn = 'getElementsByTagName';\n childRetriverString = 'span';\n noClassTesting = false;\n }\n\n return {\n isIE: /msie/i.test(userAgent) && !win.opera,\n hasSVG: Boolean(win.SVGAngle || doc.implementation.hasFeature('http://www.w3.org/TR/SVG11/feature#BasicStructure', '1.1')),\n isHeadLess: new RegExp(' HtmlUnit').test(userAgent),\n isWebKit: new RegExp(' AppleWebKit/').test(userAgent),\n childRetriverFn: childRetriverFn,\n childRetriverString: childRetriverString,\n noClassTesting: noClassTesting\n };\n },\n\n /*\n * Create a html div element and attach it with a parent. All the subsequent operations are performed\n * by upding this dom tree only.\n *\n * @param {HTMLElement} - The html element where the newly created div is to be attached. If not passed,\n * the new div is appended on the body.\n */\n createContainer: function createContainer(containerParent) {\n var body, container;\n\n if (containerParent && (containerParent.offsetWidth || containerParent.offsetHeight)) {\n if (containerParent.appendChild) {\n containerParent.appendChild(container = doc.createElement(DIV));\n container.className = containerClass;\n container.setAttribute('aria-hidden', 'true');\n container.setAttribute('role', 'presentation');\n return container;\n }\n } else {\n body = doc.getElementsByTagName('body')[0];\n\n if (body && body.appendChild) {\n container = doc.createElement(DIV);\n container.className = containerClass;\n container.setAttribute('aria-hidden', 'true');\n container.setAttribute('role', 'presentation');\n body.appendChild(container);\n return container;\n }\n }\n },\n // Finds a approximate position where the text is to be broken\n getNearestBreakIndex: function getNearestBreakIndex(text, maxWidth, sl) {\n if (!text || !text.length) {\n return 0;\n }\n\n var difference,\n getWidth = sl._getWidthFn(),\n charLen = 0,\n increment = 0,\n oriWidth = getWidth(text),\n avgWidth = oriWidth / text.length;\n\n difference = maxWidth;\n charLen = ceil(maxWidth / avgWidth);\n\n if (oriWidth < maxWidth) {\n return text.length - 1;\n }\n\n if (charLen > text.length) {\n difference = maxWidth - oriWidth;\n charLen = text.length;\n }\n\n while (difference > 0) {\n difference = maxWidth - getWidth(text.substr(0, charLen));\n increment = floor(difference / avgWidth);\n\n if (increment) {\n charLen += increment;\n } else {\n return charLen;\n }\n }\n\n while (difference < 0) {\n difference = maxWidth - getWidth(text.substr(0, charLen));\n increment = floor(difference / avgWidth);\n\n if (increment) {\n charLen += increment;\n } else {\n return charLen;\n }\n }\n\n return charLen;\n },\n\n /**\n * parses the style information\n */\n parseStyle: function parseStyle() {\n var style = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var parsedStyle = {};\n parsedStyle.fontSize = (style.fontSize || style['font-size'] || '12px') + '';\n parsedStyle.fontVariant = style.fontVariant || style['font-variant'] || 'normal';\n parsedStyle.fontWeight = style.fontWeight || style['font-weight'] || 'normal';\n parsedStyle.fontStyle = style.fontStyle || style['font-style'] || 'normal';\n parsedStyle.fontFamily = style.fontFamily || style['font-family'] || 'Verdana,sans';\n return parsedStyle;\n },\n\n /*\n * Determine lineheight of a text for a given style. It adds propery lineHeight to the style passed\n *\n * @param {Object} - The style based on which the text's metric needs to be calculated. The calculation happens\n * based on fontSize property, if its not present a default font size is assumed.\n *\n * @return {Object} - The style that was passed with lineHeight as a named propery set on the object.\n */\n setLineHeight: function setLineHeight(styleObj) {\n var fSize = styleObj.fontSize;\n styleObj.lineHeight = styleObj.lineHeight || styleObj['line-height'] || parseInt(fSize, 10) * 1.2 + 'px';\n return styleObj;\n },\n\n /**\n * Returns the clean height by removing 'px' if present.\n */\n _getCleanHeight: function _getCleanHeight(height) {\n // Remove 'px' from height and convert it to number\n height = height.replace(/px/g, '');\n return Number(height);\n },\n\n /**\n * Div is used for calculation of text dimention in all non-canvas browsers. It sets the text as\n * innerHTML of the div and uses it's offsetWidth and offsetHeight as width and height respectively\n *\n * @param {string} text - text, whose measurements are to be calculated\n * \n * @returns {Object} - dimension of text\n */\n _getDimentionUsingDiv: function _getDimentionUsingDiv() {\n var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n var sl = arguments.length > 1 ? arguments[1] : undefined;\n var container = sl._container; // In case text is an array, convert it to string.\n\n if (text instanceof Array) {\n text = text.join('');\n }\n\n container.innerHTML = text;\n return {\n width: container.offsetWidth,\n height: container.offsetHeight\n };\n },\n\n /**\n * Returns the height and width of a text using the canvas.measureText API.\n * Used for calculating width in browsers supporting html canvas.\n * In case canvas is not present,
is used for calculation as a fallback solution\n * \n * @param {any} text - text. Can be array or string.\n * \n * @return {Object} - width and height.\n */\n _getDimentionUsingCanvas: function _getDimentionUsingCanvas() {\n var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n var sl = arguments.length > 1 ? arguments[1] : undefined;\n\n var ctx = sl.ctx,\n style = sl.style,\n height = lib._getCleanHeight(style.lineHeight); // In case text is string, remove
from it.\n\n\n if (!(text instanceof Array)) {\n text = text.replace(/
/g, '');\n } else {\n // Else if it an array, convert it to string and remove
\n text = text.join('');\n text = text.replace(/
/g, '');\n }\n\n return {\n width: ctx.measureText(text).width,\n height: height\n };\n },\n\n /**\n * Checks if text contains any
tag. If yes, it returns all the indexes of it.\n * Else, it returns undefined.\n * \n * @param {string} input - text which is to be examined for
tag\n * \n * @returns {boolean} - whether text contains only
tag\n */\n _hasOnlyBRTag: function _hasOnlyBRTag() {\n var input = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n return !lib.xmlTagRegEx.test(input) && lib.brRegex.test(input);\n },\n\n /**\n * For a text containing
it returns the height and width of the text\n * \n */\n _getDimentionOfMultiLineText: function _getDimentionOfMultiLineText() {\n var rawText = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n var sl = arguments.length > 1 ? arguments[1] : undefined;\n\n var i,\n len,\n text = rawText.replace(lib.brRegex, '
'),\n textAr = lib._getTextArray(text),\n width = 0,\n maxWidth = 0,\n getWidth = sl._getWidthFn(),\n height = lib._getCleanHeight(sl.style.lineHeight),\n textHeight = height,\n textWidth,\n indiSizeStore = {};\n\n for (i = 0, len = textAr.length; i < len; i++) {\n if (textAr[i] === '
') {\n // In case of
, reset width to 0, since it will be new line now.\n // Also, increase the line height.\n maxWidth = Math.max(maxWidth, width);\n width = 0;\n textHeight += height;\n } else {\n // Else, calculate the width of the line.\n textWidth = getWidth(textAr[i]);\n width += textWidth;\n indiSizeStore[textAr[i]] = textWidth;\n }\n }\n\n maxWidth = Math.max(maxWidth, width);\n return {\n height: textHeight,\n width: maxWidth,\n detailObj: indiSizeStore\n };\n },\n\n /**\n * Splits text into array and returns. Special functionality is, it treats
as a single character\n */\n _getTextArray: function _getTextArray() {\n var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n var i,\n j,\n len,\n tempLen,\n brText,\n tempText,\n finaltextAr = []; // Split using
\n\n brText = text.split('
');\n len = brText.length;\n\n for (i = 0; i < len; i++) {\n tempText = brText[i].split('');\n tempLen = tempText.length; // for each array retrieved by spliting using
push elements to finalArray.\n\n for (j = 0; j < tempLen; j++) {\n finaltextAr.push(tempText[j]);\n } // Check if tempText is not the last text. IF true, add
to the final Array.\n\n\n if (i !== len - 1) {\n finaltextAr.push('
');\n }\n }\n\n return finaltextAr;\n },\n\n /**\n * Returns the last occurance of item in a array\n */\n _findLastIndex: function _findLastIndex() {\n var array = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n var item = arguments.length > 1 ? arguments[1] : undefined;\n var i,\n len = array.length;\n\n for (i = len - 1; i >= 0; i--) {\n if (array[i] === item) {\n return i;\n }\n }\n\n return -1;\n }\n };\n return lib;\n }\n};\n/* harmony default export */ __webpack_exports__[\"default\"] = (lib);\n\n//# sourceURL=webpack://SmartLabel/./src/lib.js?"); +eval("__webpack_require__.r(__webpack_exports__);\nvar lib = {\n init: function init(win) {\n var doc = win.document,\n nav = win.navigator,\n userAgent = nav.userAgent,\n DIV = 'DIV',\n ceil = Math.ceil,\n floor = Math.floor,\n clsNameSpace = 'fusioncharts-smartlabel-',\n containerClass = clsNameSpace + 'container',\n classNameWithTag = clsNameSpace + 'tag',\n classNameWithTagBR = clsNameSpace + 'br';\n lib = {\n win: win,\n containerClass: containerClass,\n classNameWithTag: classNameWithTag,\n classNameWithTagBR: classNameWithTagBR,\n maxDefaultCacheLimit: 1000,\n // The regex we get from new RegExp does not perform the work as intended\n // classNameReg: new RegExp('\\b' + classNameWithTag + '\\b'),\n // classNameBrReg: new RegExp('\\b' + classNameWithTagBR + '\\b'),\n classNameReg: /\\bfusioncharts-smartlabel-tag\\b/,\n classNameBrReg: /\\bfusioncharts-smartlabel-br\\b/,\n spanAdditionRegx: /(<[^<\\>]+?\\>)|(&(?:[a-z]+|#[0-9]+);|.)/ig,\n spanAdditionReplacer: '$1$2',\n spanRemovalRegx: new RegExp('\\\\]+?' + classNameWithTag + '[^\\\\>]{0,}\\\\>(.*?)\\\\<\\\\/span\\\\>', 'ig'),\n xmlTagRegEx: new RegExp('<[^>][^<]*[^>]+>', 'i'),\n brRegex: new RegExp('({br[ ]*})|()|()|()|()', 'g'),\n ltgtRegex: /<|>/g,\n nbspRegex: / | | /g,\n htmlSpecialEntityRegex: /&|"|<|>/g,\n brReplaceRegex: //ig,\n testStrAvg: 'WgI',\n // This style is applied over the parent smartlabel container. The container is kept hidden from the viewport\n parentContainerStyle: {\n position: 'absolute',\n top: '-9999em',\n whiteSpace: 'nowrap',\n padding: '0px',\n width: '1px',\n height: '1px',\n overflow: 'hidden'\n },\n // All the style which might affect the text metrics\n supportedStyle: {\n font: 'font',\n fontFamily: 'font-family',\n 'font-family': 'font-family',\n fontWeight: 'font-weight',\n 'font-weight': 'font-weight',\n fontSize: 'font-size',\n 'font-size': 'font-size',\n lineHeight: 'line-height',\n 'line-height': 'line-height',\n fontStyle: 'font-style',\n 'font-style': 'font-style'\n },\n // Get the support list for html the document where the text calcution is to be done.\n getDocumentSupport: function getDocumentSupport() {\n var childRetriverFn, childRetriverString, noClassTesting;\n\n if (doc.getElementsByClassName) {\n childRetriverFn = 'getElementsByClassName';\n childRetriverString = classNameWithTag;\n noClassTesting = true;\n } else {\n childRetriverFn = 'getElementsByTagName';\n childRetriverString = 'span';\n noClassTesting = false;\n }\n\n return {\n isIE: /msie/i.test(userAgent) && !win.opera,\n hasSVG: Boolean(win.SVGAngle || doc.implementation.hasFeature('http://www.w3.org/TR/SVG11/feature#BasicStructure', '1.1')),\n isHeadLess: new RegExp(' HtmlUnit').test(userAgent),\n isWebKit: new RegExp(' AppleWebKit/').test(userAgent),\n childRetriverFn: childRetriverFn,\n childRetriverString: childRetriverString,\n noClassTesting: noClassTesting\n };\n },\n\n /*\n * Create a html div element and attach it with a parent. All the subsequent operations are performed\n * by upding this dom tree only.\n *\n * @param {HTMLElement} - The html element where the newly created div is to be attached. If not passed,\n * the new div is appended on the body.\n */\n createContainer: function createContainer(containerParent) {\n var body, container;\n\n if (containerParent && (containerParent.offsetWidth || containerParent.offsetHeight)) {\n if (containerParent.appendChild) {\n containerParent.appendChild(container = doc.createElement(DIV));\n container.className = containerClass;\n container.setAttribute('aria-hidden', 'true');\n container.setAttribute('role', 'presentation');\n return container;\n }\n } else {\n body = doc.getElementsByTagName('body')[0];\n\n if (body && body.appendChild) {\n container = doc.createElement(DIV);\n container.className = containerClass;\n container.setAttribute('aria-hidden', 'true');\n container.setAttribute('role', 'presentation');\n body.appendChild(container);\n return container;\n }\n }\n },\n // Finds a approximate position where the text is to be broken\n getNearestBreakIndex: function getNearestBreakIndex(text, maxWidth, sl) {\n if (!text || !text.length) {\n return 0;\n }\n\n var difference,\n getWidth = sl._getWidthFn(),\n charLen = 0,\n increment = 0,\n oriWidth = getWidth(text),\n avgWidth = oriWidth / text.length;\n\n difference = maxWidth;\n charLen = ceil(maxWidth / avgWidth);\n\n if (oriWidth < maxWidth) {\n return text.length - 1;\n }\n\n if (charLen > text.length) {\n difference = maxWidth - oriWidth;\n charLen = text.length;\n }\n\n while (difference > 0) {\n difference = maxWidth - getWidth(text.substr(0, charLen));\n increment = floor(difference / avgWidth);\n\n if (increment) {\n charLen += increment;\n } else {\n return charLen;\n }\n }\n\n while (difference < 0) {\n difference = maxWidth - getWidth(text.substr(0, charLen));\n increment = floor(difference / avgWidth);\n\n if (increment) {\n charLen += increment;\n } else {\n return charLen;\n }\n }\n\n return charLen;\n },\n\n /**\n * parses the style information\n */\n parseStyle: function parseStyle() {\n var style = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var parsedStyle = {};\n parsedStyle.fontSize = (style.fontSize || style['font-size'] || '12px') + '';\n parsedStyle.fontVariant = style.fontVariant || style['font-variant'] || 'normal';\n parsedStyle.fontWeight = style.fontWeight || style['font-weight'] || 'normal';\n parsedStyle.fontStyle = style.fontStyle || style['font-style'] || 'normal';\n parsedStyle.fontFamily = style.fontFamily || style['font-family'] || 'Verdana,sans';\n return parsedStyle;\n },\n\n /*\n * Determine lineheight of a text for a given style. It adds propery lineHeight to the style passed\n *\n * @param {Object} - The style based on which the text's metric needs to be calculated. The calculation happens\n * based on fontSize property, if its not present a default font size is assumed.\n *\n * @return {Object} - The style that was passed with lineHeight as a named propery set on the object.\n */\n setLineHeight: function setLineHeight(styleObj) {\n var fSize = styleObj.fontSize;\n styleObj.lineHeight = styleObj.lineHeight || styleObj['line-height'] || parseInt(fSize, 10) * 1.2 + 'px';\n return styleObj;\n },\n\n /**\n * Returns the clean height by removing 'px' if present.\n */\n _getCleanHeight: function _getCleanHeight(height) {\n // Remove 'px' from height and convert it to number\n height = height.replace(/px/g, '');\n return Number(height);\n },\n\n /**\n * Div is used for calculation of text dimention in all non-canvas browsers. It sets the text as\n * innerHTML of the div and uses it's offsetWidth and offsetHeight as width and height respectively\n *\n * @param {string} text - text, whose measurements are to be calculated\n * \n * @returns {Object} - dimension of text\n */\n _getDimentionUsingDiv: function _getDimentionUsingDiv() {\n var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n var sl = arguments.length > 1 ? arguments[1] : undefined;\n var container = sl._container; // In case text is an array, convert it to string.\n\n if (text instanceof Array) {\n text = text.join('');\n }\n\n container.innerHTML = text;\n return {\n width: container.offsetWidth,\n height: container.offsetHeight\n };\n },\n\n /**\n * Returns the height and width of a text using the canvas.measureText API.\n * Used for calculating width in browsers supporting html canvas.\n * In case canvas is not present,
is used for calculation as a fallback solution\n * \n * @param {any} text - text. Can be array or string.\n * \n * @return {Object} - width and height.\n */\n _getDimentionUsingCanvas: function _getDimentionUsingCanvas() {\n var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n var sl = arguments.length > 1 ? arguments[1] : undefined;\n\n var ctx = sl.ctx,\n style = sl.style,\n height = lib._getCleanHeight(style.lineHeight); // In case text is string, remove
from it.\n\n\n if (!(text instanceof Array)) {\n text = text.replace(/
/g, '');\n } else {\n // Else if it an array, convert it to string and remove
\n text = text.join('');\n text = text.replace(/
/g, '');\n }\n\n return {\n width: ctx.measureText(text).width,\n height: height\n };\n },\n\n /**\n * Checks if text contains any
tag. If yes, it returns all the indexes of it.\n * Else, it returns undefined.\n * \n * @param {string} input - text which is to be examined for
tag\n * \n * @returns {boolean} - whether text contains only
tag\n */\n _hasOnlyBRTag: function _hasOnlyBRTag() {\n var input = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n return !lib.xmlTagRegEx.test(input) && lib.brRegex.test(input);\n },\n\n /**\n * For a text containing
it returns the height and width of the text\n * \n */\n _getDimentionOfMultiLineText: function _getDimentionOfMultiLineText() {\n var rawText = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n var sl = arguments.length > 1 ? arguments[1] : undefined;\n\n var i,\n len,\n text = rawText.replace(lib.brRegex, '
'),\n textAr = lib._getTextArray(text),\n width = 0,\n maxWidth = 0,\n getWidth = sl._getWidthFn(),\n height = lib._getCleanHeight(sl.style.lineHeight),\n textHeight = height,\n textWidth,\n indiSizeStore = {};\n\n for (i = 0, len = textAr.length; i < len; i++) {\n if (textAr[i] === '
') {\n // In case of
, reset width to 0, since it will be new line now.\n // Also, increase the line height.\n maxWidth = Math.max(maxWidth, width);\n width = 0;\n textHeight += height;\n } else {\n // Else, calculate the width of the line.\n textWidth = getWidth(textAr[i]);\n width += textWidth;\n indiSizeStore[textAr[i]] = textWidth;\n }\n }\n\n maxWidth = Math.max(maxWidth, width);\n return {\n height: textHeight,\n width: maxWidth,\n detailObj: indiSizeStore\n };\n },\n\n /**\n * Splits text into array and returns. Special functionality is, it treats
as a single character\n */\n _getTextArray: function _getTextArray() {\n var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n var i,\n j,\n len,\n tempLen,\n brText,\n tempText,\n finaltextAr = []; // Split using
\n\n brText = text.split('
');\n len = brText.length;\n\n for (i = 0; i < len; i++) {\n tempText = brText[i].split('');\n tempLen = tempText.length; // for each array retrieved by spliting using
push elements to finalArray.\n\n for (j = 0; j < tempLen; j++) {\n finaltextAr.push(tempText[j]);\n } // Check if tempText is not the last text. IF true, add
to the final Array.\n\n\n if (i !== len - 1) {\n finaltextAr.push('
');\n }\n }\n\n return finaltextAr;\n },\n\n /**\n * Returns the last occurance of item in a array\n */\n _findLastIndex: function _findLastIndex() {\n var array = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n var item = arguments.length > 1 ? arguments[1] : undefined;\n var i,\n len = array.length;\n\n for (i = len - 1; i >= 0; i--) {\n if (array[i] === item) {\n return i;\n }\n }\n\n return -1;\n }\n };\n return lib;\n }\n};\n/* harmony default export */ __webpack_exports__[\"default\"] = (lib);\n\n//# sourceURL=webpack://SmartLabel/./src/lib.js?"); /***/ }) diff --git a/dist/fusioncharts-smartlabel.min.js b/dist/fusioncharts-smartlabel.min.js index b5f6637..edfe291 100644 --- a/dist/fusioncharts-smartlabel.min.js +++ b/dist/fusioncharts-smartlabel.min.js @@ -1 +1 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.SmartLabel=e():t.SmartLabel=e()}(window,function(){return function(t){var e={};function i(n){if(e[n])return e[n].exports;var r=e[n]={i:n,l:!1,exports:{}};return t[n].call(r.exports,r,r.exports,i),r.l=!0,r.exports}return i.m=t,i.c=e,i.d=function(t,e,n){i.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},i.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},i.t=function(t,e){if(1&e&&(t=i(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)i.d(n,r,function(e){return t[e]}.bind(null,r));return n},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=0)}([function(t,e,i){"use strict";i.r(e);var n={init:function(t){var e=t.document,i=t.navigator.userAgent,r=Math.ceil,s=Math.floor,o="fusioncharts-smartlabel-",h=o+"container",a=o+"tag";return n={win:t,containerClass:h,classNameWithTag:a,classNameWithTagBR:"fusioncharts-smartlabel-br",maxDefaultCacheLimit:1e3,classNameReg:/\bfusioncharts-smartlabel-tag\b/,classNameBrReg:/\bfusioncharts-smartlabel-br\b/,spanAdditionRegx:/(<[^<\>]+?\>)|(&(?:[a-z]+|#[0-9]+);|.)/gi,spanAdditionReplacer:'$1$2',spanRemovalRegx:new RegExp("\\]+?"+a+"[^\\>]{0,}\\>(.*?)\\<\\/span\\>","ig"),xmlTagRegEx:new RegExp("<[^>][^<]*[^>]+>","i"),brRegex:new RegExp("({br[ ]*})|()|()|()|()","g"),ltgtRegex:/<|>/g,nbspRegex:/ /g,htmlSpecialEntityRegex:/&|"|<|>/g,brReplaceRegex://gi,testStrAvg:"WgI",parentContainerStyle:{position:"absolute",top:"-9999em",whiteSpace:"nowrap",padding:"0px",width:"1px",height:"1px",overflow:"hidden"},supportedStyle:{font:"font",fontFamily:"font-family","font-family":"font-family",fontWeight:"font-weight","font-weight":"font-weight",fontSize:"font-size","font-size":"font-size",lineHeight:"line-height","line-height":"line-height",fontStyle:"font-style","font-style":"font-style"},getDocumentSupport:function(){var n,r,s;return e.getElementsByClassName?(n="getElementsByClassName",r=a,s=!0):(n="getElementsByTagName",r="span",s=!1),{isIE:/msie/i.test(i)&&!t.opera,hasSVG:Boolean(t.SVGAngle||e.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")),isHeadLess:new RegExp(" HtmlUnit").test(i),isWebKit:new RegExp(" AppleWebKit/").test(i),childRetriverFn:n,childRetriverString:r,noClassTesting:s}},createContainer:function(t){var i,n;if(t&&(t.offsetWidth||t.offsetHeight)){if(t.appendChild)return t.appendChild(n=e.createElement("DIV")),n.className=h,n.setAttribute("aria-hidden","true"),n.setAttribute("role","presentation"),n}else if((i=e.getElementsByTagName("body")[0])&&i.appendChild)return(n=e.createElement("DIV")).className=h,n.setAttribute("aria-hidden","true"),n.setAttribute("role","presentation"),i.appendChild(n),n},getNearestBreakIndex:function(t,e,i){if(!t||!t.length)return 0;var n,o=i._getWidthFn(),h=0,a=0,l=o(t),g=l/t.length;if(n=e,h=r(e/g),lt.length&&(n=e-l,h=t.length);n>0;){if(n=e-o(t.substr(0,h)),!(a=s(n/g)))return h;h+=a}for(;n<0;){if(n=e-o(t.substr(0,h)),!(a=s(n/g)))return h;h+=a}return h},parseStyle:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e={};return e.fontSize=(t.fontSize||t["font-size"]||"12px")+"",e.fontVariant=t.fontVariant||t["font-variant"]||"normal",e.fontWeight=t.fontWeight||t["font-weight"]||"normal",e.fontStyle=t.fontStyle||t["font-style"]||"normal",e.fontFamily=t.fontFamily||t["font-family"]||"Verdana,sans",e},setLineHeight:function(t){var e=t.fontSize;return t.lineHeight=t.lineHeight||t["line-height"]||1.2*parseInt(e,10)+"px",t},_getCleanHeight:function(t){return t=t.replace(/px/g,""),Number(t)},_getDimentionUsingDiv:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",e=arguments.length>1?arguments[1]:void 0,i=e._container;return t instanceof Array&&(t=t.join("")),i.innerHTML=t,{width:i.offsetWidth,height:i.offsetHeight}},_getDimentionUsingCanvas:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",e=arguments.length>1?arguments[1]:void 0,i=e.ctx,r=e.style,s=n._getCleanHeight(r.lineHeight);return t=t instanceof Array?(t=t.join("")).replace(/
/g,""):t.replace(/
/g,""),{width:i.measureText(t).width,height:s}},_hasOnlyBRTag:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";return!n.xmlTagRegEx.test(t)&&n.brRegex.test(t)},_getDimentionOfMultiLineText:function(){var t,e,i,r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",s=arguments.length>1?arguments[1]:void 0,o=r.replace(n.brRegex,"
"),h=n._getTextArray(o),a=0,l=0,g=s._getWidthFn(),f=n._getCleanHeight(s.style.lineHeight),d=f,c={};for(t=0,e=h.length;t"===h[t]?(l=Math.max(l,a),a=0,d+=f):(a+=i=g(h[t]),c[h[t]]=i);return{height:d,width:l=Math.max(l,a),detailObj:c}},_getTextArray:function(){var t,e,i,n,r,s,o=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",h=[];for(i=(r=o.split("
")).length,t=0;t")}return h},_findLastIndex:function(){var t,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],i=arguments.length>1?arguments[1]:void 0,n=e.length;for(t=n-1;t>=0;t--)if(e[t]===i)return t;return-1}}}},r=n,s=r.init(window),o=s.win.document,h=s.getDocumentSupport(),a=h.isWebKit?0:4.5;function l(t,e,i){var n;i=(i=i>5?i:5)<20?i:20,this.maxContainers=i,this.first=null,this.last=null,this.containers={},this.length=0,this.rootNode=t,e&&((n=o.createElementNS("http://www.w3.org/2000/svg","svg")).setAttributeNS("http://www.w3.org/2000/svg","xlink","http://www.w3.org/1999/xlink"),n.setAttributeNS("http://www.w3.org/2000/svg","height","0"),n.setAttributeNS("http://www.w3.org/2000/svg","width","0"),this.svgRoot=n,this.rootNode.appendChild(n))}l.prototype.get=function(t){var e,i,n,r=this.containers,o=this.length,h=this.maxContainers,a="";for(i in s.supportedStyle)void 0!==t[i]&&(a+=s.supportedStyle[i]+":"+t[i]+";");if(!a)return!1;if(n=r[a])this.first!==n&&(n.prev&&(n.prev.next=n.next),n.next&&(n.next.prev=n.prev),n.next=this.first,n.next.prev=n,this.last===n&&(this.last=n.prev),n.prev=null,this.first=n);else{if(o>=h)for(e=o-h+1;e--;)this.removeContainer(this.last);n=this.addContainer(a)}return n},l.prototype._makeDivNode=function(t){var e,i=t.keyStr;t.node||(t.node=o.createElement("div"),t.node.className="fusioncharts-div",this.rootNode.appendChild(t.node)),e=t.node,h.isIE&&!h.hasSVG?e.style.setAttribute("cssText",i):e.setAttribute("style",i),e.setAttribute("aria-hidden","true"),e.setAttribute("role","presentation"),e.style.display="inline-block",e.innerHTML=s.testStrAvg,t.lineHeight=e.offsetHeight,t.avgCharWidth=e.offsetWidth/3,h.isBrowserLess?(t.svgText||(t.svgText=o.createElementNS("http://www.w3.org/2000/svg","text"),this.svgRoot.appendChild(e)),(e=t.svgText).setAttribute("style",i),e.textContent=s.testStrAvg,t.lineHeight=e.getBBox().height,t.avgCharWidth=(e.getBBox().width-a)/3,e.textContent="...",t.ellipsesWidth=e.getBBox().width-a,e.textContent=".",t.dotWidth=e.getBBox().width-a):(e.innerHTML="...",t.ellipsesWidth=e.offsetWidth,e.innerHTML=".",t.dotWidth=e.offsetWidth,e.innerHTML="")},l.prototype.addContainer=function(t){var e;return this.containers[t]=e={next:null,prev:null,node:null,ellipsesWidth:0,lineHeight:0,dotWidth:0,avgCharWidth:4,keyStr:t,charCache:{}},e.next=this.first,e.next&&(e.next.prev=e),this.first=e,this.last||(this.last=e),this.length+=1,e},l.prototype.removeContainer=function(t){var e=t.keyStr;e&&this.length&&t&&(this.length-=1,t.prev&&(t.prev.next=t.next),t.next&&(t.next.prev=t.prev),this.first===t&&(this.first=t.next),this.last===t&&(this.last=t.prev),t.node&&t.node.parentNode.removeChild(t.node),delete this.containers[e])},l.prototype.dispose=function(){var t,e=this.containers;for(t in this.maxContainers=null,e)this.removeContainer(e[t]);this.rootNode.parentNode.removeChild(this.rootNode),this.rootNode=null,this.first=null,this.last=null};var g=l,f=r.init(window),d=f.win.document,c=f.win.Math,p=c.max,u=c.round,x={" ":" "},m=f.getDocumentSupport(),v=m.isWebKit?0:4.5;function y(t,e,i){var n,r,s,o=!1,h=window.document.createElement("canvas");for(r in(i=i||{}).maxCacheLimit=isFinite(s=i.maxCacheLimit)?s:f.maxDefaultCacheLimit,"string"==typeof t&&(t=d.getElementById(t)),(n=f.createContainer(t)).innerHTML=f.testStrAvg,!m.isHeadLess&&(m.isIE||n.offsetHeight||n.offsetWidth)||(o=!0),n.innerHTML="",f.parentContainerStyle)n.style[r]=f.parentContainerStyle[r];this.parentContainer=n,this.ctx=h&&h.getContext&&h.getContext("2d"),this._containerManager=new g(n,o,10),this._showNoEllipses=!e,this._init=!0,this.style={},this.oldStyle={},this.options=i,this.setStyle()}y.textToLines=function(t){return(t=t||{}).text?"string"!=typeof t.text&&(t.text=t.text.toString()):t.text="",t.lines=t.text.split(/\n|/gi),t},y.prototype._calCharDimWithCache=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",e=arguments.length>1?arguments[1]:void 0,i=arguments.length>2?arguments[2]:void 0;if(!this._init)return!1;var n,r,s,o,h,a,l,g,f,d=this.options.maxCacheLimit,c=this.style||{};return a=this._advancedCache=this._advancedCache||(this._advancedCache={}),l=this._advancedCacheKey||(this._advancedCacheKey=[]),g=t+c.fontSize+c.fontFamily+c.fontWeight+c.fontStyle,f=t+"init"+c.fontSize+c.fontFamily+c.fontWeight+c.fontStyle,!this.ctx&&x[t]&&(t=x[t]),e?void 0===(h=a[f])&&(r=this._getDimention(t.repeat?t.repeat(i):Array(i+1).join(t)).width,s=this._getDimention(t).width,h=a[f]=(r-i*s)/(i+1),l.push(f),l.length>d&&delete a[l.shift()]):h=0,(o=a[g])?{width:o.width,height:o.height}:((n=this._getDimention(t)).width+=h,a[g]={width:n.width,height:n.height},l.push(g),l.length>d&&delete a[l.shift()],n)},y.prototype._getDimention=function(t){return this.requireDiv||!this.ctx?f._getDimentionUsingDiv(t,this):f._getDimentionUsingCanvas(t,this)},y.prototype._getWidthFn=function(){var t=this,e=t._containerObj.svgText;return e?function(t){var i,n;return e.textContent=t,(n=(i=e.getBBox()).width-v)<1&&(n=i.width),n}:function(e){return t.requireDiv||!t.ctx?f._getDimentionUsingDiv(e,t).width:f._getDimentionUsingCanvas(e,t).width}},y.prototype._isSameStyle=function(){var t=this.oldStyle||{},e=this.style;return e.fontSize===t.fontSize&&e.fontFamily===t.fontFamily&&e.fontStyle===t.fontStyle&&e.fontWeight===t.fontWeight&&e.fontVariant===t.fontVariant},y.prototype._setStyleOfCanvas=function(){if(!this._isSameStyle()){var t,e,i=this.style,n=i.fontStyle,r=i.fontVariant,s=i.fontWeight,o=i.fontSize,h=i.fontFamily;t=n+" "+r+" "+s+" "+(o+=-1===o.indexOf("px")?"px":"")+" "+h,this.ctx.font=t,e=this._containerObj=this._containerManager.get(i),this._containerObj?(this._container=e.node,this._context=e.context,this._cache=e.charCache,this._lineHeight=e.lineHeight,this._styleNotSet=!1):this._styleNotSet=!0,e.ellipsesWidth=this._calCharDimWithCache("...",!1).width,e.dotWidth=this._calCharDimWithCache(".",!1).width,e.lineHeight=this._lineHeight=e.lineHeight||f._getCleanHeight(i.lineHeight),this.oldStyle=i}},y.prototype._setStyleOfDiv=function(){var t,e=this.style;this._containerObj=t=this._containerManager.get(e),t.node||this._containerManager._makeDivNode(this._containerObj),this._containerObj?(this._container=t.node,this._context=t.context,this._cache=t.charCache,this._lineHeight=t.lineHeight,this._styleNotSet=!1):this._styleNotSet=!0},y.prototype._updateStyle=function(){return this.requireDiv||!this.ctx?this._setStyleOfDiv():this._setStyleOfCanvas()},y.prototype.setStyle=function(t){return this.style=f.parseStyle(t),f.setLineHeight(this.style),this},y.prototype.useEllipsesOnOverflow=function(t){return this._init?(this._showNoEllipses=!t,this):this},y.prototype.getSmartText=function(t,e,i,n){if(!this._init)return!1;null==t?t="":"string"!=typeof t&&(t=t.toString());var r,s,o,h,a,l,g,c,u,x,v,y,_,w,b,T,S,C,H,W,N,R,L,M,D,j,O,B,E,A,I,z,F,V,k,U=0,q=-1,K=-1,$=-1,P=0,G=0,J=[],Q=0,X=this._showNoEllipses?"":"...",Y=this.ctx,Z=[],tt=-1,et=-1,it=-1,nt=function(t){for(var e=/\s/,i=(t=t.replace(/^\s\s*/,"")).length;e.test(t.charAt(i-=1)););return t.slice(0,i+1)},rt={text:t,maxWidth:e,maxHeight:i,width:null,height:null,oriTextWidth:null,oriTextHeight:null,oriText:t,isTruncated:!1};if(O=f.xmlTagRegEx.test(t)||f.nbspRegex.test(t),V=f._hasOnlyBRTag(t),this.requireDiv=O&&!V,this._updateStyle(),B=this._lineHeight,E=this._context,A=this._container,z=(I=this._containerObj).ellipsesWidth,F=I.dotWidth,l=t.replace(f.spanAdditionRegx,"$2"),y=this._getWidthFn(),B-i<=1&&B-i>=0&&(i*=1.2),Y||A){if(!m.isBrowserLess){if(O?V?(t=t.replace(f.brRegex,"
"),k=f._getDimentionOfMultiLineText(t,this),rt.oriTextWidth=g=k.width,rt.oriTextHeight=c=k.height):(A.innerHTML=t,rt.oriTextWidth=g=A.offsetWidth,rt.oriTextHeight=c=A.offsetHeight):(h=t=t.replace(f.ltgtRegex,function(t){return"<"===t?"<":">"}),b=this.getOriSize(h,!0,{hasHTMLTag:O,hasOnlyBrTag:V,cleanText:!0}),rt.oriTextWidth=g=b.width,rt.oriTextHeight=c=b.height),c<=i&&g<=e)return rt.width=rt.oriTextWidth=g,rt.height=rt.oriTextHeight=c,rt;if(B>i)return rt.text="",rt.width=rt.oriTextWidth=0,rt.height=rt.oriTextHeight=0,rt}if(t=nt(t).replace(/(\s+)/g," "),a=this._showNoEllipses?e:e-z,!O||V){if(r=(J=f._getTextArray(t)).length,s="",o=[],v=J[0],this._cache[v]?H=this._cache[v].width:(H=y(v),this._cache[v]={width:H}),a>H&&!V)o=t.substr(0,f.getNearestBreakIndex(t,a,this)).split("");else{if(H>e)return rt.text="",rt.width=rt.oriTextWidth=rt.height=rt.oriTextHeight=0,rt;X&&((a=e-2*F)>H?X="..":(a=e-F)>H?X=".":(a=0,X=""))}if(Q=o.length,P=y(o.join("")),G=this._lineHeight,n){for(;Q"!==o[Q]){if(this._cache[v]?H=this._cache[v].width:(b&&(H=b.detailObj[v])||(H=y(v)),this._cache[v]={width:H}),(P+=H)>a&&(s||(s=o.slice(0,-1).join("")),P>e))return rt.text=nt(s)+X,rt.tooltext=rt.oriText,rt.width=p(U,P),rt.height=G,rt}else G+=this._lineHeight,$=Q,U=p(U,P),P=0,s=null;return rt.text=o.join(""),rt.width=p(U,P),rt.height=G,rt}for(;Q"===o[Q]){if(U=p(U,P),(G+=this._lineHeight)<=i){$=Q,P=0,s=null;continue}if(G>i)return s=o.slice(0,-1).join(""),rt.text=nt(s)+X,rt.tooltext=l,rt.width=U,rt.height=G-this._lineHeight,rt}if(this._cache[v]?H=this._cache[v].width:(b&&(H=b.detailObj[v])||(H=y(v)),this._cache[v]={width:H}),(P+=H)>a&&(s||(s=o.slice(0,-1).join("")),P>e)){if("
"===J[Q+1])continue;if(K=f._findLastIndex(J.slice(0,o.length)," "),q=f._findLastIndex(J.slice(0,o.length),"-"),K>$?(P=y(o.slice($+1,K).join("")),o.splice(K,1,"
"),$=K,u=K+1):q>$?(q===o.length-1?(P=y(o.slice($+1,K).join("")),o.splice(q,1,"
-")):(P=y(o.slice($+1,K).join("")),o.splice(q,1,"-
")),$=q,u=q+1):(o.splice(o.length-1,1,"
"+J[Q]),it=o.length-2,P=y(o.slice($+1,it+1).join("")),$=it,u=Q),(G+=this._lineHeight)>i)return rt.text=nt(s)+X,rt.tooltext=rt.oriText,rt.width=e,rt.height=G-this._lineHeight,rt;U=p(U,P),s=null,V?P=f._getDimentionOfMultiLineText(o.slice($+1).join(""),this).width:(x=f.getNearestBreakIndex(t.substr(u),a,this),P=y(t.substr(u,x||1)),o.length)/g,'$1'),A.innerHTML=t,S=0,C=(T=A[m.childRetriverFn](m.childRetriverString)).length;Se||!r)return rt.text="",rt.width=rt.oriTextWidth=rt.height=rt.oriTextHeight=0,rt;if(H>a&&!this._showNoEllipses&&((a=e-2*F)>H?X="..":(a=e-F)>H?X=".":(a=0,X="")),_=Z[0].elem.offsetLeft,w=Z[0].elem.offsetTop,n)for(;Qa&&(j||(j=Q),A.offsetWidth>e&&(D=Q,Q=r));else for(;Qa?(j||(j=Q),R>e&&(K=Z[Q].spaceIdx,q=Z[Q].dashIdx,K>$?(Z[K].elem.innerHTML="
",$=K):q>$?(Z[q].elem.innerHTML=q===Q?"
-":"-
",$=q):W.parentNode.insertBefore(M=d.createElement("br"),W),W.offsetHeight+W.offsetTop>i?(M?M.parentNode.removeChild(M):$===q?Z[q].elem.innerHTML="-":Z[K].elem.innerHTML=" ",D=Q,Q=r):j=null)):L>i&&(D=Q,Q=r);if(D=j;Q-=1)(W=Z[Q].elem).parentNode.removeChild(W);for(;Q>=0;Q-=1)W=Z[Q].elem,f.classNameBrReg.test(W.className)?W.parentNode.removeChild(W):Q=0}return rt.text=A.innerHTML.replace(f.spanRemovalRegx,"$1").replace(/\&\;/g,"&"),rt.isTruncated&&(rt.text+=X,rt.tooltext=l),rt.height=A.offsetHeight,rt.width=A.offsetWidth,rt}return rt.error=new Error("Body Tag Missing!"),rt},y.prototype.getOriSize=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(!this._init)return!1;null==t?t="":"string"!=typeof t&&(t=t.toString());var n,r,s,o,h,a,l=0,g=0,d={},c=i.hasHTMLTag,x=i.hasOnlyBrTag;if(void 0===c&&(c=f.xmlTagRegEx.test(t)||f.nbspRegex.test(t)),void 0===x&&(x=f._hasOnlyBRTag(t)),this.requireDiv=c&&!x,i.cleanText||(t=t.replace(f.ltgtRegex,function(t){return"<"===t?"<":">"})),this._updateStyle(),a=this._container,x)return f._getDimentionOfMultiLineText(t,this);if(!e)return this._calCharDimWithCache(t);if(c)return a.innerHTML=t,{width:a.offsetWidth,height:a.offsetHeight};for(o=0,h=(n=t.split("")).length;o]+?\>)|(&(?:[a-z]+|#[0-9]+);|.)/gi,spanAdditionReplacer:'$1$2',spanRemovalRegx:new RegExp("\\]+?"+a+"[^\\>]{0,}\\>(.*?)\\<\\/span\\>","ig"),xmlTagRegEx:new RegExp("<[^>][^<]*[^>]+>","i"),brRegex:new RegExp("({br[ ]*})|()|()|()|()","g"),ltgtRegex:/<|>/g,nbspRegex:/ | | /g,htmlSpecialEntityRegex:/&|"|<|>/g,brReplaceRegex://gi,testStrAvg:"WgI",parentContainerStyle:{position:"absolute",top:"-9999em",whiteSpace:"nowrap",padding:"0px",width:"1px",height:"1px",overflow:"hidden"},supportedStyle:{font:"font",fontFamily:"font-family","font-family":"font-family",fontWeight:"font-weight","font-weight":"font-weight",fontSize:"font-size","font-size":"font-size",lineHeight:"line-height","line-height":"line-height",fontStyle:"font-style","font-style":"font-style"},getDocumentSupport:function(){var n,r,s;return e.getElementsByClassName?(n="getElementsByClassName",r=a,s=!0):(n="getElementsByTagName",r="span",s=!1),{isIE:/msie/i.test(i)&&!t.opera,hasSVG:Boolean(t.SVGAngle||e.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")),isHeadLess:new RegExp(" HtmlUnit").test(i),isWebKit:new RegExp(" AppleWebKit/").test(i),childRetriverFn:n,childRetriverString:r,noClassTesting:s}},createContainer:function(t){var i,n;if(t&&(t.offsetWidth||t.offsetHeight)){if(t.appendChild)return t.appendChild(n=e.createElement("DIV")),n.className=h,n.setAttribute("aria-hidden","true"),n.setAttribute("role","presentation"),n}else if((i=e.getElementsByTagName("body")[0])&&i.appendChild)return(n=e.createElement("DIV")).className=h,n.setAttribute("aria-hidden","true"),n.setAttribute("role","presentation"),i.appendChild(n),n},getNearestBreakIndex:function(t,e,i){if(!t||!t.length)return 0;var n,o=i._getWidthFn(),h=0,a=0,l=o(t),g=l/t.length;if(n=e,h=r(e/g),lt.length&&(n=e-l,h=t.length);n>0;){if(n=e-o(t.substr(0,h)),!(a=s(n/g)))return h;h+=a}for(;n<0;){if(n=e-o(t.substr(0,h)),!(a=s(n/g)))return h;h+=a}return h},parseStyle:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e={};return e.fontSize=(t.fontSize||t["font-size"]||"12px")+"",e.fontVariant=t.fontVariant||t["font-variant"]||"normal",e.fontWeight=t.fontWeight||t["font-weight"]||"normal",e.fontStyle=t.fontStyle||t["font-style"]||"normal",e.fontFamily=t.fontFamily||t["font-family"]||"Verdana,sans",e},setLineHeight:function(t){var e=t.fontSize;return t.lineHeight=t.lineHeight||t["line-height"]||1.2*parseInt(e,10)+"px",t},_getCleanHeight:function(t){return t=t.replace(/px/g,""),Number(t)},_getDimentionUsingDiv:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",e=(arguments.length>1?arguments[1]:void 0)._container;return t instanceof Array&&(t=t.join("")),e.innerHTML=t,{width:e.offsetWidth,height:e.offsetHeight}},_getDimentionUsingCanvas:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",e=arguments.length>1?arguments[1]:void 0,i=e.ctx,r=e.style,s=n._getCleanHeight(r.lineHeight);return t=t instanceof Array?(t=t.join("")).replace(/
/g,""):t.replace(/
/g,""),{width:i.measureText(t).width,height:s}},_hasOnlyBRTag:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";return!n.xmlTagRegEx.test(t)&&n.brRegex.test(t)},_getDimentionOfMultiLineText:function(){var t,e,i,r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",s=arguments.length>1?arguments[1]:void 0,o=r.replace(n.brRegex,"
"),h=n._getTextArray(o),a=0,l=0,g=s._getWidthFn(),f=n._getCleanHeight(s.style.lineHeight),d=f,c={};for(t=0,e=h.length;t"===h[t]?(l=Math.max(l,a),a=0,d+=f):(a+=i=g(h[t]),c[h[t]]=i);return{height:d,width:l=Math.max(l,a),detailObj:c}},_getTextArray:function(){var t,e,i,n,r,s,o=[];for(i=(r=(arguments.length>0&&void 0!==arguments[0]?arguments[0]:"").split("
")).length,t=0;t")}return o},_findLastIndex:function(){var t,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],i=arguments.length>1?arguments[1]:void 0;for(t=e.length-1;t>=0;t--)if(e[t]===i)return t;return-1}}}},r=n,s=r.init(window),o=s.win.document,h=s.getDocumentSupport(),a=h.isWebKit?0:4.5;function l(t,e,i){var n;i=(i=i>5?i:5)<20?i:20,this.maxContainers=i,this.first=null,this.last=null,this.containers={},this.length=0,this.rootNode=t,e&&((n=o.createElementNS("http://www.w3.org/2000/svg","svg")).setAttributeNS("http://www.w3.org/2000/svg","xlink","http://www.w3.org/1999/xlink"),n.setAttributeNS("http://www.w3.org/2000/svg","height","0"),n.setAttributeNS("http://www.w3.org/2000/svg","width","0"),this.svgRoot=n,this.rootNode.appendChild(n))}l.prototype.get=function(t){var e,i,n,r=this.containers,o=this.length,h=this.maxContainers,a="";for(i in s.supportedStyle)void 0!==t[i]&&(a+=s.supportedStyle[i]+":"+t[i]+";");if(!a)return!1;if(n=r[a])this.first!==n&&(n.prev&&(n.prev.next=n.next),n.next&&(n.next.prev=n.prev),n.next=this.first,n.next.prev=n,this.last===n&&(this.last=n.prev),n.prev=null,this.first=n);else{if(o>=h)for(e=o-h+1;e--;)this.removeContainer(this.last);n=this.addContainer(a)}return n},l.prototype._makeDivNode=function(t){var e,i=t.keyStr;t.node||(t.node=o.createElement("div"),t.node.className="fusioncharts-div",this.rootNode.appendChild(t.node)),e=t.node,h.isIE&&!h.hasSVG?e.style.setAttribute("cssText",i):e.setAttribute("style",i),e.setAttribute("aria-hidden","true"),e.setAttribute("role","presentation"),e.style.display="inline-block",e.innerHTML=s.testStrAvg,t.lineHeight=e.offsetHeight,t.avgCharWidth=e.offsetWidth/3,h.isBrowserLess?(t.svgText||(t.svgText=o.createElementNS("http://www.w3.org/2000/svg","text"),this.svgRoot.appendChild(e)),(e=t.svgText).setAttribute("style",i),e.textContent=s.testStrAvg,t.lineHeight=e.getBBox().height,t.avgCharWidth=(e.getBBox().width-a)/3,e.textContent="...",t.ellipsesWidth=e.getBBox().width-a,e.textContent=".",t.dotWidth=e.getBBox().width-a):(e.innerHTML="...",t.ellipsesWidth=e.offsetWidth,e.innerHTML=".",t.dotWidth=e.offsetWidth,e.innerHTML="")},l.prototype.addContainer=function(t){var e;return this.containers[t]=e={next:null,prev:null,node:null,ellipsesWidth:0,lineHeight:0,dotWidth:0,avgCharWidth:4,keyStr:t,charCache:{}},e.next=this.first,e.next&&(e.next.prev=e),this.first=e,this.last||(this.last=e),this.length+=1,e},l.prototype.removeContainer=function(t){var e=t.keyStr;e&&this.length&&t&&(this.length-=1,t.prev&&(t.prev.next=t.next),t.next&&(t.next.prev=t.prev),this.first===t&&(this.first=t.next),this.last===t&&(this.last=t.prev),t.node&&t.node.parentNode.removeChild(t.node),delete this.containers[e])},l.prototype.dispose=function(){var t,e=this.containers;for(t in this.maxContainers=null,e)this.removeContainer(e[t]);this.rootNode.parentNode.removeChild(this.rootNode),this.rootNode=null,this.first=null,this.last=null};var g=l;function f(t,e,i){return e in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t}var d=r.init(window),c=d.win.document,u=d.win.Math,p=u.max,x=u.round,m={" ":" "},v=d.getDocumentSupport(),y=v.isWebKit?0:4.5;function _(t,e,i){var n,r,s,o=!1,h=window.document.createElement("canvas");for(r in(i=i||{}).maxCacheLimit=isFinite(s=i.maxCacheLimit)?s:d.maxDefaultCacheLimit,"string"==typeof t&&(t=c.getElementById(t)),(n=d.createContainer(t)).innerHTML=d.testStrAvg,!v.isHeadLess&&(v.isIE||n.offsetHeight||n.offsetWidth)||(o=!0),n.innerHTML="",d.parentContainerStyle)n.style[r]=d.parentContainerStyle[r];this.parentContainer=n,this.ctx=h&&h.getContext&&h.getContext("2d"),this._containerManager=new g(n,o,10),this._showNoEllipses=!e,this._init=!0,this.style={},this.oldStyle={},this.options=i,this.setStyle()}_.textToLines=function(t){return(t=t||{}).text?"string"!=typeof t.text&&(t.text=t.text.toString()):t.text="",t.lines=t.text.split(/\n|/gi),t},_.prototype._calCharDimWithCache=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",e=arguments.length>1?arguments[1]:void 0,i=arguments.length>2?arguments[2]:void 0;if(!this._init)return!1;var n,r,s,o,h,a,l,g,f,d=this.options.maxCacheLimit,c=this.style||{};return a=this._advancedCache=this._advancedCache||(this._advancedCache={}),l=this._advancedCacheKey||(this._advancedCacheKey=[]),g=t+c.fontSize+c.fontFamily+c.fontWeight+c.fontStyle,f=t+"init"+c.fontSize+c.fontFamily+c.fontWeight+c.fontStyle,!this.ctx&&m[t]&&(t=m[t]),e?void 0===(h=a[f])&&(r=this._getDimention(t.repeat?t.repeat(i):Array(i+1).join(t)).width,s=this._getDimention(t).width,h=a[f]=(r-i*s)/(i+1),l.push(f),l.length>d&&delete a[l.shift()]):h=0,(o=a[g])?{width:o.width,height:o.height}:((n=this._getDimention(t)).width+=h,a[g]={width:n.width,height:n.height},l.push(g),l.length>d&&delete a[l.shift()],n)},_.prototype._getDimention=function(t){return this.requireDiv||!this.ctx?d._getDimentionUsingDiv(t,this):d._getDimentionUsingCanvas(t,this)},_.prototype._getWidthFn=function(){var t=this,e=t._containerObj.svgText;return e?function(t){var i,n;return e.textContent=t,(n=(i=e.getBBox()).width-y)<1&&(n=i.width),n}:function(e){return t.requireDiv||!t.ctx?d._getDimentionUsingDiv(e,t).width:d._getDimentionUsingCanvas(e,t).width}},_.prototype._isSameStyle=function(){var t=this.oldStyle||{},e=this.style;return e.fontSize===t.fontSize&&e.fontFamily===t.fontFamily&&e.fontStyle===t.fontStyle&&e.fontWeight===t.fontWeight&&e.fontVariant===t.fontVariant},_.prototype._setStyleOfCanvas=function(){if(!this._isSameStyle()){var t,e,i=this.style,n=i.fontStyle,r=i.fontVariant,s=i.fontWeight,o=i.fontSize,h=i.fontFamily;t=n+" "+r+" "+s+" "+(o+=-1===o.indexOf("px")?"px":"")+" "+h,this.ctx.font=t,e=this._containerObj=this._containerManager.get(i),this._containerObj?(this._container=e.node,this._context=e.context,this._cache=e.charCache,this._lineHeight=e.lineHeight,this._styleNotSet=!1):this._styleNotSet=!0,e.ellipsesWidth=this._calCharDimWithCache("...",!1).width,e.dotWidth=this._calCharDimWithCache(".",!1).width,e.lineHeight=this._lineHeight=e.lineHeight||d._getCleanHeight(i.lineHeight),this.oldStyle=i}},_.prototype._setStyleOfDiv=function(){var t,e=this.style;this._containerObj=t=this._containerManager.get(e),t.node||this._containerManager._makeDivNode(this._containerObj),this._containerObj?(this._container=t.node,this._context=t.context,this._cache=t.charCache,this._lineHeight=t.lineHeight,this._styleNotSet=!1):this._styleNotSet=!0},_.prototype._updateStyle=function(){return this.requireDiv||!this.ctx?this._setStyleOfDiv():this._setStyleOfCanvas()},_.prototype.setStyle=function(t){return this.style=d.parseStyle(t),d.setLineHeight(this.style),this},_.prototype.useEllipsesOnOverflow=function(t){return this._init?(this._showNoEllipses=!t,this):this},_.prototype.getSmartText=function(t,e,i,n){if(!this._init)return!1;null==t?t="":"string"!=typeof t&&(t=t.toString());var r,s,o,h,a,l,g,f,u,x,m,y,_,b,w,S,T,C,H,W,N,R,O,j,L,M,D,B,E,A,z,I,F,k,V,P=0,U=-1,q=-1,K=-1,$=0,G=0,J=[],Q=0,X=this._showNoEllipses?"":"...",Y=this.ctx,Z=[],tt=-1,et=-1,it=-1,nt=function(t){for(var e=/\s/,i=(t=t.replace(/^\s\s*/,"")).length;e.test(t.charAt(i-=1)););return t.slice(0,i+1)},rt={text:t,maxWidth:e,maxHeight:i,width:null,height:null,oriTextWidth:null,oriTextHeight:null,oriText:t,isTruncated:!1};if(D=d.xmlTagRegEx.test(t)||d.nbspRegex.test(t),k=d._hasOnlyBRTag(t),this.requireDiv=D&&!k,this._updateStyle(),B=this._lineHeight,E=this._context,A=this._container,I=(z=this._containerObj).ellipsesWidth,F=z.dotWidth,l=t.replace(d.spanAdditionRegx,"$2"),y=this._getWidthFn(),B-i<=1&&B-i>=0&&(i*=1.2),Y||A){if(!v.isBrowserLess){if(D?k?(t=t.replace(d.brRegex,"
"),V=d._getDimentionOfMultiLineText(t,this),rt.oriTextWidth=g=V.width,rt.oriTextHeight=f=V.height):(A.innerHTML=t,rt.oriTextWidth=g=A.offsetWidth,rt.oriTextHeight=f=A.offsetHeight):(h=t=t.replace(d.ltgtRegex,function(t){return"<"===t?"<":">"}),w=this.getSize(h,!0,{hasHTMLTag:D,hasOnlyBrTag:k,cleanText:!0}),rt.oriTextWidth=g=w.width,rt.oriTextHeight=f=w.height),f<=i&&g<=e)return rt.width=rt.oriTextWidth=g,rt.height=rt.oriTextHeight=f,rt;if(B>i)return rt.text="",rt.width=rt.oriTextWidth=0,rt.height=rt.oriTextHeight=0,rt}if(t=nt(t).replace(/(\s+)/g," "),a=this._showNoEllipses?e:e-I,!D||k){if(r=(J=d._getTextArray(t)).length,s="",o=[],m=J[0],this._cache[m]?H=this._cache[m].width:(H=y(m),this._cache[m]={width:H}),a>H&&!k)o=t.substr(0,d.getNearestBreakIndex(t,a,this)).split("");else{if(H>e)return rt.text="",rt.width=rt.oriTextWidth=rt.height=rt.oriTextHeight=0,rt;X&&((a=e-2*F)>H?X="..":(a=e-F)>H?X=".":(a=0,X=""))}if(Q=o.length,$=y(o.join("")),G=this._lineHeight,n){for(;Q"!==o[Q]){if(this._cache[m]?H=this._cache[m].width:(w&&(H=w.detailObj[m])||(H=y(m)),this._cache[m]={width:H}),($+=H)>a&&(s||(s=o.slice(0,-1).join("")),$>e))return rt.text=nt(s)+X,rt.tooltext=rt.oriText,rt.width=p(P,$),rt.height=G,rt}else G+=this._lineHeight,K=Q,P=p(P,$),$=0,s=null;return rt.text=o.join(""),rt.width=p(P,$),rt.height=G,rt}for(;Q"===o[Q]){if(P=p(P,$),(G+=this._lineHeight)<=i){K=Q,$=0,s=null;continue}if(G>i)return s=o.slice(0,-1).join(""),rt.text=nt(s)+X,rt.tooltext=l,rt.width=P,rt.height=G-this._lineHeight,rt}if(this._cache[m]?H=this._cache[m].width:(w&&(H=w.detailObj[m])||(H=y(m)),this._cache[m]={width:H}),($+=H)>a&&(s||(s=o.slice(0,-1).join("")),$>e)){if("
"===J[Q+1])continue;if(q=d._findLastIndex(J.slice(0,o.length)," "),U=d._findLastIndex(J.slice(0,o.length),"-"),q>K?($=y(o.slice(K+1,q).join("")),o.splice(q,1,"
"),K=q,u=q+1):U>K?(U===o.length-1?($=y(o.slice(K+1,q).join("")),o.splice(U,1,"
-")):($=y(o.slice(K+1,q).join("")),o.splice(U,1,"-
")),K=U,u=U+1):(o.splice(o.length-1,1,"
"+J[Q]),it=o.length-2,$=y(o.slice(K+1,it+1).join("")),K=it,u=Q),(G+=this._lineHeight)>i)return rt.text=nt(s)+X,rt.tooltext=rt.oriText,rt.width=e,rt.height=G-this._lineHeight,rt;P=p(P,$),s=null,k?$=d._getDimentionOfMultiLineText(o.slice(K+1).join(""),this).width:(x=d.getNearestBreakIndex(t.substr(u),a,this),$=y(t.substr(u,x||1)),o.length)/g,'$1'),A.innerHTML=t,T=0,C=(S=A[v.childRetriverFn](v.childRetriverString)).length;Te||!r)return rt.text="",rt.width=rt.oriTextWidth=rt.height=rt.oriTextHeight=0,rt;if(H>a&&!this._showNoEllipses&&((a=e-2*F)>H?X="..":(a=e-F)>H?X=".":(a=0,X="")),_=Z[0].elem.offsetLeft,b=Z[0].elem.offsetTop,n)for(;Qa&&(M||(M=Q),A.offsetWidth>e&&(L=Q,Q=r));else for(;Qa?(M||(M=Q),R>e&&(q=Z[Q].spaceIdx,U=Z[Q].dashIdx,q>K?(Z[q].elem.innerHTML="
",K=q):U>K?(Z[U].elem.innerHTML=U===Q?"
-":"-
",K=U):W.parentNode.insertBefore(j=c.createElement("br"),W),W.offsetHeight+W.offsetTop>i?(j?j.parentNode.removeChild(j):K===U?Z[U].elem.innerHTML="-":Z[q].elem.innerHTML=" ",L=Q,Q=r):M=null)):O>i&&(L=Q,Q=r);if(L=M;Q-=1)(W=Z[Q].elem).parentNode.removeChild(W);for(;Q>=0;Q-=1)W=Z[Q].elem,d.classNameBrReg.test(W.className)?W.parentNode.removeChild(W):Q=0}return rt.text=A.innerHTML.replace(d.spanRemovalRegx,"$1").replace(/\&\;/g,"&"),rt.isTruncated&&(rt.text+=X,rt.tooltext=l),rt.height=A.offsetHeight,rt.width=A.offsetWidth,rt}return rt.error=new Error("Body Tag Missing!"),rt},_.prototype.getSize=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(!this._init)return!1;null==t?t="":"string"!=typeof t&&(t=t.toString());var n,r,s,o,h,a,l=0,g=0,c={},u=i.hasHTMLTag,m=i.hasOnlyBrTag;if(void 0===u&&(u=d.xmlTagRegEx.test(t)||d.nbspRegex.test(t)),void 0===m&&(m=d._hasOnlyBRTag(t)),this.requireDiv=u&&!m,i.cleanText||(t=t.replace(d.ltgtRegex,function(t){return"<"===t?"<":">"})),this._updateStyle(),a=this._container,!e)return this._calCharDimWithCache(t);for(o=0,h=(n=t.split("")).length;o0&&void 0!==arguments[0]?arguments[0]:"",e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return this.getSize(t,e,i)},_.prototype.dispose=function(){return this._init?(this._containerManager&&this._containerManager.dispose&&this._containerManager.dispose(),delete this._container,delete this._context,delete this._cache,delete this._containerManager,delete this._containerObj,delete this.id,delete this.style,delete this.parentContainer,delete this._showNoEllipses,this):this};e.default=_}]).default}); \ No newline at end of file diff --git a/es/SmartlabelManager.js b/es/SmartlabelManager.js index aea6821..228840a 100644 --- a/es/SmartlabelManager.js +++ b/es/SmartlabelManager.js @@ -1 +1 @@ -import lib from"./lib";import ContainerManager from"./container-manager";var slLib=lib.init(window),doc=slLib.win.document,M=slLib.win.Math,max=M.max,round=M.round,htmlSplCharSpace={" ":" "},documentSupport=slLib.getDocumentSupport(),SVG_BBOX_CORRECTION=documentSupport.isWebKit?0:4.5;function SmartLabelManager(container,useEllipses,options){var wrapper,prop,max,isBrowserLess=false,canvas=window.document.createElement("canvas");options=options||{};options.maxCacheLimit=isFinite(max=options.maxCacheLimit)?max:slLib.maxDefaultCacheLimit;if(typeof container==="string"){container=doc.getElementById(container)}wrapper=slLib.createContainer(container);wrapper.innerHTML=slLib.testStrAvg;if(documentSupport.isHeadLess||!documentSupport.isIE&&!wrapper.offsetHeight&&!wrapper.offsetWidth){isBrowserLess=true}wrapper.innerHTML="";for(prop in slLib.parentContainerStyle){wrapper.style[prop]=slLib.parentContainerStyle[prop]}this.parentContainer=wrapper;this.ctx=canvas&&canvas.getContext&&canvas.getContext("2d");this._containerManager=new ContainerManager(wrapper,isBrowserLess,10);this._showNoEllipses=!useEllipses;this._init=true;this.style={};this.oldStyle={};this.options=options;this.setStyle()}SmartLabelManager.textToLines=function(smartlabel){smartlabel=smartlabel||{};if(!smartlabel.text){smartlabel.text=""}else if(typeof smartlabel.text!=="string"){smartlabel.text=smartlabel.text.toString()}smartlabel.lines=smartlabel.text.split(/\n|/ig);return smartlabel};SmartLabelManager.prototype._calCharDimWithCache=function(){var text=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"";var calculateDifference=arguments.length>1?arguments[1]:undefined;var length=arguments.length>2?arguments[2]:undefined;if(!this._init){return false}var size,tw,twi,cachedStyle,asymmetricDifference,maxAdvancedCacheLimit=this.options.maxCacheLimit,style=this.style||{},cache,advancedCacheKey,cacheName,cacheInitName;cache=this._advancedCache=this._advancedCache||(this._advancedCache={});advancedCacheKey=this._advancedCacheKey||(this._advancedCacheKey=[]);cacheName=text+style.fontSize+style.fontFamily+style.fontWeight+style.fontStyle;cacheInitName=text+"init"+style.fontSize+style.fontFamily+style.fontWeight+style.fontStyle;if(!this.ctx&&htmlSplCharSpace[text]){text=htmlSplCharSpace[text]}if(!calculateDifference){asymmetricDifference=0}else{if((asymmetricDifference=cache[cacheInitName])===undefined){tw=this._getDimention(text.repeat?text.repeat(length):Array(length+1).join(text)).width;twi=this._getDimention(text).width;asymmetricDifference=cache[cacheInitName]=(tw-length*twi)/(length+1);advancedCacheKey.push(cacheInitName);if(advancedCacheKey.length>maxAdvancedCacheLimit){delete cache[advancedCacheKey.shift()]}}}if(cachedStyle=cache[cacheName]){return{width:cachedStyle.width,height:cachedStyle.height}}size=this._getDimention(text);size.width+=asymmetricDifference;cache[cacheName]={width:size.width,height:size.height};advancedCacheKey.push(cacheName);if(advancedCacheKey.length>maxAdvancedCacheLimit){delete cache[advancedCacheKey.shift()]}return size};SmartLabelManager.prototype._getDimention=function(text){if(this.requireDiv||!this.ctx){return slLib._getDimentionUsingDiv(text,this)}else{return slLib._getDimentionUsingCanvas(text,this)}};SmartLabelManager.prototype._getWidthFn=function(){var sl=this,contObj=sl._containerObj,svgText=contObj.svgText;if(svgText){return function(str){var bbox,width;svgText.textContent=str;bbox=svgText.getBBox();width=bbox.width-SVG_BBOX_CORRECTION;if(width<1){width=bbox.width}return width}}else{return function(str){if(sl.requireDiv||!sl.ctx){return slLib._getDimentionUsingDiv(str,sl).width}else{return slLib._getDimentionUsingCanvas(str,sl).width}}}};SmartLabelManager.prototype._isSameStyle=function(){var sl=this,oldStyle=sl.oldStyle||{},style=sl.style;if(style.fontSize!==oldStyle.fontSize||style.fontFamily!==oldStyle.fontFamily||style.fontStyle!==oldStyle.fontStyle||style.fontWeight!==oldStyle.fontWeight||style.fontVariant!==oldStyle.fontVariant){return false}return true};SmartLabelManager.prototype._setStyleOfCanvas=function(){if(this._isSameStyle()){return}var sl=this,style=sl.style,hashString,sCont,fontStyle=style.fontStyle,fontVariant=style.fontVariant,fontWeight=style.fontWeight,fontSize=style.fontSize,fontFamily=style.fontFamily;fontSize+=fontSize.indexOf("px")===-1?"px":"";hashString=fontStyle+" "+fontVariant+" "+fontWeight+" "+fontSize+" "+fontFamily;sl.ctx.font=hashString;sCont=this._containerObj=this._containerManager.get(style);if(this._containerObj){this._container=sCont.node;this._context=sCont.context;this._cache=sCont.charCache;this._lineHeight=sCont.lineHeight;this._styleNotSet=false}else{this._styleNotSet=true}sCont.ellipsesWidth=sl._calCharDimWithCache("...",false).width;sCont.dotWidth=sl._calCharDimWithCache(".",false).width;sCont.lineHeight=this._lineHeight=sCont.lineHeight||slLib._getCleanHeight(style.lineHeight);this.oldStyle=style};SmartLabelManager.prototype._setStyleOfDiv=function(){var sCont,style=this.style;this._containerObj=sCont=this._containerManager.get(style);if(!sCont.node){this._containerManager._makeDivNode(this._containerObj)}if(this._containerObj){this._container=sCont.node;this._context=sCont.context;this._cache=sCont.charCache;this._lineHeight=sCont.lineHeight;this._styleNotSet=false}else{this._styleNotSet=true}};SmartLabelManager.prototype._updateStyle=function(){return this.requireDiv||!this.ctx?this._setStyleOfDiv():this._setStyleOfCanvas()};SmartLabelManager.prototype.setStyle=function(style){this.style=slLib.parseStyle(style);slLib.setLineHeight(this.style);return this};SmartLabelManager.prototype.useEllipsesOnOverflow=function(useEllipses){if(!this._init){return this}this._showNoEllipses=!useEllipses;return this};SmartLabelManager.prototype.getSmartText=function(text,maxWidth,maxHeight,noWrap){if(!this._init){return false}if(text===undefined||text===null){text=""}else if(typeof text!=="string"){text=text.toString()}var len,trimStr,tempArr,tmpText,maxWidthWithEll,toolText,oriWidth,oriHeight,newCharIndex,nearestChar,tempChar,getWidth,initialLeft,initialTop,getOriSizeImproveObj,spanArr,x,y,minWidth,elem,chr,elemRightMostPoint,elemLowestPoint,lastBR,removeFromIndex,removeFromIndexForEllipses,hasHTMLTag=false,maxStrWidth=0,lastDash=-1,lastSpace=-1,lastIndexBroken=-1,strWidth=0,strHeight=0,oriTextArr=[],i=0,ellipsesStr=this._showNoEllipses?"":"...",lineHeight,context,container,sCont,ellipsesWidth,dotWidth,canvas=this.ctx,characterArr=[],dashIndex=-1,spaceIndex=-1,lastLineBreak=-1,hasOnlyBrTag,dimentionObj,fastTrim=function fastTrim(str){str=str.replace(/^\s\s*/,"");var ws=/\s/,i=str.length;while(ws.test(str.charAt(i-=1))){}return str.slice(0,i+1)},smartLabel={text:text,maxWidth:maxWidth,maxHeight:maxHeight,width:null,height:null,oriTextWidth:null,oriTextHeight:null,oriText:text,isTruncated:false};hasHTMLTag=slLib.xmlTagRegEx.test(text)||slLib.nbspRegex.test(text);hasOnlyBrTag=slLib._hasOnlyBRTag(text);this.requireDiv=hasHTMLTag&&!hasOnlyBrTag;this._updateStyle();lineHeight=this._lineHeight;context=this._context;container=this._container;sCont=this._containerObj;ellipsesWidth=sCont.ellipsesWidth;dotWidth=sCont.dotWidth;toolText=text.replace(slLib.spanAdditionRegx,"$2");getWidth=this._getWidthFn();if(lineHeight-maxHeight<=1&&lineHeight-maxHeight>=0){maxHeight*=1.2}if(canvas||container){if(!documentSupport.isBrowserLess){if(!hasHTMLTag){tmpText=text=text.replace(slLib.ltgtRegex,function(match){return match==="<"?"<":">"});getOriSizeImproveObj=this.getOriSize(tmpText,true,{hasHTMLTag:hasHTMLTag,hasOnlyBrTag:hasOnlyBrTag,cleanText:true});smartLabel.oriTextWidth=oriWidth=getOriSizeImproveObj.width;smartLabel.oriTextHeight=oriHeight=getOriSizeImproveObj.height}else if(hasOnlyBrTag){text=text.replace(slLib.brRegex,"
");dimentionObj=slLib._getDimentionOfMultiLineText(text,this);smartLabel.oriTextWidth=oriWidth=dimentionObj.width;smartLabel.oriTextHeight=oriHeight=dimentionObj.height}else{container.innerHTML=text;smartLabel.oriTextWidth=oriWidth=container.offsetWidth;smartLabel.oriTextHeight=oriHeight=container.offsetHeight}if(oriHeight<=maxHeight&&oriWidth<=maxWidth){smartLabel.width=smartLabel.oriTextWidth=oriWidth;smartLabel.height=smartLabel.oriTextHeight=oriHeight;return smartLabel}if(lineHeight>maxHeight){smartLabel.text="";smartLabel.width=smartLabel.oriTextWidth=0;smartLabel.height=smartLabel.oriTextHeight=0;return smartLabel}}text=fastTrim(text).replace(/(\s+)/g," ");maxWidthWithEll=this._showNoEllipses?maxWidth:maxWidth-ellipsesWidth;if(!hasHTMLTag||hasOnlyBrTag){oriTextArr=slLib._getTextArray(text);len=oriTextArr.length;trimStr="";tempArr=[];tempChar=oriTextArr[0];if(this._cache[tempChar]){minWidth=this._cache[tempChar].width}else{minWidth=getWidth(tempChar);this._cache[tempChar]={width:minWidth}}if(maxWidthWithEll>minWidth&&!hasOnlyBrTag){tempArr=text.substr(0,slLib.getNearestBreakIndex(text,maxWidthWithEll,this)).split("")}else if(minWidth>maxWidth){smartLabel.text="";smartLabel.width=smartLabel.oriTextWidth=smartLabel.height=smartLabel.oriTextHeight=0;return smartLabel}else if(ellipsesStr){maxWidthWithEll=maxWidth-2*dotWidth;if(maxWidthWithEll>minWidth){ellipsesStr=".."}else{maxWidthWithEll=maxWidth-dotWidth;if(maxWidthWithEll>minWidth){ellipsesStr="."}else{maxWidthWithEll=0;ellipsesStr=""}}}i=tempArr.length;strWidth=getWidth(tempArr.join(""));strHeight=this._lineHeight;if(noWrap){for(;i"){strHeight+=this._lineHeight;lastIndexBroken=i;maxStrWidth=max(maxStrWidth,strWidth);strWidth=0;trimStr=null;continue}if(this._cache[tempChar]){minWidth=this._cache[tempChar].width}else{if(!getOriSizeImproveObj||!(minWidth=getOriSizeImproveObj.detailObj[tempChar])){minWidth=getWidth(tempChar)}this._cache[tempChar]={width:minWidth}}strWidth+=minWidth;if(strWidth>maxWidthWithEll){if(!trimStr){trimStr=tempArr.slice(0,-1).join("")}if(strWidth>maxWidth){smartLabel.text=fastTrim(trimStr)+ellipsesStr;smartLabel.tooltext=smartLabel.oriText;smartLabel.width=max(maxStrWidth,strWidth);smartLabel.height=strHeight;return smartLabel}}}smartLabel.text=tempArr.join("");smartLabel.width=max(maxStrWidth,strWidth);smartLabel.height=strHeight;return smartLabel}else{for(;i"){maxStrWidth=max(maxStrWidth,strWidth);strHeight+=this._lineHeight;if(strHeight<=maxHeight){lastIndexBroken=i;strWidth=0;trimStr=null;continue}else if(strHeight>maxHeight){trimStr=tempArr.slice(0,-1).join("");smartLabel.text=fastTrim(trimStr)+ellipsesStr;smartLabel.tooltext=toolText;smartLabel.width=maxStrWidth;smartLabel.height=strHeight-this._lineHeight;return smartLabel}}if(this._cache[tempChar]){minWidth=this._cache[tempChar].width}else{if(!getOriSizeImproveObj||!(minWidth=getOriSizeImproveObj.detailObj[tempChar])){minWidth=getWidth(tempChar)}this._cache[tempChar]={width:minWidth}}strWidth+=minWidth;if(strWidth>maxWidthWithEll){if(!trimStr){trimStr=tempArr.slice(0,-1).join("")}if(strWidth>maxWidth){if(oriTextArr[i+1]==="
"){continue}lastSpace=slLib._findLastIndex(oriTextArr.slice(0,tempArr.length)," ");lastDash=slLib._findLastIndex(oriTextArr.slice(0,tempArr.length),"-");if(lastSpace>lastIndexBroken){strWidth=getWidth(tempArr.slice(lastIndexBroken+1,lastSpace).join(""));tempArr.splice(lastSpace,1,"
");lastIndexBroken=lastSpace;newCharIndex=lastSpace+1}else if(lastDash>lastIndexBroken){if(lastDash===tempArr.length-1){strWidth=getWidth(tempArr.slice(lastIndexBroken+1,lastSpace).join(""));tempArr.splice(lastDash,1,"
-")}else{strWidth=getWidth(tempArr.slice(lastIndexBroken+1,lastSpace).join(""));tempArr.splice(lastDash,1,"-
")}lastIndexBroken=lastDash;newCharIndex=lastDash+1}else{tempArr.splice(tempArr.length-1,1,"
"+oriTextArr[i]);lastLineBreak=tempArr.length-2;strWidth=getWidth(tempArr.slice(lastIndexBroken+1,lastLineBreak+1).join(""));lastIndexBroken=lastLineBreak;newCharIndex=i}strHeight+=this._lineHeight;if(strHeight>maxHeight){smartLabel.text=fastTrim(trimStr)+ellipsesStr;smartLabel.tooltext=smartLabel.oriText;smartLabel.width=maxWidth;smartLabel.height=strHeight-this._lineHeight;return smartLabel}else{maxStrWidth=max(maxStrWidth,strWidth);trimStr=null;if(!hasOnlyBrTag){nearestChar=slLib.getNearestBreakIndex(text.substr(newCharIndex),maxWidthWithEll,this);strWidth=getWidth(text.substr(newCharIndex,nearestChar||1));if(tempArr.length)/g,"$1");container.innerHTML=text;spanArr=container[documentSupport.childRetriverFn](documentSupport.childRetriverString);for(x=0,y=spanArr.length;xmaxWidth||!len){smartLabel.text="";smartLabel.width=smartLabel.oriTextWidth=smartLabel.height=smartLabel.oriTextHeight=0;return smartLabel}else if(minWidth>maxWidthWithEll&&!this._showNoEllipses){maxWidthWithEll=maxWidth-2*dotWidth;if(maxWidthWithEll>minWidth){ellipsesStr=".."}else{maxWidthWithEll=maxWidth-dotWidth;if(maxWidthWithEll>minWidth){ellipsesStr="."}else{maxWidthWithEll=0;ellipsesStr=""}}}initialLeft=characterArr[0].elem.offsetLeft;initialTop=characterArr[0].elem.offsetTop;if(noWrap){for(;imaxWidthWithEll){if(!removeFromIndexForEllipses){removeFromIndexForEllipses=i}if(container.offsetWidth>maxWidth){removeFromIndex=i;i=len}}}}else{for(;imaxWidthWithEll){if(!removeFromIndexForEllipses){removeFromIndexForEllipses=i}if(elemRightMostPoint>maxWidth){lastSpace=characterArr[i].spaceIdx;lastDash=characterArr[i].dashIdx;if(lastSpace>lastIndexBroken){characterArr[lastSpace].elem.innerHTML="
";lastIndexBroken=lastSpace}else if(lastDash>lastIndexBroken){if(lastDash===i){characterArr[lastDash].elem.innerHTML="
-"}else{characterArr[lastDash].elem.innerHTML="-
"}lastIndexBroken=lastDash}else{elem.parentNode.insertBefore(lastBR=doc.createElement("br"),elem)}if(elem.offsetHeight+elem.offsetTop>maxHeight){if(lastBR){lastBR.parentNode.removeChild(lastBR)}else if(lastIndexBroken===lastDash){characterArr[lastDash].elem.innerHTML="-"}else{characterArr[lastSpace].elem.innerHTML=" "}removeFromIndex=i;i=len}else{removeFromIndexForEllipses=null}}}else{if(elemLowestPoint>maxHeight){removeFromIndex=i;i=len}}}}if(removeFromIndex=removeFromIndexForEllipses;i-=1){elem=characterArr[i].elem;elem.parentNode.removeChild(elem)}for(;i>=0;i-=1){elem=characterArr[i].elem;if(slLib.classNameBrReg.test(elem.className)){elem.parentNode.removeChild(elem)}else{i=0}}}smartLabel.text=container.innerHTML.replace(slLib.spanRemovalRegx,"$1").replace(/\&\;/g,"&");if(smartLabel.isTruncated){smartLabel.text+=ellipsesStr;smartLabel.tooltext=toolText}}smartLabel.height=container.offsetHeight;smartLabel.width=container.offsetWidth;return smartLabel}else{smartLabel.error=new Error("Body Tag Missing!");return smartLabel}};SmartLabelManager.prototype.getOriSize=function(){var text=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"";var detailedCalculationFlag=arguments.length>1&&arguments[1]!==undefined?arguments[1]:true;var config=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};if(!this._init){return false}if(text===undefined||text===null){text=""}else if(typeof text!=="string"){text=text.toString()}var textArr,letter,lSize,i,l,cumulativeSize=0,height=0,container,indiSizeStore={},hasHTMLTag=config.hasHTMLTag,hasOnlyBrTag=config.hasOnlyBrTag;if(typeof hasHTMLTag==="undefined"){hasHTMLTag=slLib.xmlTagRegEx.test(text)||slLib.nbspRegex.test(text)}if(typeof hasOnlyBrTag==="undefined"){hasOnlyBrTag=slLib._hasOnlyBRTag(text)}this.requireDiv=hasHTMLTag&&!hasOnlyBrTag;if(!config.cleanText){text=text.replace(slLib.ltgtRegex,function(match){return match==="<"?"<":">"})}this._updateStyle();container=this._container;if(hasOnlyBrTag){return slLib._getDimentionOfMultiLineText(text,this)}if(!detailedCalculationFlag){return this._calCharDimWithCache(text)}if(hasHTMLTag){container.innerHTML=text;return{width:container.offsetWidth,height:container.offsetHeight}}textArr=text.split("");for(i=0,l=textArr.length;i/ig);return smartlabel};SmartLabelManager.prototype._calCharDimWithCache=function(){var text=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"";var calculateDifference=arguments.length>1?arguments[1]:undefined;var length=arguments.length>2?arguments[2]:undefined;if(!this._init){return false}var size,tw,twi,cachedStyle,asymmetricDifference,maxAdvancedCacheLimit=this.options.maxCacheLimit,style=this.style||{},cache,advancedCacheKey,cacheName,cacheInitName;cache=this._advancedCache=this._advancedCache||(this._advancedCache={});advancedCacheKey=this._advancedCacheKey||(this._advancedCacheKey=[]);cacheName=text+style.fontSize+style.fontFamily+style.fontWeight+style.fontStyle;cacheInitName=text+"init"+style.fontSize+style.fontFamily+style.fontWeight+style.fontStyle;if(!this.ctx&&htmlSplCharSpace[text]){text=htmlSplCharSpace[text]}if(!calculateDifference){asymmetricDifference=0}else{if((asymmetricDifference=cache[cacheInitName])===undefined){tw=this._getDimention(text.repeat?text.repeat(length):Array(length+1).join(text)).width;twi=this._getDimention(text).width;asymmetricDifference=cache[cacheInitName]=(tw-length*twi)/(length+1);advancedCacheKey.push(cacheInitName);if(advancedCacheKey.length>maxAdvancedCacheLimit){delete cache[advancedCacheKey.shift()]}}}if(cachedStyle=cache[cacheName]){return{width:cachedStyle.width,height:cachedStyle.height}}size=this._getDimention(text);size.width+=asymmetricDifference;cache[cacheName]={width:size.width,height:size.height};advancedCacheKey.push(cacheName);if(advancedCacheKey.length>maxAdvancedCacheLimit){delete cache[advancedCacheKey.shift()]}return size};SmartLabelManager.prototype._getDimention=function(text){if(this.requireDiv||!this.ctx){return slLib._getDimentionUsingDiv(text,this)}else{return slLib._getDimentionUsingCanvas(text,this)}};SmartLabelManager.prototype._getWidthFn=function(){var sl=this,contObj=sl._containerObj,svgText=contObj.svgText;if(svgText){return function(str){var bbox,width;svgText.textContent=str;bbox=svgText.getBBox();width=bbox.width-SVG_BBOX_CORRECTION;if(width<1){width=bbox.width}return width}}else{return function(str){if(sl.requireDiv||!sl.ctx){return slLib._getDimentionUsingDiv(str,sl).width}else{return slLib._getDimentionUsingCanvas(str,sl).width}}}};SmartLabelManager.prototype._isSameStyle=function(){var sl=this,oldStyle=sl.oldStyle||{},style=sl.style;if(style.fontSize!==oldStyle.fontSize||style.fontFamily!==oldStyle.fontFamily||style.fontStyle!==oldStyle.fontStyle||style.fontWeight!==oldStyle.fontWeight||style.fontVariant!==oldStyle.fontVariant){return false}return true};SmartLabelManager.prototype._setStyleOfCanvas=function(){if(this._isSameStyle()){return}var sl=this,style=sl.style,hashString,sCont,fontStyle=style.fontStyle,fontVariant=style.fontVariant,fontWeight=style.fontWeight,fontSize=style.fontSize,fontFamily=style.fontFamily;fontSize+=fontSize.indexOf("px")===-1?"px":"";hashString=fontStyle+" "+fontVariant+" "+fontWeight+" "+fontSize+" "+fontFamily;sl.ctx.font=hashString;sCont=this._containerObj=this._containerManager.get(style);if(this._containerObj){this._container=sCont.node;this._context=sCont.context;this._cache=sCont.charCache;this._lineHeight=sCont.lineHeight;this._styleNotSet=false}else{this._styleNotSet=true}sCont.ellipsesWidth=sl._calCharDimWithCache("...",false).width;sCont.dotWidth=sl._calCharDimWithCache(".",false).width;sCont.lineHeight=this._lineHeight=sCont.lineHeight||slLib._getCleanHeight(style.lineHeight);this.oldStyle=style};SmartLabelManager.prototype._setStyleOfDiv=function(){var sCont,style=this.style;this._containerObj=sCont=this._containerManager.get(style);if(!sCont.node){this._containerManager._makeDivNode(this._containerObj)}if(this._containerObj){this._container=sCont.node;this._context=sCont.context;this._cache=sCont.charCache;this._lineHeight=sCont.lineHeight;this._styleNotSet=false}else{this._styleNotSet=true}};SmartLabelManager.prototype._updateStyle=function(){return this.requireDiv||!this.ctx?this._setStyleOfDiv():this._setStyleOfCanvas()};SmartLabelManager.prototype.setStyle=function(style){this.style=slLib.parseStyle(style);slLib.setLineHeight(this.style);return this};SmartLabelManager.prototype.useEllipsesOnOverflow=function(useEllipses){if(!this._init){return this}this._showNoEllipses=!useEllipses;return this};SmartLabelManager.prototype.getSmartText=function(text,maxWidth,maxHeight,noWrap){if(!this._init){return false}if(text===undefined||text===null){text=""}else if(typeof text!=="string"){text=text.toString()}var len,trimStr,tempArr,tmpText,maxWidthWithEll,toolText,oriWidth,oriHeight,newCharIndex,nearestChar,tempChar,getWidth,initialLeft,initialTop,getOriSizeImproveObj,spanArr,x,y,minWidth,elem,chr,elemRightMostPoint,elemLowestPoint,lastBR,removeFromIndex,removeFromIndexForEllipses,hasHTMLTag=false,maxStrWidth=0,lastDash=-1,lastSpace=-1,lastIndexBroken=-1,strWidth=0,strHeight=0,oriTextArr=[],i=0,ellipsesStr=this._showNoEllipses?"":"...",lineHeight,context,container,sCont,ellipsesWidth,dotWidth,canvas=this.ctx,characterArr=[],dashIndex=-1,spaceIndex=-1,lastLineBreak=-1,hasOnlyBrTag,dimentionObj,fastTrim=function fastTrim(str){str=str.replace(/^\s\s*/,"");var ws=/\s/,i=str.length;while(ws.test(str.charAt(i-=1))){}return str.slice(0,i+1)},smartLabel={text:text,maxWidth:maxWidth,maxHeight:maxHeight,width:null,height:null,oriTextWidth:null,oriTextHeight:null,oriText:text,isTruncated:false};hasHTMLTag=slLib.xmlTagRegEx.test(text)||slLib.nbspRegex.test(text);hasOnlyBrTag=slLib._hasOnlyBRTag(text);this.requireDiv=hasHTMLTag&&!hasOnlyBrTag;this._updateStyle();lineHeight=this._lineHeight;context=this._context;container=this._container;sCont=this._containerObj;ellipsesWidth=sCont.ellipsesWidth;dotWidth=sCont.dotWidth;toolText=text.replace(slLib.spanAdditionRegx,"$2");getWidth=this._getWidthFn();if(lineHeight-maxHeight<=1&&lineHeight-maxHeight>=0){maxHeight*=1.2}if(canvas||container){if(!documentSupport.isBrowserLess){if(!hasHTMLTag){tmpText=text=text.replace(slLib.ltgtRegex,function(match){return match==="<"?"<":">"});getOriSizeImproveObj=this.getSize(tmpText,true,{hasHTMLTag:hasHTMLTag,hasOnlyBrTag:hasOnlyBrTag,cleanText:true});smartLabel.oriTextWidth=oriWidth=getOriSizeImproveObj.width;smartLabel.oriTextHeight=oriHeight=getOriSizeImproveObj.height}else if(hasOnlyBrTag){text=text.replace(slLib.brRegex,"
");dimentionObj=slLib._getDimentionOfMultiLineText(text,this);smartLabel.oriTextWidth=oriWidth=dimentionObj.width;smartLabel.oriTextHeight=oriHeight=dimentionObj.height}else{container.innerHTML=text;smartLabel.oriTextWidth=oriWidth=container.offsetWidth;smartLabel.oriTextHeight=oriHeight=container.offsetHeight}if(oriHeight<=maxHeight&&oriWidth<=maxWidth){smartLabel.width=smartLabel.oriTextWidth=oriWidth;smartLabel.height=smartLabel.oriTextHeight=oriHeight;return smartLabel}if(lineHeight>maxHeight){smartLabel.text="";smartLabel.width=smartLabel.oriTextWidth=0;smartLabel.height=smartLabel.oriTextHeight=0;return smartLabel}}text=fastTrim(text).replace(/(\s+)/g," ");maxWidthWithEll=this._showNoEllipses?maxWidth:maxWidth-ellipsesWidth;if(!hasHTMLTag||hasOnlyBrTag){oriTextArr=slLib._getTextArray(text);len=oriTextArr.length;trimStr="";tempArr=[];tempChar=oriTextArr[0];if(this._cache[tempChar]){minWidth=this._cache[tempChar].width}else{minWidth=getWidth(tempChar);this._cache[tempChar]={width:minWidth}}if(maxWidthWithEll>minWidth&&!hasOnlyBrTag){tempArr=text.substr(0,slLib.getNearestBreakIndex(text,maxWidthWithEll,this)).split("")}else if(minWidth>maxWidth){smartLabel.text="";smartLabel.width=smartLabel.oriTextWidth=smartLabel.height=smartLabel.oriTextHeight=0;return smartLabel}else if(ellipsesStr){maxWidthWithEll=maxWidth-2*dotWidth;if(maxWidthWithEll>minWidth){ellipsesStr=".."}else{maxWidthWithEll=maxWidth-dotWidth;if(maxWidthWithEll>minWidth){ellipsesStr="."}else{maxWidthWithEll=0;ellipsesStr=""}}}i=tempArr.length;strWidth=getWidth(tempArr.join(""));strHeight=this._lineHeight;if(noWrap){for(;i"){strHeight+=this._lineHeight;lastIndexBroken=i;maxStrWidth=max(maxStrWidth,strWidth);strWidth=0;trimStr=null;continue}if(this._cache[tempChar]){minWidth=this._cache[tempChar].width}else{if(!getOriSizeImproveObj||!(minWidth=getOriSizeImproveObj.detailObj[tempChar])){minWidth=getWidth(tempChar)}this._cache[tempChar]={width:minWidth}}strWidth+=minWidth;if(strWidth>maxWidthWithEll){if(!trimStr){trimStr=tempArr.slice(0,-1).join("")}if(strWidth>maxWidth){smartLabel.text=fastTrim(trimStr)+ellipsesStr;smartLabel.tooltext=smartLabel.oriText;smartLabel.width=max(maxStrWidth,strWidth);smartLabel.height=strHeight;return smartLabel}}}smartLabel.text=tempArr.join("");smartLabel.width=max(maxStrWidth,strWidth);smartLabel.height=strHeight;return smartLabel}else{for(;i"){maxStrWidth=max(maxStrWidth,strWidth);strHeight+=this._lineHeight;if(strHeight<=maxHeight){lastIndexBroken=i;strWidth=0;trimStr=null;continue}else if(strHeight>maxHeight){trimStr=tempArr.slice(0,-1).join("");smartLabel.text=fastTrim(trimStr)+ellipsesStr;smartLabel.tooltext=toolText;smartLabel.width=maxStrWidth;smartLabel.height=strHeight-this._lineHeight;return smartLabel}}if(this._cache[tempChar]){minWidth=this._cache[tempChar].width}else{if(!getOriSizeImproveObj||!(minWidth=getOriSizeImproveObj.detailObj[tempChar])){minWidth=getWidth(tempChar)}this._cache[tempChar]={width:minWidth}}strWidth+=minWidth;if(strWidth>maxWidthWithEll){if(!trimStr){trimStr=tempArr.slice(0,-1).join("")}if(strWidth>maxWidth){if(oriTextArr[i+1]==="
"){continue}lastSpace=slLib._findLastIndex(oriTextArr.slice(0,tempArr.length)," ");lastDash=slLib._findLastIndex(oriTextArr.slice(0,tempArr.length),"-");if(lastSpace>lastIndexBroken){strWidth=getWidth(tempArr.slice(lastIndexBroken+1,lastSpace).join(""));tempArr.splice(lastSpace,1,"
");lastIndexBroken=lastSpace;newCharIndex=lastSpace+1}else if(lastDash>lastIndexBroken){if(lastDash===tempArr.length-1){strWidth=getWidth(tempArr.slice(lastIndexBroken+1,lastSpace).join(""));tempArr.splice(lastDash,1,"
-")}else{strWidth=getWidth(tempArr.slice(lastIndexBroken+1,lastSpace).join(""));tempArr.splice(lastDash,1,"-
")}lastIndexBroken=lastDash;newCharIndex=lastDash+1}else{tempArr.splice(tempArr.length-1,1,"
"+oriTextArr[i]);lastLineBreak=tempArr.length-2;strWidth=getWidth(tempArr.slice(lastIndexBroken+1,lastLineBreak+1).join(""));lastIndexBroken=lastLineBreak;newCharIndex=i}strHeight+=this._lineHeight;if(strHeight>maxHeight){smartLabel.text=fastTrim(trimStr)+ellipsesStr;smartLabel.tooltext=smartLabel.oriText;smartLabel.width=maxWidth;smartLabel.height=strHeight-this._lineHeight;return smartLabel}else{maxStrWidth=max(maxStrWidth,strWidth);trimStr=null;if(!hasOnlyBrTag){nearestChar=slLib.getNearestBreakIndex(text.substr(newCharIndex),maxWidthWithEll,this);strWidth=getWidth(text.substr(newCharIndex,nearestChar||1));if(tempArr.length)/g,"$1");container.innerHTML=text;spanArr=container[documentSupport.childRetriverFn](documentSupport.childRetriverString);for(x=0,y=spanArr.length;xmaxWidth||!len){smartLabel.text="";smartLabel.width=smartLabel.oriTextWidth=smartLabel.height=smartLabel.oriTextHeight=0;return smartLabel}else if(minWidth>maxWidthWithEll&&!this._showNoEllipses){maxWidthWithEll=maxWidth-2*dotWidth;if(maxWidthWithEll>minWidth){ellipsesStr=".."}else{maxWidthWithEll=maxWidth-dotWidth;if(maxWidthWithEll>minWidth){ellipsesStr="."}else{maxWidthWithEll=0;ellipsesStr=""}}}initialLeft=characterArr[0].elem.offsetLeft;initialTop=characterArr[0].elem.offsetTop;if(noWrap){for(;imaxWidthWithEll){if(!removeFromIndexForEllipses){removeFromIndexForEllipses=i}if(container.offsetWidth>maxWidth){removeFromIndex=i;i=len}}}}else{for(;imaxWidthWithEll){if(!removeFromIndexForEllipses){removeFromIndexForEllipses=i}if(elemRightMostPoint>maxWidth){lastSpace=characterArr[i].spaceIdx;lastDash=characterArr[i].dashIdx;if(lastSpace>lastIndexBroken){characterArr[lastSpace].elem.innerHTML="
";lastIndexBroken=lastSpace}else if(lastDash>lastIndexBroken){if(lastDash===i){characterArr[lastDash].elem.innerHTML="
-"}else{characterArr[lastDash].elem.innerHTML="-
"}lastIndexBroken=lastDash}else{elem.parentNode.insertBefore(lastBR=doc.createElement("br"),elem)}if(elem.offsetHeight+elem.offsetTop>maxHeight){if(lastBR){lastBR.parentNode.removeChild(lastBR)}else if(lastIndexBroken===lastDash){characterArr[lastDash].elem.innerHTML="-"}else{characterArr[lastSpace].elem.innerHTML=" "}removeFromIndex=i;i=len}else{removeFromIndexForEllipses=null}}}else{if(elemLowestPoint>maxHeight){removeFromIndex=i;i=len}}}}if(removeFromIndex=removeFromIndexForEllipses;i-=1){elem=characterArr[i].elem;elem.parentNode.removeChild(elem)}for(;i>=0;i-=1){elem=characterArr[i].elem;if(slLib.classNameBrReg.test(elem.className)){elem.parentNode.removeChild(elem)}else{i=0}}}smartLabel.text=container.innerHTML.replace(slLib.spanRemovalRegx,"$1").replace(/\&\;/g,"&");if(smartLabel.isTruncated){smartLabel.text+=ellipsesStr;smartLabel.tooltext=toolText}}smartLabel.height=container.offsetHeight;smartLabel.width=container.offsetWidth;return smartLabel}else{smartLabel.error=new Error("Body Tag Missing!");return smartLabel}};SmartLabelManager.prototype.getSize=function(){var text=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"";var detailedCalculationFlag=arguments.length>1&&arguments[1]!==undefined?arguments[1]:true;var config=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};if(!this._init){return false}if(text===undefined||text===null){text=""}else if(typeof text!=="string"){text=text.toString()}var textArr,letter,lSize,i,l,cumulativeSize=0,height=0,container,indiSizeStore={},hasHTMLTag=config.hasHTMLTag,hasOnlyBrTag=config.hasOnlyBrTag;if(typeof hasHTMLTag==="undefined"){hasHTMLTag=slLib.xmlTagRegEx.test(text)||slLib.nbspRegex.test(text)}if(typeof hasOnlyBrTag==="undefined"){hasOnlyBrTag=slLib._hasOnlyBRTag(text)}this.requireDiv=hasHTMLTag&&!hasOnlyBrTag;if(!config.cleanText){text=text.replace(slLib.ltgtRegex,function(match){return match==="<"?"<":">"})}this._updateStyle();container=this._container;if(!detailedCalculationFlag){return this._calCharDimWithCache(text)}else{textArr=text.split("");for(i=0,l=textArr.length;i0&&arguments[0]!==undefined?arguments[0]:"";var detailedCalculationFlag=arguments.length>1&&arguments[1]!==undefined?arguments[1]:true;var config=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};return this.getSize(text,detailedCalculationFlag,config)};SmartLabelManager.prototype.dispose=function(){if(!this._init){return this}if(this._containerManager&&this._containerManager.dispose){this._containerManager.dispose()}delete this._container;delete this._context;delete this._cache;delete this._containerManager;delete this._containerObj;delete this.id;delete this.style;delete this.parentContainer;delete this._showNoEllipses;return this};export default SmartLabelManager; \ No newline at end of file diff --git a/es/lib.js b/es/lib.js index 26b328b..7a15045 100644 --- a/es/lib.js +++ b/es/lib.js @@ -1 +1 @@ -var lib={init:function init(win){var doc=win.document,nav=win.navigator,userAgent=nav.userAgent,DIV="DIV",ceil=Math.ceil,floor=Math.floor,clsNameSpace="fusioncharts-smartlabel-",containerClass=clsNameSpace+"container",classNameWithTag=clsNameSpace+"tag",classNameWithTagBR=clsNameSpace+"br";lib={win:win,containerClass:containerClass,classNameWithTag:classNameWithTag,classNameWithTagBR:classNameWithTagBR,maxDefaultCacheLimit:1000,classNameReg:/\bfusioncharts-smartlabel-tag\b/,classNameBrReg:/\bfusioncharts-smartlabel-br\b/,spanAdditionRegx:/(<[^<\>]+?\>)|(&(?:[a-z]+|#[0-9]+);|.)/ig,spanAdditionReplacer:"$1$2",spanRemovalRegx:new RegExp("\\]+?"+classNameWithTag+"[^\\>]{0,}\\>(.*?)\\<\\/span\\>","ig"),xmlTagRegEx:new RegExp("<[^>][^<]*[^>]+>","i"),brRegex:new RegExp("({br[ ]*})|()|()|()|()","g"),ltgtRegex:/<|>/g,nbspRegex:/ /g,htmlSpecialEntityRegex:/&|"|<|>/g,brReplaceRegex://ig,testStrAvg:"WgI",parentContainerStyle:{position:"absolute",top:"-9999em",whiteSpace:"nowrap",padding:"0px",width:"1px",height:"1px",overflow:"hidden"},supportedStyle:{font:"font",fontFamily:"font-family","font-family":"font-family",fontWeight:"font-weight","font-weight":"font-weight",fontSize:"font-size","font-size":"font-size",lineHeight:"line-height","line-height":"line-height",fontStyle:"font-style","font-style":"font-style"},getDocumentSupport:function getDocumentSupport(){var childRetriverFn,childRetriverString,noClassTesting;if(doc.getElementsByClassName){childRetriverFn="getElementsByClassName";childRetriverString=classNameWithTag;noClassTesting=true}else{childRetriverFn="getElementsByTagName";childRetriverString="span";noClassTesting=false}return{isIE:/msie/i.test(userAgent)&&!win.opera,hasSVG:Boolean(win.SVGAngle||doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")),isHeadLess:new RegExp(" HtmlUnit").test(userAgent),isWebKit:new RegExp(" AppleWebKit/").test(userAgent),childRetriverFn:childRetriverFn,childRetriverString:childRetriverString,noClassTesting:noClassTesting}},createContainer:function createContainer(containerParent){var body,container;if(containerParent&&(containerParent.offsetWidth||containerParent.offsetHeight)){if(containerParent.appendChild){containerParent.appendChild(container=doc.createElement(DIV));container.className=containerClass;container.setAttribute("aria-hidden","true");container.setAttribute("role","presentation");return container}}else{body=doc.getElementsByTagName("body")[0];if(body&&body.appendChild){container=doc.createElement(DIV);container.className=containerClass;container.setAttribute("aria-hidden","true");container.setAttribute("role","presentation");body.appendChild(container);return container}}},getNearestBreakIndex:function getNearestBreakIndex(text,maxWidth,sl){if(!text||!text.length){return 0}var difference,getWidth=sl._getWidthFn(),charLen=0,increment=0,oriWidth=getWidth(text),avgWidth=oriWidth/text.length;difference=maxWidth;charLen=ceil(maxWidth/avgWidth);if(oriWidthtext.length){difference=maxWidth-oriWidth;charLen=text.length}while(difference>0){difference=maxWidth-getWidth(text.substr(0,charLen));increment=floor(difference/avgWidth);if(increment){charLen+=increment}else{return charLen}}while(difference<0){difference=maxWidth-getWidth(text.substr(0,charLen));increment=floor(difference/avgWidth);if(increment){charLen+=increment}else{return charLen}}return charLen},parseStyle:function parseStyle(){var style=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};var parsedStyle={};parsedStyle.fontSize=(style.fontSize||style["font-size"]||"12px")+"";parsedStyle.fontVariant=style.fontVariant||style["font-variant"]||"normal";parsedStyle.fontWeight=style.fontWeight||style["font-weight"]||"normal";parsedStyle.fontStyle=style.fontStyle||style["font-style"]||"normal";parsedStyle.fontFamily=style.fontFamily||style["font-family"]||"Verdana,sans";return parsedStyle},setLineHeight:function setLineHeight(styleObj){var fSize=styleObj.fontSize;styleObj.lineHeight=styleObj.lineHeight||styleObj["line-height"]||parseInt(fSize,10)*1.2+"px";return styleObj},_getCleanHeight:function _getCleanHeight(height){height=height.replace(/px/g,"");return Number(height)},_getDimentionUsingDiv:function _getDimentionUsingDiv(){var text=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"";var sl=arguments.length>1?arguments[1]:undefined;var container=sl._container;if(text instanceof Array){text=text.join("")}container.innerHTML=text;return{width:container.offsetWidth,height:container.offsetHeight}},_getDimentionUsingCanvas:function _getDimentionUsingCanvas(){var text=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"";var sl=arguments.length>1?arguments[1]:undefined;var ctx=sl.ctx,style=sl.style,height=lib._getCleanHeight(style.lineHeight);if(!(text instanceof Array)){text=text.replace(/
/g,"")}else{text=text.join("");text=text.replace(/
/g,"")}return{width:ctx.measureText(text).width,height:height}},_hasOnlyBRTag:function _hasOnlyBRTag(){var input=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"";return!lib.xmlTagRegEx.test(input)&&lib.brRegex.test(input)},_getDimentionOfMultiLineText:function _getDimentionOfMultiLineText(){var rawText=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"";var sl=arguments.length>1?arguments[1]:undefined;var i,len,text=rawText.replace(lib.brRegex,"
"),textAr=lib._getTextArray(text),width=0,maxWidth=0,getWidth=sl._getWidthFn(),height=lib._getCleanHeight(sl.style.lineHeight),textHeight=height,textWidth,indiSizeStore={};for(i=0,len=textAr.length;i"){maxWidth=Math.max(maxWidth,width);width=0;textHeight+=height}else{textWidth=getWidth(textAr[i]);width+=textWidth;indiSizeStore[textAr[i]]=textWidth}}maxWidth=Math.max(maxWidth,width);return{height:textHeight,width:maxWidth,detailObj:indiSizeStore}},_getTextArray:function _getTextArray(){var text=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"";var i,j,len,tempLen,brText,tempText,finaltextAr=[];brText=text.split("
");len=brText.length;for(i=0;i")}}return finaltextAr},_findLastIndex:function _findLastIndex(){var array=arguments.length>0&&arguments[0]!==undefined?arguments[0]:[];var item=arguments.length>1?arguments[1]:undefined;var i,len=array.length;for(i=len-1;i>=0;i--){if(array[i]===item){return i}}return-1}};return lib}};export default lib; \ No newline at end of file +var lib={init:function init(win){var doc=win.document,nav=win.navigator,userAgent=nav.userAgent,DIV="DIV",ceil=Math.ceil,floor=Math.floor,clsNameSpace="fusioncharts-smartlabel-",containerClass=clsNameSpace+"container",classNameWithTag=clsNameSpace+"tag",classNameWithTagBR=clsNameSpace+"br";lib={win:win,containerClass:containerClass,classNameWithTag:classNameWithTag,classNameWithTagBR:classNameWithTagBR,maxDefaultCacheLimit:1000,classNameReg:/\bfusioncharts-smartlabel-tag\b/,classNameBrReg:/\bfusioncharts-smartlabel-br\b/,spanAdditionRegx:/(<[^<\>]+?\>)|(&(?:[a-z]+|#[0-9]+);|.)/ig,spanAdditionReplacer:"$1$2",spanRemovalRegx:new RegExp("\\]+?"+classNameWithTag+"[^\\>]{0,}\\>(.*?)\\<\\/span\\>","ig"),xmlTagRegEx:new RegExp("<[^>][^<]*[^>]+>","i"),brRegex:new RegExp("({br[ ]*})|()|()|()|()","g"),ltgtRegex:/<|>/g,nbspRegex:/ | | /g,htmlSpecialEntityRegex:/&|"|<|>/g,brReplaceRegex://ig,testStrAvg:"WgI",parentContainerStyle:{position:"absolute",top:"-9999em",whiteSpace:"nowrap",padding:"0px",width:"1px",height:"1px",overflow:"hidden"},supportedStyle:{font:"font",fontFamily:"font-family","font-family":"font-family",fontWeight:"font-weight","font-weight":"font-weight",fontSize:"font-size","font-size":"font-size",lineHeight:"line-height","line-height":"line-height",fontStyle:"font-style","font-style":"font-style"},getDocumentSupport:function getDocumentSupport(){var childRetriverFn,childRetriverString,noClassTesting;if(doc.getElementsByClassName){childRetriverFn="getElementsByClassName";childRetriverString=classNameWithTag;noClassTesting=true}else{childRetriverFn="getElementsByTagName";childRetriverString="span";noClassTesting=false}return{isIE:/msie/i.test(userAgent)&&!win.opera,hasSVG:Boolean(win.SVGAngle||doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")),isHeadLess:new RegExp(" HtmlUnit").test(userAgent),isWebKit:new RegExp(" AppleWebKit/").test(userAgent),childRetriverFn:childRetriverFn,childRetriverString:childRetriverString,noClassTesting:noClassTesting}},createContainer:function createContainer(containerParent){var body,container;if(containerParent&&(containerParent.offsetWidth||containerParent.offsetHeight)){if(containerParent.appendChild){containerParent.appendChild(container=doc.createElement(DIV));container.className=containerClass;container.setAttribute("aria-hidden","true");container.setAttribute("role","presentation");return container}}else{body=doc.getElementsByTagName("body")[0];if(body&&body.appendChild){container=doc.createElement(DIV);container.className=containerClass;container.setAttribute("aria-hidden","true");container.setAttribute("role","presentation");body.appendChild(container);return container}}},getNearestBreakIndex:function getNearestBreakIndex(text,maxWidth,sl){if(!text||!text.length){return 0}var difference,getWidth=sl._getWidthFn(),charLen=0,increment=0,oriWidth=getWidth(text),avgWidth=oriWidth/text.length;difference=maxWidth;charLen=ceil(maxWidth/avgWidth);if(oriWidthtext.length){difference=maxWidth-oriWidth;charLen=text.length}while(difference>0){difference=maxWidth-getWidth(text.substr(0,charLen));increment=floor(difference/avgWidth);if(increment){charLen+=increment}else{return charLen}}while(difference<0){difference=maxWidth-getWidth(text.substr(0,charLen));increment=floor(difference/avgWidth);if(increment){charLen+=increment}else{return charLen}}return charLen},parseStyle:function parseStyle(){var style=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};var parsedStyle={};parsedStyle.fontSize=(style.fontSize||style["font-size"]||"12px")+"";parsedStyle.fontVariant=style.fontVariant||style["font-variant"]||"normal";parsedStyle.fontWeight=style.fontWeight||style["font-weight"]||"normal";parsedStyle.fontStyle=style.fontStyle||style["font-style"]||"normal";parsedStyle.fontFamily=style.fontFamily||style["font-family"]||"Verdana,sans";return parsedStyle},setLineHeight:function setLineHeight(styleObj){var fSize=styleObj.fontSize;styleObj.lineHeight=styleObj.lineHeight||styleObj["line-height"]||parseInt(fSize,10)*1.2+"px";return styleObj},_getCleanHeight:function _getCleanHeight(height){height=height.replace(/px/g,"");return Number(height)},_getDimentionUsingDiv:function _getDimentionUsingDiv(){var text=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"";var sl=arguments.length>1?arguments[1]:undefined;var container=sl._container;if(text instanceof Array){text=text.join("")}container.innerHTML=text;return{width:container.offsetWidth,height:container.offsetHeight}},_getDimentionUsingCanvas:function _getDimentionUsingCanvas(){var text=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"";var sl=arguments.length>1?arguments[1]:undefined;var ctx=sl.ctx,style=sl.style,height=lib._getCleanHeight(style.lineHeight);if(!(text instanceof Array)){text=text.replace(/
/g,"")}else{text=text.join("");text=text.replace(/
/g,"")}return{width:ctx.measureText(text).width,height:height}},_hasOnlyBRTag:function _hasOnlyBRTag(){var input=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"";return!lib.xmlTagRegEx.test(input)&&lib.brRegex.test(input)},_getDimentionOfMultiLineText:function _getDimentionOfMultiLineText(){var rawText=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"";var sl=arguments.length>1?arguments[1]:undefined;var i,len,text=rawText.replace(lib.brRegex,"
"),textAr=lib._getTextArray(text),width=0,maxWidth=0,getWidth=sl._getWidthFn(),height=lib._getCleanHeight(sl.style.lineHeight),textHeight=height,textWidth,indiSizeStore={};for(i=0,len=textAr.length;i"){maxWidth=Math.max(maxWidth,width);width=0;textHeight+=height}else{textWidth=getWidth(textAr[i]);width+=textWidth;indiSizeStore[textAr[i]]=textWidth}}maxWidth=Math.max(maxWidth,width);return{height:textHeight,width:maxWidth,detailObj:indiSizeStore}},_getTextArray:function _getTextArray(){var text=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"";var i,j,len,tempLen,brText,tempText,finaltextAr=[];brText=text.split("
");len=brText.length;for(i=0;i")}}return finaltextAr},_findLastIndex:function _findLastIndex(){var array=arguments.length>0&&arguments[0]!==undefined?arguments[0]:[];var item=arguments.length>1?arguments[1]:undefined;var i,len=array.length;for(i=len-1;i>=0;i--){if(array[i]===item){return i}}return-1}};return lib}};export default lib; \ No newline at end of file diff --git a/src/SmartlabelManager.js b/src/SmartlabelManager.js index b997c68..4685fe0 100644 --- a/src/SmartlabelManager.js +++ b/src/SmartlabelManager.js @@ -466,7 +466,7 @@ SmartLabelManager.prototype.getSmartText = function (text, maxWidth, maxHeight, tmpText = text = text.replace(slLib.ltgtRegex, function (match) { return match === '<' ? '<' : '>'; }); - getOriSizeImproveObj = this.getOriSize(tmpText, true, { + getOriSizeImproveObj = this.getSize(tmpText, true, { hasHTMLTag: hasHTMLTag, hasOnlyBrTag: hasOnlyBrTag, cleanText: true @@ -913,7 +913,7 @@ SmartLabelManager.prototype.getSmartText = function (text, maxWidth, maxHeight, * } * If detailedCalculationFlag is set to false the returned object wont have the detailObj prop. */ -SmartLabelManager.prototype.getOriSize = function (text = '', detailedCalculationFlag = true, config = {}) { +SmartLabelManager.prototype.getSize = function (text = '', detailedCalculationFlag = true, config = {}) { if (!this._init) { return false; } @@ -951,14 +951,27 @@ SmartLabelManager.prototype.getOriSize = function (text = '', detailedCalculatio } this._updateStyle(); container = this._container; - // If text has br tag, return the width and height with proper calculations - if (hasOnlyBrTag) { - return slLib._getDimentionOfMultiLineText(text, this); - } // When text is normal text if (!detailedCalculationFlag) { return this._calCharDimWithCache(text); + } else { + // Calculate the width of every letter with an approximation + textArr = text.split(''); + for (i = 0, l = textArr.length; i < l; i++) { + letter = textArr[i]; + lSize = this._calCharDimWithCache(letter, false, textArr.length); + height = max(height, lSize.height); + cumulativeSize += lSize.width; + indiSizeStore[letter] = lSize.width; + } + } + // If text has br tag, return the width and height with proper calculations + if (hasOnlyBrTag) { + return { + ...slLib._getDimentionOfMultiLineText(text, this), + detailObj: indiSizeStore + }; } // text contains html tags other than br @@ -966,20 +979,11 @@ SmartLabelManager.prototype.getOriSize = function (text = '', detailedCalculatio container.innerHTML = text; return { width: container.offsetWidth, - height: container.offsetHeight + height: container.offsetHeight, + detailObj: indiSizeStore }; } - // Calculate the width of every letter with an approximation - textArr = text.split(''); - for (i = 0, l = textArr.length; i < l; i++) { - letter = textArr[i]; - lSize = this._calCharDimWithCache(letter, false, textArr.length); - height = max(height, lSize.height); - cumulativeSize += lSize.width; - indiSizeStore[letter] = lSize.width; - } - return { width: round(cumulativeSize), height: height, @@ -991,12 +995,8 @@ SmartLabelManager.prototype.getOriSize = function (text = '', detailedCalculatio * getOriSize API will eventually be deprecated and will be renamed to getSize API. For the next two versions, * both getOriSize and getSize API will be supported. */ -SmartLabelManager.prototype.getSize = function (text = '', detailedCalculationFlag = true, config = {}) { - if (!this._init) { - return false; - } - - return this.getOriSize(text, detailedCalculationFlag, config); +SmartLabelManager.prototype.getOriSize = function (text = '', detailedCalculationFlag = true, config = {}) { + return this.getSize(text, detailedCalculationFlag, config); }; /* * Dispose the container and object allocated by the smartlabel diff --git a/test/smartlabel-manager.js b/test/smartlabel-manager.js index 83f5e76..e41b431 100644 --- a/test/smartlabel-manager.js +++ b/test/smartlabel-manager.js @@ -16,6 +16,7 @@ describe('SmartLabel', function () { 'useEllipsesOnOverflow', 'getSmartText', 'getOriSize', + 'getSize', 'dispose' ], dirty = false; @@ -85,10 +86,10 @@ describe('SmartLabel', function () { it('sets the style properly', function () { - var sizeWOStyle = sl.getOriSize('A quick brown fox'), + var sizeWOStyle = sl.getSize('A quick brown fox'), sizeWithStyle = sl .setStyle({fontSize: '30px'}) - .getOriSize('A quick brown fox'); + .getSize('A quick brown fox'); expect(sizeWOStyle).to.not.deep.equal(sizeWithStyle); @@ -102,7 +103,7 @@ describe('SmartLabel', function () { fontSize: '20px', fontFamily: 'Verdana' }) - .getOriSize('a quick brown fox'); + .getSize('a quick brown fox'); expect(size.height).to.be.equal(24); // Error value: +-2px @@ -222,6 +223,17 @@ describe('SmartLabel', function () { expect(smarttext.lines.length).to.equal(6); }); + it('getSize API should always return detailObj', function () { + var smarttext, + present; + + smarttext = sl.getSize('AAAA'); + expect(smarttext.hasOwnProperty('detailObj')).to.equal(true); + smarttext = sl.getSize('AAA
AAA'); + expect(smarttext.hasOwnProperty('detailObj')).to.equal(true); + smarttext = sl.getSize('AAA
AAA'); + expect(smarttext.hasOwnProperty('detailObj')).to.equal(true); + }) it('removes the div when disposed', function () {