* Returns {width, height, offset} objects for the first, last, widest, highest tick * labels where offset indicates the anchor point offset from the top in pixels. * @return {{ first: object, last: object, widest: object, highest: object, widths: Array, heights: array }} * @private
(ticks, length, maxTicksLimit)
| 817 | * @private |
| 818 | */ |
| 819 | _computeLabelSizes(ticks, length, maxTicksLimit) { |
| 820 | const {ctx, _longestTextCache: caches} = this; |
| 821 | const widths = []; |
| 822 | const heights = []; |
| 823 | const increment = Math.floor(length / getTicksLimit(length, maxTicksLimit)); |
| 824 | let widestLabelSize = 0; |
| 825 | let highestLabelSize = 0; |
| 826 | let i, j, jlen, label, tickFont, fontString, cache, lineHeight, width, height, nestedLabel; |
| 827 | |
| 828 | for (i = 0; i < length; i += increment) { |
| 829 | label = ticks[i].label; |
| 830 | tickFont = this._resolveTickFontOptions(i); |
| 831 | ctx.font = fontString = tickFont.string; |
| 832 | cache = caches[fontString] = caches[fontString] || {data: {}, gc: []}; |
| 833 | lineHeight = tickFont.lineHeight; |
| 834 | width = height = 0; |
| 835 | // Undefined labels and arrays should not be measured |
| 836 | if (!isNullOrUndef(label) && !isArray(label)) { |
| 837 | width = _measureText(ctx, cache.data, cache.gc, width, label); |
| 838 | height = lineHeight; |
| 839 | } else if (isArray(label)) { |
| 840 | // if it is an array let's measure each element |
| 841 | for (j = 0, jlen = label.length; j < jlen; ++j) { |
| 842 | nestedLabel = /** @type {string} */ (label[j]); |
| 843 | // Undefined labels and arrays should not be measured |
| 844 | if (!isNullOrUndef(nestedLabel) && !isArray(nestedLabel)) { |
| 845 | width = _measureText(ctx, cache.data, cache.gc, width, nestedLabel); |
| 846 | height += lineHeight; |
| 847 | } |
| 848 | } |
| 849 | } |
| 850 | widths.push(width); |
| 851 | heights.push(height); |
| 852 | widestLabelSize = Math.max(width, widestLabelSize); |
| 853 | highestLabelSize = Math.max(height, highestLabelSize); |
| 854 | } |
| 855 | garbageCollect(caches, length); |
| 856 | |
| 857 | const widest = widths.indexOf(widestLabelSize); |
| 858 | const highest = heights.indexOf(highestLabelSize); |
| 859 | |
| 860 | const valueAt = (idx) => ({width: widths[idx] || 0, height: heights[idx] || 0}); |
| 861 | |
| 862 | return { |
| 863 | first: valueAt(0), |
| 864 | last: valueAt(length - 1), |
| 865 | widest: valueAt(widest), |
| 866 | highest: valueAt(highest), |
| 867 | widths, |
| 868 | heights, |
| 869 | }; |
| 870 | } |
| 871 | |
| 872 | /** |
| 873 | * Used to get the label to display in the tooltip for the given value |
no test coverage detected