|   | 
| /* | 
| * Licensed to the Apache Software Foundation (ASF) under one | 
| * or more contributor license agreements.  See the NOTICE file | 
| * distributed with this work for additional information | 
| * regarding copyright ownership.  The ASF licenses this file | 
| * to you under the Apache License, Version 2.0 (the | 
| * "License"); you may not use this file except in compliance | 
| * with the License.  You may obtain a copy of the License at | 
| * | 
| *   http://www.apache.org/licenses/LICENSE-2.0 | 
| * | 
| * Unless required by applicable law or agreed to in writing, | 
| * software distributed under the License is distributed on an | 
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
| * KIND, either express or implied.  See the License for the | 
| * specific language governing permissions and limitations | 
| * under the License. | 
| */ | 
|   | 
|   | 
| /** | 
|  * AUTO-GENERATED FILE. DO NOT MODIFY. | 
|  */ | 
|   | 
| /* | 
| * Licensed to the Apache Software Foundation (ASF) under one | 
| * or more contributor license agreements.  See the NOTICE file | 
| * distributed with this work for additional information | 
| * regarding copyright ownership.  The ASF licenses this file | 
| * to you under the Apache License, Version 2.0 (the | 
| * "License"); you may not use this file except in compliance | 
| * with the License.  You may obtain a copy of the License at | 
| * | 
| *   http://www.apache.org/licenses/LICENSE-2.0 | 
| * | 
| * Unless required by applicable law or agreed to in writing, | 
| * software distributed under the License is distributed on an | 
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
| * KIND, either express or implied.  See the License for the | 
| * specific language governing permissions and limitations | 
| * under the License. | 
| */ | 
| import { retrieve, defaults, extend, each, isObject, map, isString, isNumber, isFunction, retrieve2 } from 'zrender/lib/core/util.js'; | 
| import * as graphic from '../../util/graphic.js'; | 
| import { getECData } from '../../util/innerStore.js'; | 
| import { createTextStyle } from '../../label/labelStyle.js'; | 
| import Model from '../../model/Model.js'; | 
| import { isRadianAroundZero, remRadian } from '../../util/number.js'; | 
| import { createSymbol, normalizeSymbolOffset } from '../../util/symbol.js'; | 
| import * as matrixUtil from 'zrender/lib/core/matrix.js'; | 
| import { applyTransform as v2ApplyTransform } from 'zrender/lib/core/vector.js'; | 
| import { shouldShowAllLabels } from '../../coord/axisHelper.js'; | 
| import { prepareLayoutList, hideOverlap } from '../../label/labelLayoutHelper.js'; | 
| var PI = Math.PI; | 
| /** | 
|  * A final axis is translated and rotated from a "standard axis". | 
|  * So opt.position and opt.rotation is required. | 
|  * | 
|  * A standard axis is and axis from [0, 0] to [0, axisExtent[1]], | 
|  * for example: (0, 0) ------------> (0, 50) | 
|  * | 
|  * nameDirection or tickDirection or labelDirection is 1 means tick | 
|  * or label is below the standard axis, whereas is -1 means above | 
|  * the standard axis. labelOffset means offset between label and axis, | 
|  * which is useful when 'onZero', where axisLabel is in the grid and | 
|  * label in outside grid. | 
|  * | 
|  * Tips: like always, | 
|  * positive rotation represents anticlockwise, and negative rotation | 
|  * represents clockwise. | 
|  * The direction of position coordinate is the same as the direction | 
|  * of screen coordinate. | 
|  * | 
|  * Do not need to consider axis 'inverse', which is auto processed by | 
|  * axis extent. | 
|  */ | 
| var AxisBuilder = /** @class */function () { | 
|   function AxisBuilder(axisModel, opt) { | 
|     this.group = new graphic.Group(); | 
|     this.opt = opt; | 
|     this.axisModel = axisModel; | 
|     // Default value | 
|     defaults(opt, { | 
|       labelOffset: 0, | 
|       nameDirection: 1, | 
|       tickDirection: 1, | 
|       labelDirection: 1, | 
|       silent: true, | 
|       handleAutoShown: function () { | 
|         return true; | 
|       } | 
|     }); | 
|     // FIXME Not use a separate text group? | 
|     var transformGroup = new graphic.Group({ | 
|       x: opt.position[0], | 
|       y: opt.position[1], | 
|       rotation: opt.rotation | 
|     }); | 
|     // this.group.add(transformGroup); | 
|     // this._transformGroup = transformGroup; | 
|     transformGroup.updateTransform(); | 
|     this._transformGroup = transformGroup; | 
|   } | 
|   AxisBuilder.prototype.hasBuilder = function (name) { | 
|     return !!builders[name]; | 
|   }; | 
|   AxisBuilder.prototype.add = function (name) { | 
|     builders[name](this.opt, this.axisModel, this.group, this._transformGroup); | 
|   }; | 
|   AxisBuilder.prototype.getGroup = function () { | 
|     return this.group; | 
|   }; | 
|   AxisBuilder.innerTextLayout = function (axisRotation, textRotation, direction) { | 
|     var rotationDiff = remRadian(textRotation - axisRotation); | 
|     var textAlign; | 
|     var textVerticalAlign; | 
|     if (isRadianAroundZero(rotationDiff)) { | 
|       // Label is parallel with axis line. | 
|       textVerticalAlign = direction > 0 ? 'top' : 'bottom'; | 
|       textAlign = 'center'; | 
|     } else if (isRadianAroundZero(rotationDiff - PI)) { | 
|       // Label is inverse parallel with axis line. | 
|       textVerticalAlign = direction > 0 ? 'bottom' : 'top'; | 
|       textAlign = 'center'; | 
|     } else { | 
|       textVerticalAlign = 'middle'; | 
|       if (rotationDiff > 0 && rotationDiff < PI) { | 
|         textAlign = direction > 0 ? 'right' : 'left'; | 
|       } else { | 
|         textAlign = direction > 0 ? 'left' : 'right'; | 
|       } | 
|     } | 
|     return { | 
|       rotation: rotationDiff, | 
|       textAlign: textAlign, | 
|       textVerticalAlign: textVerticalAlign | 
|     }; | 
|   }; | 
|   AxisBuilder.makeAxisEventDataBase = function (axisModel) { | 
|     var eventData = { | 
|       componentType: axisModel.mainType, | 
|       componentIndex: axisModel.componentIndex | 
|     }; | 
|     eventData[axisModel.mainType + 'Index'] = axisModel.componentIndex; | 
|     return eventData; | 
|   }; | 
|   AxisBuilder.isLabelSilent = function (axisModel) { | 
|     var tooltipOpt = axisModel.get('tooltip'); | 
|     return axisModel.get('silent') | 
|     // Consider mouse cursor, add these restrictions. | 
|     || !(axisModel.get('triggerEvent') || tooltipOpt && tooltipOpt.show); | 
|   }; | 
|   return AxisBuilder; | 
| }(); | 
| ; | 
| var builders = { | 
|   axisLine: function (opt, axisModel, group, transformGroup) { | 
|     var shown = axisModel.get(['axisLine', 'show']); | 
|     if (shown === 'auto' && opt.handleAutoShown) { | 
|       shown = opt.handleAutoShown('axisLine'); | 
|     } | 
|     if (!shown) { | 
|       return; | 
|     } | 
|     var extent = axisModel.axis.getExtent(); | 
|     var matrix = transformGroup.transform; | 
|     var pt1 = [extent[0], 0]; | 
|     var pt2 = [extent[1], 0]; | 
|     var inverse = pt1[0] > pt2[0]; | 
|     if (matrix) { | 
|       v2ApplyTransform(pt1, pt1, matrix); | 
|       v2ApplyTransform(pt2, pt2, matrix); | 
|     } | 
|     var lineStyle = extend({ | 
|       lineCap: 'round' | 
|     }, axisModel.getModel(['axisLine', 'lineStyle']).getLineStyle()); | 
|     var line = new graphic.Line({ | 
|       shape: { | 
|         x1: pt1[0], | 
|         y1: pt1[1], | 
|         x2: pt2[0], | 
|         y2: pt2[1] | 
|       }, | 
|       style: lineStyle, | 
|       strokeContainThreshold: opt.strokeContainThreshold || 5, | 
|       silent: true, | 
|       z2: 1 | 
|     }); | 
|     graphic.subPixelOptimizeLine(line.shape, line.style.lineWidth); | 
|     line.anid = 'line'; | 
|     group.add(line); | 
|     var arrows = axisModel.get(['axisLine', 'symbol']); | 
|     if (arrows != null) { | 
|       var arrowSize = axisModel.get(['axisLine', 'symbolSize']); | 
|       if (isString(arrows)) { | 
|         // Use the same arrow for start and end point | 
|         arrows = [arrows, arrows]; | 
|       } | 
|       if (isString(arrowSize) || isNumber(arrowSize)) { | 
|         // Use the same size for width and height | 
|         arrowSize = [arrowSize, arrowSize]; | 
|       } | 
|       var arrowOffset = normalizeSymbolOffset(axisModel.get(['axisLine', 'symbolOffset']) || 0, arrowSize); | 
|       var symbolWidth_1 = arrowSize[0]; | 
|       var symbolHeight_1 = arrowSize[1]; | 
|       each([{ | 
|         rotate: opt.rotation + Math.PI / 2, | 
|         offset: arrowOffset[0], | 
|         r: 0 | 
|       }, { | 
|         rotate: opt.rotation - Math.PI / 2, | 
|         offset: arrowOffset[1], | 
|         r: Math.sqrt((pt1[0] - pt2[0]) * (pt1[0] - pt2[0]) + (pt1[1] - pt2[1]) * (pt1[1] - pt2[1])) | 
|       }], function (point, index) { | 
|         if (arrows[index] !== 'none' && arrows[index] != null) { | 
|           var symbol = createSymbol(arrows[index], -symbolWidth_1 / 2, -symbolHeight_1 / 2, symbolWidth_1, symbolHeight_1, lineStyle.stroke, true); | 
|           // Calculate arrow position with offset | 
|           var r = point.r + point.offset; | 
|           var pt = inverse ? pt2 : pt1; | 
|           symbol.attr({ | 
|             rotation: point.rotate, | 
|             x: pt[0] + r * Math.cos(opt.rotation), | 
|             y: pt[1] - r * Math.sin(opt.rotation), | 
|             silent: true, | 
|             z2: 11 | 
|           }); | 
|           group.add(symbol); | 
|         } | 
|       }); | 
|     } | 
|   }, | 
|   axisTickLabel: function (opt, axisModel, group, transformGroup) { | 
|     var ticksEls = buildAxisMajorTicks(group, transformGroup, axisModel, opt); | 
|     var labelEls = buildAxisLabel(group, transformGroup, axisModel, opt); | 
|     fixMinMaxLabelShow(axisModel, labelEls, ticksEls); | 
|     buildAxisMinorTicks(group, transformGroup, axisModel, opt.tickDirection); | 
|     // This bit fixes the label overlap issue for the time chart. | 
|     // See https://github.com/apache/echarts/issues/14266 for more. | 
|     if (axisModel.get(['axisLabel', 'hideOverlap'])) { | 
|       var labelList = prepareLayoutList(map(labelEls, function (label) { | 
|         return { | 
|           label: label, | 
|           priority: label.z2, | 
|           defaultAttr: { | 
|             ignore: label.ignore | 
|           } | 
|         }; | 
|       })); | 
|       hideOverlap(labelList); | 
|     } | 
|   }, | 
|   axisName: function (opt, axisModel, group, transformGroup) { | 
|     var name = retrieve(opt.axisName, axisModel.get('name')); | 
|     if (!name) { | 
|       return; | 
|     } | 
|     var nameLocation = axisModel.get('nameLocation'); | 
|     var nameDirection = opt.nameDirection; | 
|     var textStyleModel = axisModel.getModel('nameTextStyle'); | 
|     var gap = axisModel.get('nameGap') || 0; | 
|     var extent = axisModel.axis.getExtent(); | 
|     var gapSignal = extent[0] > extent[1] ? -1 : 1; | 
|     var pos = [nameLocation === 'start' ? extent[0] - gapSignal * gap : nameLocation === 'end' ? extent[1] + gapSignal * gap : (extent[0] + extent[1]) / 2, | 
|     // Reuse labelOffset. | 
|     isNameLocationCenter(nameLocation) ? opt.labelOffset + nameDirection * gap : 0]; | 
|     var labelLayout; | 
|     var nameRotation = axisModel.get('nameRotate'); | 
|     if (nameRotation != null) { | 
|       nameRotation = nameRotation * PI / 180; // To radian. | 
|     } | 
|     var axisNameAvailableWidth; | 
|     if (isNameLocationCenter(nameLocation)) { | 
|       labelLayout = AxisBuilder.innerTextLayout(opt.rotation, nameRotation != null ? nameRotation : opt.rotation, | 
|       // Adapt to axis. | 
|       nameDirection); | 
|     } else { | 
|       labelLayout = endTextLayout(opt.rotation, nameLocation, nameRotation || 0, extent); | 
|       axisNameAvailableWidth = opt.axisNameAvailableWidth; | 
|       if (axisNameAvailableWidth != null) { | 
|         axisNameAvailableWidth = Math.abs(axisNameAvailableWidth / Math.sin(labelLayout.rotation)); | 
|         !isFinite(axisNameAvailableWidth) && (axisNameAvailableWidth = null); | 
|       } | 
|     } | 
|     var textFont = textStyleModel.getFont(); | 
|     var truncateOpt = axisModel.get('nameTruncate', true) || {}; | 
|     var ellipsis = truncateOpt.ellipsis; | 
|     var maxWidth = retrieve(opt.nameTruncateMaxWidth, truncateOpt.maxWidth, axisNameAvailableWidth); | 
|     var textEl = new graphic.Text({ | 
|       x: pos[0], | 
|       y: pos[1], | 
|       rotation: labelLayout.rotation, | 
|       silent: AxisBuilder.isLabelSilent(axisModel), | 
|       style: createTextStyle(textStyleModel, { | 
|         text: name, | 
|         font: textFont, | 
|         overflow: 'truncate', | 
|         width: maxWidth, | 
|         ellipsis: ellipsis, | 
|         fill: textStyleModel.getTextColor() || axisModel.get(['axisLine', 'lineStyle', 'color']), | 
|         align: textStyleModel.get('align') || labelLayout.textAlign, | 
|         verticalAlign: textStyleModel.get('verticalAlign') || labelLayout.textVerticalAlign | 
|       }), | 
|       z2: 1 | 
|     }); | 
|     graphic.setTooltipConfig({ | 
|       el: textEl, | 
|       componentModel: axisModel, | 
|       itemName: name | 
|     }); | 
|     textEl.__fullText = name; | 
|     // Id for animation | 
|     textEl.anid = 'name'; | 
|     if (axisModel.get('triggerEvent')) { | 
|       var eventData = AxisBuilder.makeAxisEventDataBase(axisModel); | 
|       eventData.targetType = 'axisName'; | 
|       eventData.name = name; | 
|       getECData(textEl).eventData = eventData; | 
|     } | 
|     // FIXME | 
|     transformGroup.add(textEl); | 
|     textEl.updateTransform(); | 
|     group.add(textEl); | 
|     textEl.decomposeTransform(); | 
|   } | 
| }; | 
| function endTextLayout(rotation, textPosition, textRotate, extent) { | 
|   var rotationDiff = remRadian(textRotate - rotation); | 
|   var textAlign; | 
|   var textVerticalAlign; | 
|   var inverse = extent[0] > extent[1]; | 
|   var onLeft = textPosition === 'start' && !inverse || textPosition !== 'start' && inverse; | 
|   if (isRadianAroundZero(rotationDiff - PI / 2)) { | 
|     textVerticalAlign = onLeft ? 'bottom' : 'top'; | 
|     textAlign = 'center'; | 
|   } else if (isRadianAroundZero(rotationDiff - PI * 1.5)) { | 
|     textVerticalAlign = onLeft ? 'top' : 'bottom'; | 
|     textAlign = 'center'; | 
|   } else { | 
|     textVerticalAlign = 'middle'; | 
|     if (rotationDiff < PI * 1.5 && rotationDiff > PI / 2) { | 
|       textAlign = onLeft ? 'left' : 'right'; | 
|     } else { | 
|       textAlign = onLeft ? 'right' : 'left'; | 
|     } | 
|   } | 
|   return { | 
|     rotation: rotationDiff, | 
|     textAlign: textAlign, | 
|     textVerticalAlign: textVerticalAlign | 
|   }; | 
| } | 
| function fixMinMaxLabelShow(axisModel, labelEls, tickEls) { | 
|   if (shouldShowAllLabels(axisModel.axis)) { | 
|     return; | 
|   } | 
|   // If min or max are user set, we need to check | 
|   // If the tick on min(max) are overlap on their neighbour tick | 
|   // If they are overlapped, we need to hide the min(max) tick label | 
|   var showMinLabel = axisModel.get(['axisLabel', 'showMinLabel']); | 
|   var showMaxLabel = axisModel.get(['axisLabel', 'showMaxLabel']); | 
|   // FIXME | 
|   // Have not consider onBand yet, where tick els is more than label els. | 
|   labelEls = labelEls || []; | 
|   tickEls = tickEls || []; | 
|   var firstLabel = labelEls[0]; | 
|   var nextLabel = labelEls[1]; | 
|   var lastLabel = labelEls[labelEls.length - 1]; | 
|   var prevLabel = labelEls[labelEls.length - 2]; | 
|   var firstTick = tickEls[0]; | 
|   var nextTick = tickEls[1]; | 
|   var lastTick = tickEls[tickEls.length - 1]; | 
|   var prevTick = tickEls[tickEls.length - 2]; | 
|   if (showMinLabel === false) { | 
|     ignoreEl(firstLabel); | 
|     ignoreEl(firstTick); | 
|   } else if (isTwoLabelOverlapped(firstLabel, nextLabel)) { | 
|     if (showMinLabel) { | 
|       ignoreEl(nextLabel); | 
|       ignoreEl(nextTick); | 
|     } else { | 
|       ignoreEl(firstLabel); | 
|       ignoreEl(firstTick); | 
|     } | 
|   } | 
|   if (showMaxLabel === false) { | 
|     ignoreEl(lastLabel); | 
|     ignoreEl(lastTick); | 
|   } else if (isTwoLabelOverlapped(prevLabel, lastLabel)) { | 
|     if (showMaxLabel) { | 
|       ignoreEl(prevLabel); | 
|       ignoreEl(prevTick); | 
|     } else { | 
|       ignoreEl(lastLabel); | 
|       ignoreEl(lastTick); | 
|     } | 
|   } | 
| } | 
| function ignoreEl(el) { | 
|   el && (el.ignore = true); | 
| } | 
| function isTwoLabelOverlapped(current, next) { | 
|   // current and next has the same rotation. | 
|   var firstRect = current && current.getBoundingRect().clone(); | 
|   var nextRect = next && next.getBoundingRect().clone(); | 
|   if (!firstRect || !nextRect) { | 
|     return; | 
|   } | 
|   // When checking intersect of two rotated labels, we use mRotationBack | 
|   // to avoid that boundingRect is enlarge when using `boundingRect.applyTransform`. | 
|   var mRotationBack = matrixUtil.identity([]); | 
|   matrixUtil.rotate(mRotationBack, mRotationBack, -current.rotation); | 
|   firstRect.applyTransform(matrixUtil.mul([], mRotationBack, current.getLocalTransform())); | 
|   nextRect.applyTransform(matrixUtil.mul([], mRotationBack, next.getLocalTransform())); | 
|   return firstRect.intersect(nextRect); | 
| } | 
| function isNameLocationCenter(nameLocation) { | 
|   return nameLocation === 'middle' || nameLocation === 'center'; | 
| } | 
| function createTicks(ticksCoords, tickTransform, tickEndCoord, tickLineStyle, anidPrefix) { | 
|   var tickEls = []; | 
|   var pt1 = []; | 
|   var pt2 = []; | 
|   for (var i = 0; i < ticksCoords.length; i++) { | 
|     var tickCoord = ticksCoords[i].coord; | 
|     pt1[0] = tickCoord; | 
|     pt1[1] = 0; | 
|     pt2[0] = tickCoord; | 
|     pt2[1] = tickEndCoord; | 
|     if (tickTransform) { | 
|       v2ApplyTransform(pt1, pt1, tickTransform); | 
|       v2ApplyTransform(pt2, pt2, tickTransform); | 
|     } | 
|     // Tick line, Not use group transform to have better line draw | 
|     var tickEl = new graphic.Line({ | 
|       shape: { | 
|         x1: pt1[0], | 
|         y1: pt1[1], | 
|         x2: pt2[0], | 
|         y2: pt2[1] | 
|       }, | 
|       style: tickLineStyle, | 
|       z2: 2, | 
|       autoBatch: true, | 
|       silent: true | 
|     }); | 
|     graphic.subPixelOptimizeLine(tickEl.shape, tickEl.style.lineWidth); | 
|     tickEl.anid = anidPrefix + '_' + ticksCoords[i].tickValue; | 
|     tickEls.push(tickEl); | 
|   } | 
|   return tickEls; | 
| } | 
| function buildAxisMajorTicks(group, transformGroup, axisModel, opt) { | 
|   var axis = axisModel.axis; | 
|   var tickModel = axisModel.getModel('axisTick'); | 
|   var shown = tickModel.get('show'); | 
|   if (shown === 'auto' && opt.handleAutoShown) { | 
|     shown = opt.handleAutoShown('axisTick'); | 
|   } | 
|   if (!shown || axis.scale.isBlank()) { | 
|     return; | 
|   } | 
|   var lineStyleModel = tickModel.getModel('lineStyle'); | 
|   var tickEndCoord = opt.tickDirection * tickModel.get('length'); | 
|   var ticksCoords = axis.getTicksCoords(); | 
|   var ticksEls = createTicks(ticksCoords, transformGroup.transform, tickEndCoord, defaults(lineStyleModel.getLineStyle(), { | 
|     stroke: axisModel.get(['axisLine', 'lineStyle', 'color']) | 
|   }), 'ticks'); | 
|   for (var i = 0; i < ticksEls.length; i++) { | 
|     group.add(ticksEls[i]); | 
|   } | 
|   return ticksEls; | 
| } | 
| function buildAxisMinorTicks(group, transformGroup, axisModel, tickDirection) { | 
|   var axis = axisModel.axis; | 
|   var minorTickModel = axisModel.getModel('minorTick'); | 
|   if (!minorTickModel.get('show') || axis.scale.isBlank()) { | 
|     return; | 
|   } | 
|   var minorTicksCoords = axis.getMinorTicksCoords(); | 
|   if (!minorTicksCoords.length) { | 
|     return; | 
|   } | 
|   var lineStyleModel = minorTickModel.getModel('lineStyle'); | 
|   var tickEndCoord = tickDirection * minorTickModel.get('length'); | 
|   var minorTickLineStyle = defaults(lineStyleModel.getLineStyle(), defaults(axisModel.getModel('axisTick').getLineStyle(), { | 
|     stroke: axisModel.get(['axisLine', 'lineStyle', 'color']) | 
|   })); | 
|   for (var i = 0; i < minorTicksCoords.length; i++) { | 
|     var minorTicksEls = createTicks(minorTicksCoords[i], transformGroup.transform, tickEndCoord, minorTickLineStyle, 'minorticks_' + i); | 
|     for (var k = 0; k < minorTicksEls.length; k++) { | 
|       group.add(minorTicksEls[k]); | 
|     } | 
|   } | 
| } | 
| function buildAxisLabel(group, transformGroup, axisModel, opt) { | 
|   var axis = axisModel.axis; | 
|   var show = retrieve(opt.axisLabelShow, axisModel.get(['axisLabel', 'show'])); | 
|   if (!show || axis.scale.isBlank()) { | 
|     return; | 
|   } | 
|   var labelModel = axisModel.getModel('axisLabel'); | 
|   var labelMargin = labelModel.get('margin'); | 
|   var labels = axis.getViewLabels(); | 
|   // Special label rotate. | 
|   var labelRotation = (retrieve(opt.labelRotate, labelModel.get('rotate')) || 0) * PI / 180; | 
|   var labelLayout = AxisBuilder.innerTextLayout(opt.rotation, labelRotation, opt.labelDirection); | 
|   var rawCategoryData = axisModel.getCategories && axisModel.getCategories(true); | 
|   var labelEls = []; | 
|   var silent = AxisBuilder.isLabelSilent(axisModel); | 
|   var triggerEvent = axisModel.get('triggerEvent'); | 
|   each(labels, function (labelItem, index) { | 
|     var tickValue = axis.scale.type === 'ordinal' ? axis.scale.getRawOrdinalNumber(labelItem.tickValue) : labelItem.tickValue; | 
|     var formattedLabel = labelItem.formattedLabel; | 
|     var rawLabel = labelItem.rawLabel; | 
|     var itemLabelModel = labelModel; | 
|     if (rawCategoryData && rawCategoryData[tickValue]) { | 
|       var rawCategoryItem = rawCategoryData[tickValue]; | 
|       if (isObject(rawCategoryItem) && rawCategoryItem.textStyle) { | 
|         itemLabelModel = new Model(rawCategoryItem.textStyle, labelModel, axisModel.ecModel); | 
|       } | 
|     } | 
|     var textColor = itemLabelModel.getTextColor() || axisModel.get(['axisLine', 'lineStyle', 'color']); | 
|     var tickCoord = axis.dataToCoord(tickValue); | 
|     var align = itemLabelModel.getShallow('align', true) || labelLayout.textAlign; | 
|     var alignMin = retrieve2(itemLabelModel.getShallow('alignMinLabel', true), align); | 
|     var alignMax = retrieve2(itemLabelModel.getShallow('alignMaxLabel', true), align); | 
|     var verticalAlign = itemLabelModel.getShallow('verticalAlign', true) || itemLabelModel.getShallow('baseline', true) || labelLayout.textVerticalAlign; | 
|     var verticalAlignMin = retrieve2(itemLabelModel.getShallow('verticalAlignMinLabel', true), verticalAlign); | 
|     var verticalAlignMax = retrieve2(itemLabelModel.getShallow('verticalAlignMaxLabel', true), verticalAlign); | 
|     var textEl = new graphic.Text({ | 
|       x: tickCoord, | 
|       y: opt.labelOffset + opt.labelDirection * labelMargin, | 
|       rotation: labelLayout.rotation, | 
|       silent: silent, | 
|       z2: 10 + (labelItem.level || 0), | 
|       style: createTextStyle(itemLabelModel, { | 
|         text: formattedLabel, | 
|         align: index === 0 ? alignMin : index === labels.length - 1 ? alignMax : align, | 
|         verticalAlign: index === 0 ? verticalAlignMin : index === labels.length - 1 ? verticalAlignMax : verticalAlign, | 
|         fill: isFunction(textColor) ? textColor( | 
|         // (1) In category axis with data zoom, tick is not the original | 
|         // index of axis.data. So tick should not be exposed to user | 
|         // in category axis. | 
|         // (2) Compatible with previous version, which always use formatted label as | 
|         // input. But in interval scale the formatted label is like '223,445', which | 
|         // maked user replace ','. So we modify it to return original val but remain | 
|         // it as 'string' to avoid error in replacing. | 
|         axis.type === 'category' ? rawLabel : axis.type === 'value' ? tickValue + '' : tickValue, index) : textColor | 
|       }) | 
|     }); | 
|     textEl.anid = 'label_' + tickValue; | 
|     graphic.setTooltipConfig({ | 
|       el: textEl, | 
|       componentModel: axisModel, | 
|       itemName: formattedLabel, | 
|       formatterParamsExtra: { | 
|         isTruncated: function () { | 
|           return textEl.isTruncated; | 
|         }, | 
|         value: rawLabel, | 
|         tickIndex: index | 
|       } | 
|     }); | 
|     // Pack data for mouse event | 
|     if (triggerEvent) { | 
|       var eventData = AxisBuilder.makeAxisEventDataBase(axisModel); | 
|       eventData.targetType = 'axisLabel'; | 
|       eventData.value = rawLabel; | 
|       eventData.tickIndex = index; | 
|       if (axis.type === 'category') { | 
|         eventData.dataIndex = tickValue; | 
|       } | 
|       getECData(textEl).eventData = eventData; | 
|     } | 
|     // FIXME | 
|     transformGroup.add(textEl); | 
|     textEl.updateTransform(); | 
|     labelEls.push(textEl); | 
|     group.add(textEl); | 
|     textEl.decomposeTransform(); | 
|   }); | 
|   return labelEls; | 
| } | 
| export default AxisBuilder; |