|   | 
| /* | 
| * 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 ZRText from 'zrender/lib/graphic/Text.js'; | 
| import { isFunction, retrieve2, extend, keys, trim } from 'zrender/lib/core/util.js'; | 
| import { SPECIAL_STATES, DISPLAY_STATES } from '../util/states.js'; | 
| import { deprecateReplaceLog } from '../util/log.js'; | 
| import { makeInner, interpolateRawValues } from '../util/model.js'; | 
| import { initProps, updateProps } from '../util/graphic.js'; | 
| var EMPTY_OBJ = {}; | 
| export function setLabelText(label, labelTexts) { | 
|   for (var i = 0; i < SPECIAL_STATES.length; i++) { | 
|     var stateName = SPECIAL_STATES[i]; | 
|     var text = labelTexts[stateName]; | 
|     var state = label.ensureState(stateName); | 
|     state.style = state.style || {}; | 
|     state.style.text = text; | 
|   } | 
|   var oldStates = label.currentStates.slice(); | 
|   label.clearStates(true); | 
|   label.setStyle({ | 
|     text: labelTexts.normal | 
|   }); | 
|   label.useStates(oldStates, true); | 
| } | 
| function getLabelText(opt, stateModels, interpolatedValue) { | 
|   var labelFetcher = opt.labelFetcher; | 
|   var labelDataIndex = opt.labelDataIndex; | 
|   var labelDimIndex = opt.labelDimIndex; | 
|   var normalModel = stateModels.normal; | 
|   var baseText; | 
|   if (labelFetcher) { | 
|     baseText = labelFetcher.getFormattedLabel(labelDataIndex, 'normal', null, labelDimIndex, normalModel && normalModel.get('formatter'), interpolatedValue != null ? { | 
|       interpolatedValue: interpolatedValue | 
|     } : null); | 
|   } | 
|   if (baseText == null) { | 
|     baseText = isFunction(opt.defaultText) ? opt.defaultText(labelDataIndex, opt, interpolatedValue) : opt.defaultText; | 
|   } | 
|   var statesText = { | 
|     normal: baseText | 
|   }; | 
|   for (var i = 0; i < SPECIAL_STATES.length; i++) { | 
|     var stateName = SPECIAL_STATES[i]; | 
|     var stateModel = stateModels[stateName]; | 
|     statesText[stateName] = retrieve2(labelFetcher ? labelFetcher.getFormattedLabel(labelDataIndex, stateName, null, labelDimIndex, stateModel && stateModel.get('formatter')) : null, baseText); | 
|   } | 
|   return statesText; | 
| } | 
| function setLabelStyle(targetEl, labelStatesModels, opt, stateSpecified | 
| // TODO specified position? | 
| ) { | 
|   opt = opt || EMPTY_OBJ; | 
|   var isSetOnText = targetEl instanceof ZRText; | 
|   var needsCreateText = false; | 
|   for (var i = 0; i < DISPLAY_STATES.length; i++) { | 
|     var stateModel = labelStatesModels[DISPLAY_STATES[i]]; | 
|     if (stateModel && stateModel.getShallow('show')) { | 
|       needsCreateText = true; | 
|       break; | 
|     } | 
|   } | 
|   var textContent = isSetOnText ? targetEl : targetEl.getTextContent(); | 
|   if (needsCreateText) { | 
|     if (!isSetOnText) { | 
|       // Reuse the previous | 
|       if (!textContent) { | 
|         textContent = new ZRText(); | 
|         targetEl.setTextContent(textContent); | 
|       } | 
|       // Use same state proxy | 
|       if (targetEl.stateProxy) { | 
|         textContent.stateProxy = targetEl.stateProxy; | 
|       } | 
|     } | 
|     var labelStatesTexts = getLabelText(opt, labelStatesModels); | 
|     var normalModel = labelStatesModels.normal; | 
|     var showNormal = !!normalModel.getShallow('show'); | 
|     var normalStyle = createTextStyle(normalModel, stateSpecified && stateSpecified.normal, opt, false, !isSetOnText); | 
|     normalStyle.text = labelStatesTexts.normal; | 
|     if (!isSetOnText) { | 
|       // Always create new | 
|       targetEl.setTextConfig(createTextConfig(normalModel, opt, false)); | 
|     } | 
|     for (var i = 0; i < SPECIAL_STATES.length; i++) { | 
|       var stateName = SPECIAL_STATES[i]; | 
|       var stateModel = labelStatesModels[stateName]; | 
|       if (stateModel) { | 
|         var stateObj = textContent.ensureState(stateName); | 
|         var stateShow = !!retrieve2(stateModel.getShallow('show'), showNormal); | 
|         if (stateShow !== showNormal) { | 
|           stateObj.ignore = !stateShow; | 
|         } | 
|         stateObj.style = createTextStyle(stateModel, stateSpecified && stateSpecified[stateName], opt, true, !isSetOnText); | 
|         stateObj.style.text = labelStatesTexts[stateName]; | 
|         if (!isSetOnText) { | 
|           var targetElEmphasisState = targetEl.ensureState(stateName); | 
|           targetElEmphasisState.textConfig = createTextConfig(stateModel, opt, true); | 
|         } | 
|       } | 
|     } | 
|     // PENDING: if there is many requirements that emphasis position | 
|     // need to be different from normal position, we might consider | 
|     // auto silent is those cases. | 
|     textContent.silent = !!normalModel.getShallow('silent'); | 
|     // Keep x and y | 
|     if (textContent.style.x != null) { | 
|       normalStyle.x = textContent.style.x; | 
|     } | 
|     if (textContent.style.y != null) { | 
|       normalStyle.y = textContent.style.y; | 
|     } | 
|     textContent.ignore = !showNormal; | 
|     // Always create new style. | 
|     textContent.useStyle(normalStyle); | 
|     textContent.dirty(); | 
|     if (opt.enableTextSetter) { | 
|       labelInner(textContent).setLabelText = function (interpolatedValue) { | 
|         var labelStatesTexts = getLabelText(opt, labelStatesModels, interpolatedValue); | 
|         setLabelText(textContent, labelStatesTexts); | 
|       }; | 
|     } | 
|   } else if (textContent) { | 
|     // Not display rich text. | 
|     textContent.ignore = true; | 
|   } | 
|   targetEl.dirty(); | 
| } | 
| export { setLabelStyle }; | 
| export function getLabelStatesModels(itemModel, labelName) { | 
|   labelName = labelName || 'label'; | 
|   var statesModels = { | 
|     normal: itemModel.getModel(labelName) | 
|   }; | 
|   for (var i = 0; i < SPECIAL_STATES.length; i++) { | 
|     var stateName = SPECIAL_STATES[i]; | 
|     statesModels[stateName] = itemModel.getModel([stateName, labelName]); | 
|   } | 
|   return statesModels; | 
| } | 
| /** | 
|  * Set basic textStyle properties. | 
|  */ | 
| export function createTextStyle(textStyleModel, specifiedTextStyle, | 
| // Fixed style in the code. Can't be set by model. | 
| opt, isNotNormal, isAttached // If text is attached on an element. If so, auto color will handling in zrender. | 
| ) { | 
|   var textStyle = {}; | 
|   setTextStyleCommon(textStyle, textStyleModel, opt, isNotNormal, isAttached); | 
|   specifiedTextStyle && extend(textStyle, specifiedTextStyle); | 
|   // textStyle.host && textStyle.host.dirty && textStyle.host.dirty(false); | 
|   return textStyle; | 
| } | 
| export function createTextConfig(textStyleModel, opt, isNotNormal) { | 
|   opt = opt || {}; | 
|   var textConfig = {}; | 
|   var labelPosition; | 
|   var labelRotate = textStyleModel.getShallow('rotate'); | 
|   var labelDistance = retrieve2(textStyleModel.getShallow('distance'), isNotNormal ? null : 5); | 
|   var labelOffset = textStyleModel.getShallow('offset'); | 
|   labelPosition = textStyleModel.getShallow('position') || (isNotNormal ? null : 'inside'); | 
|   // 'outside' is not a valid zr textPostion value, but used | 
|   // in bar series, and magric type should be considered. | 
|   labelPosition === 'outside' && (labelPosition = opt.defaultOutsidePosition || 'top'); | 
|   if (labelPosition != null) { | 
|     textConfig.position = labelPosition; | 
|   } | 
|   if (labelOffset != null) { | 
|     textConfig.offset = labelOffset; | 
|   } | 
|   if (labelRotate != null) { | 
|     labelRotate *= Math.PI / 180; | 
|     textConfig.rotation = labelRotate; | 
|   } | 
|   if (labelDistance != null) { | 
|     textConfig.distance = labelDistance; | 
|   } | 
|   // fill and auto is determined by the color of path fill if it's not specified by developers. | 
|   textConfig.outsideFill = textStyleModel.get('color') === 'inherit' ? opt.inheritColor || null : 'auto'; | 
|   return textConfig; | 
| } | 
| /** | 
|  * The uniform entry of set text style, that is, retrieve style definitions | 
|  * from `model` and set to `textStyle` object. | 
|  * | 
|  * Never in merge mode, but in overwrite mode, that is, all of the text style | 
|  * properties will be set. (Consider the states of normal and emphasis and | 
|  * default value can be adopted, merge would make the logic too complicated | 
|  * to manage.) | 
|  */ | 
| function setTextStyleCommon(textStyle, textStyleModel, opt, isNotNormal, isAttached) { | 
|   // Consider there will be abnormal when merge hover style to normal style if given default value. | 
|   opt = opt || EMPTY_OBJ; | 
|   var ecModel = textStyleModel.ecModel; | 
|   var globalTextStyle = ecModel && ecModel.option.textStyle; | 
|   // Consider case: | 
|   // { | 
|   //     data: [{ | 
|   //         value: 12, | 
|   //         label: { | 
|   //             rich: { | 
|   //                 // no 'a' here but using parent 'a'. | 
|   //             } | 
|   //         } | 
|   //     }], | 
|   //     rich: { | 
|   //         a: { ... } | 
|   //     } | 
|   // } | 
|   var richItemNames = getRichItemNames(textStyleModel); | 
|   var richResult; | 
|   if (richItemNames) { | 
|     richResult = {}; | 
|     for (var name_1 in richItemNames) { | 
|       if (richItemNames.hasOwnProperty(name_1)) { | 
|         // Cascade is supported in rich. | 
|         var richTextStyle = textStyleModel.getModel(['rich', name_1]); | 
|         // In rich, never `disableBox`. | 
|         // FIXME: consider `label: {formatter: '{a|xx}', color: 'blue', rich: {a: {}}}`, | 
|         // the default color `'blue'` will not be adopted if no color declared in `rich`. | 
|         // That might confuses users. So probably we should put `textStyleModel` as the | 
|         // root ancestor of the `richTextStyle`. But that would be a break change. | 
|         setTokenTextStyle(richResult[name_1] = {}, richTextStyle, globalTextStyle, opt, isNotNormal, isAttached, false, true); | 
|       } | 
|     } | 
|   } | 
|   if (richResult) { | 
|     textStyle.rich = richResult; | 
|   } | 
|   var overflow = textStyleModel.get('overflow'); | 
|   if (overflow) { | 
|     textStyle.overflow = overflow; | 
|   } | 
|   var margin = textStyleModel.get('minMargin'); | 
|   if (margin != null) { | 
|     textStyle.margin = margin; | 
|   } | 
|   setTokenTextStyle(textStyle, textStyleModel, globalTextStyle, opt, isNotNormal, isAttached, true, false); | 
| } | 
| // Consider case: | 
| // { | 
| //     data: [{ | 
| //         value: 12, | 
| //         label: { | 
| //             rich: { | 
| //                 // no 'a' here but using parent 'a'. | 
| //             } | 
| //         } | 
| //     }], | 
| //     rich: { | 
| //         a: { ... } | 
| //     } | 
| // } | 
| // TODO TextStyleModel | 
| function getRichItemNames(textStyleModel) { | 
|   // Use object to remove duplicated names. | 
|   var richItemNameMap; | 
|   while (textStyleModel && textStyleModel !== textStyleModel.ecModel) { | 
|     var rich = (textStyleModel.option || EMPTY_OBJ).rich; | 
|     if (rich) { | 
|       richItemNameMap = richItemNameMap || {}; | 
|       var richKeys = keys(rich); | 
|       for (var i = 0; i < richKeys.length; i++) { | 
|         var richKey = richKeys[i]; | 
|         richItemNameMap[richKey] = 1; | 
|       } | 
|     } | 
|     textStyleModel = textStyleModel.parentModel; | 
|   } | 
|   return richItemNameMap; | 
| } | 
| var TEXT_PROPS_WITH_GLOBAL = ['fontStyle', 'fontWeight', 'fontSize', 'fontFamily', 'textShadowColor', 'textShadowBlur', 'textShadowOffsetX', 'textShadowOffsetY']; | 
| var TEXT_PROPS_SELF = ['align', 'lineHeight', 'width', 'height', 'tag', 'verticalAlign', 'ellipsis']; | 
| var TEXT_PROPS_BOX = ['padding', 'borderWidth', 'borderRadius', 'borderDashOffset', 'backgroundColor', 'borderColor', 'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY']; | 
| function setTokenTextStyle(textStyle, textStyleModel, globalTextStyle, opt, isNotNormal, isAttached, isBlock, inRich) { | 
|   // In merge mode, default value should not be given. | 
|   globalTextStyle = !isNotNormal && globalTextStyle || EMPTY_OBJ; | 
|   var inheritColor = opt && opt.inheritColor; | 
|   var fillColor = textStyleModel.getShallow('color'); | 
|   var strokeColor = textStyleModel.getShallow('textBorderColor'); | 
|   var opacity = retrieve2(textStyleModel.getShallow('opacity'), globalTextStyle.opacity); | 
|   if (fillColor === 'inherit' || fillColor === 'auto') { | 
|     if (process.env.NODE_ENV !== 'production') { | 
|       if (fillColor === 'auto') { | 
|         deprecateReplaceLog('color: \'auto\'', 'color: \'inherit\''); | 
|       } | 
|     } | 
|     if (inheritColor) { | 
|       fillColor = inheritColor; | 
|     } else { | 
|       fillColor = null; | 
|     } | 
|   } | 
|   if (strokeColor === 'inherit' || strokeColor === 'auto') { | 
|     if (process.env.NODE_ENV !== 'production') { | 
|       if (strokeColor === 'auto') { | 
|         deprecateReplaceLog('color: \'auto\'', 'color: \'inherit\''); | 
|       } | 
|     } | 
|     if (inheritColor) { | 
|       strokeColor = inheritColor; | 
|     } else { | 
|       strokeColor = null; | 
|     } | 
|   } | 
|   if (!isAttached) { | 
|     // Only use default global textStyle.color if text is individual. | 
|     // Otherwise it will use the strategy of attached text color because text may be on a path. | 
|     fillColor = fillColor || globalTextStyle.color; | 
|     strokeColor = strokeColor || globalTextStyle.textBorderColor; | 
|   } | 
|   if (fillColor != null) { | 
|     textStyle.fill = fillColor; | 
|   } | 
|   if (strokeColor != null) { | 
|     textStyle.stroke = strokeColor; | 
|   } | 
|   var textBorderWidth = retrieve2(textStyleModel.getShallow('textBorderWidth'), globalTextStyle.textBorderWidth); | 
|   if (textBorderWidth != null) { | 
|     textStyle.lineWidth = textBorderWidth; | 
|   } | 
|   var textBorderType = retrieve2(textStyleModel.getShallow('textBorderType'), globalTextStyle.textBorderType); | 
|   if (textBorderType != null) { | 
|     textStyle.lineDash = textBorderType; | 
|   } | 
|   var textBorderDashOffset = retrieve2(textStyleModel.getShallow('textBorderDashOffset'), globalTextStyle.textBorderDashOffset); | 
|   if (textBorderDashOffset != null) { | 
|     textStyle.lineDashOffset = textBorderDashOffset; | 
|   } | 
|   if (!isNotNormal && opacity == null && !inRich) { | 
|     opacity = opt && opt.defaultOpacity; | 
|   } | 
|   if (opacity != null) { | 
|     textStyle.opacity = opacity; | 
|   } | 
|   // TODO | 
|   if (!isNotNormal && !isAttached) { | 
|     // Set default finally. | 
|     if (textStyle.fill == null && opt.inheritColor) { | 
|       textStyle.fill = opt.inheritColor; | 
|     } | 
|   } | 
|   // Do not use `getFont` here, because merge should be supported, where | 
|   // part of these properties may be changed in emphasis style, and the | 
|   // others should remain their original value got from normal style. | 
|   for (var i = 0; i < TEXT_PROPS_WITH_GLOBAL.length; i++) { | 
|     var key = TEXT_PROPS_WITH_GLOBAL[i]; | 
|     var val = retrieve2(textStyleModel.getShallow(key), globalTextStyle[key]); | 
|     if (val != null) { | 
|       textStyle[key] = val; | 
|     } | 
|   } | 
|   for (var i = 0; i < TEXT_PROPS_SELF.length; i++) { | 
|     var key = TEXT_PROPS_SELF[i]; | 
|     var val = textStyleModel.getShallow(key); | 
|     if (val != null) { | 
|       textStyle[key] = val; | 
|     } | 
|   } | 
|   if (textStyle.verticalAlign == null) { | 
|     var baseline = textStyleModel.getShallow('baseline'); | 
|     if (baseline != null) { | 
|       textStyle.verticalAlign = baseline; | 
|     } | 
|   } | 
|   if (!isBlock || !opt.disableBox) { | 
|     for (var i = 0; i < TEXT_PROPS_BOX.length; i++) { | 
|       var key = TEXT_PROPS_BOX[i]; | 
|       var val = textStyleModel.getShallow(key); | 
|       if (val != null) { | 
|         textStyle[key] = val; | 
|       } | 
|     } | 
|     var borderType = textStyleModel.getShallow('borderType'); | 
|     if (borderType != null) { | 
|       textStyle.borderDash = borderType; | 
|     } | 
|     if ((textStyle.backgroundColor === 'auto' || textStyle.backgroundColor === 'inherit') && inheritColor) { | 
|       if (process.env.NODE_ENV !== 'production') { | 
|         if (textStyle.backgroundColor === 'auto') { | 
|           deprecateReplaceLog('backgroundColor: \'auto\'', 'backgroundColor: \'inherit\''); | 
|         } | 
|       } | 
|       textStyle.backgroundColor = inheritColor; | 
|     } | 
|     if ((textStyle.borderColor === 'auto' || textStyle.borderColor === 'inherit') && inheritColor) { | 
|       if (process.env.NODE_ENV !== 'production') { | 
|         if (textStyle.borderColor === 'auto') { | 
|           deprecateReplaceLog('borderColor: \'auto\'', 'borderColor: \'inherit\''); | 
|         } | 
|       } | 
|       textStyle.borderColor = inheritColor; | 
|     } | 
|   } | 
| } | 
| export function getFont(opt, ecModel) { | 
|   var gTextStyleModel = ecModel && ecModel.getModel('textStyle'); | 
|   return trim([ | 
|   // FIXME in node-canvas fontWeight is before fontStyle | 
|   opt.fontStyle || gTextStyleModel && gTextStyleModel.getShallow('fontStyle') || '', opt.fontWeight || gTextStyleModel && gTextStyleModel.getShallow('fontWeight') || '', (opt.fontSize || gTextStyleModel && gTextStyleModel.getShallow('fontSize') || 12) + 'px', opt.fontFamily || gTextStyleModel && gTextStyleModel.getShallow('fontFamily') || 'sans-serif'].join(' ')); | 
| } | 
| export var labelInner = makeInner(); | 
| export function setLabelValueAnimation(label, labelStatesModels, value, getDefaultText) { | 
|   if (!label) { | 
|     return; | 
|   } | 
|   var obj = labelInner(label); | 
|   obj.prevValue = obj.value; | 
|   obj.value = value; | 
|   var normalLabelModel = labelStatesModels.normal; | 
|   obj.valueAnimation = normalLabelModel.get('valueAnimation'); | 
|   if (obj.valueAnimation) { | 
|     obj.precision = normalLabelModel.get('precision'); | 
|     obj.defaultInterpolatedText = getDefaultText; | 
|     obj.statesModels = labelStatesModels; | 
|   } | 
| } | 
| export function animateLabelValue(textEl, dataIndex, data, animatableModel, labelFetcher) { | 
|   var labelInnerStore = labelInner(textEl); | 
|   if (!labelInnerStore.valueAnimation || labelInnerStore.prevValue === labelInnerStore.value) { | 
|     // Value not changed, no new label animation | 
|     return; | 
|   } | 
|   var defaultInterpolatedText = labelInnerStore.defaultInterpolatedText; | 
|   // Consider the case that being animating, do not use the `obj.value`, | 
|   // Otherwise it will jump to the `obj.value` when this new animation started. | 
|   var currValue = retrieve2(labelInnerStore.interpolatedValue, labelInnerStore.prevValue); | 
|   var targetValue = labelInnerStore.value; | 
|   function during(percent) { | 
|     var interpolated = interpolateRawValues(data, labelInnerStore.precision, currValue, targetValue, percent); | 
|     labelInnerStore.interpolatedValue = percent === 1 ? null : interpolated; | 
|     var labelText = getLabelText({ | 
|       labelDataIndex: dataIndex, | 
|       labelFetcher: labelFetcher, | 
|       defaultText: defaultInterpolatedText ? defaultInterpolatedText(interpolated) : interpolated + '' | 
|     }, labelInnerStore.statesModels, interpolated); | 
|     setLabelText(textEl, labelText); | 
|   } | 
|   textEl.percent = 0; | 
|   (labelInnerStore.prevValue == null ? initProps : updateProps)(textEl, { | 
|     // percent is used to prevent animation from being aborted #15916 | 
|     percent: 1 | 
|   }, animatableModel, dataIndex, null, during); | 
| } |