| 
/* 
 | 
* 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 { __extends } from "tslib"; 
 | 
import BoundingRect from 'zrender/lib/core/BoundingRect.js'; 
 | 
import * as matrix from 'zrender/lib/core/matrix.js'; 
 | 
import * as graphic from '../../util/graphic.js'; 
 | 
import { createTextStyle } from '../../label/labelStyle.js'; 
 | 
import * as layout from '../../util/layout.js'; 
 | 
import TimelineView from './TimelineView.js'; 
 | 
import TimelineAxis from './TimelineAxis.js'; 
 | 
import { createSymbol, normalizeSymbolOffset, normalizeSymbolSize } from '../../util/symbol.js'; 
 | 
import * as numberUtil from '../../util/number.js'; 
 | 
import { merge, each, extend, isString, bind, defaults, retrieve2 } from 'zrender/lib/core/util.js'; 
 | 
import OrdinalScale from '../../scale/Ordinal.js'; 
 | 
import TimeScale from '../../scale/Time.js'; 
 | 
import IntervalScale from '../../scale/Interval.js'; 
 | 
import { parsePercent } from 'zrender/lib/contain/text.js'; 
 | 
import { makeInner } from '../../util/model.js'; 
 | 
import { getECData } from '../../util/innerStore.js'; 
 | 
import { enableHoverEmphasis } from '../../util/states.js'; 
 | 
import { createTooltipMarkup } from '../tooltip/tooltipMarkup.js'; 
 | 
var PI = Math.PI; 
 | 
var labelDataIndexStore = makeInner(); 
 | 
var SliderTimelineView = /** @class */function (_super) { 
 | 
  __extends(SliderTimelineView, _super); 
 | 
  function SliderTimelineView() { 
 | 
    var _this = _super !== null && _super.apply(this, arguments) || this; 
 | 
    _this.type = SliderTimelineView.type; 
 | 
    return _this; 
 | 
  } 
 | 
  SliderTimelineView.prototype.init = function (ecModel, api) { 
 | 
    this.api = api; 
 | 
  }; 
 | 
  /** 
 | 
   * @override 
 | 
   */ 
 | 
  SliderTimelineView.prototype.render = function (timelineModel, ecModel, api) { 
 | 
    this.model = timelineModel; 
 | 
    this.api = api; 
 | 
    this.ecModel = ecModel; 
 | 
    this.group.removeAll(); 
 | 
    if (timelineModel.get('show', true)) { 
 | 
      var layoutInfo_1 = this._layout(timelineModel, api); 
 | 
      var mainGroup_1 = this._createGroup('_mainGroup'); 
 | 
      var labelGroup = this._createGroup('_labelGroup'); 
 | 
      var axis_1 = this._axis = this._createAxis(layoutInfo_1, timelineModel); 
 | 
      timelineModel.formatTooltip = function (dataIndex) { 
 | 
        var name = axis_1.scale.getLabel({ 
 | 
          value: dataIndex 
 | 
        }); 
 | 
        return createTooltipMarkup('nameValue', { 
 | 
          noName: true, 
 | 
          value: name 
 | 
        }); 
 | 
      }; 
 | 
      each(['AxisLine', 'AxisTick', 'Control', 'CurrentPointer'], function (name) { 
 | 
        this['_render' + name](layoutInfo_1, mainGroup_1, axis_1, timelineModel); 
 | 
      }, this); 
 | 
      this._renderAxisLabel(layoutInfo_1, labelGroup, axis_1, timelineModel); 
 | 
      this._position(layoutInfo_1, timelineModel); 
 | 
    } 
 | 
    this._doPlayStop(); 
 | 
    this._updateTicksStatus(); 
 | 
  }; 
 | 
  /** 
 | 
   * @override 
 | 
   */ 
 | 
  SliderTimelineView.prototype.remove = function () { 
 | 
    this._clearTimer(); 
 | 
    this.group.removeAll(); 
 | 
  }; 
 | 
  /** 
 | 
   * @override 
 | 
   */ 
 | 
  SliderTimelineView.prototype.dispose = function () { 
 | 
    this._clearTimer(); 
 | 
  }; 
 | 
  SliderTimelineView.prototype._layout = function (timelineModel, api) { 
 | 
    var labelPosOpt = timelineModel.get(['label', 'position']); 
 | 
    var orient = timelineModel.get('orient'); 
 | 
    var viewRect = getViewRect(timelineModel, api); 
 | 
    var parsedLabelPos; 
 | 
    // Auto label offset. 
 | 
    if (labelPosOpt == null || labelPosOpt === 'auto') { 
 | 
      parsedLabelPos = orient === 'horizontal' ? viewRect.y + viewRect.height / 2 < api.getHeight() / 2 ? '-' : '+' : viewRect.x + viewRect.width / 2 < api.getWidth() / 2 ? '+' : '-'; 
 | 
    } else if (isString(labelPosOpt)) { 
 | 
      parsedLabelPos = { 
 | 
        horizontal: { 
 | 
          top: '-', 
 | 
          bottom: '+' 
 | 
        }, 
 | 
        vertical: { 
 | 
          left: '-', 
 | 
          right: '+' 
 | 
        } 
 | 
      }[orient][labelPosOpt]; 
 | 
    } else { 
 | 
      // is number 
 | 
      parsedLabelPos = labelPosOpt; 
 | 
    } 
 | 
    var labelAlignMap = { 
 | 
      horizontal: 'center', 
 | 
      vertical: parsedLabelPos >= 0 || parsedLabelPos === '+' ? 'left' : 'right' 
 | 
    }; 
 | 
    var labelBaselineMap = { 
 | 
      horizontal: parsedLabelPos >= 0 || parsedLabelPos === '+' ? 'top' : 'bottom', 
 | 
      vertical: 'middle' 
 | 
    }; 
 | 
    var rotationMap = { 
 | 
      horizontal: 0, 
 | 
      vertical: PI / 2 
 | 
    }; 
 | 
    // Position 
 | 
    var mainLength = orient === 'vertical' ? viewRect.height : viewRect.width; 
 | 
    var controlModel = timelineModel.getModel('controlStyle'); 
 | 
    var showControl = controlModel.get('show', true); 
 | 
    var controlSize = showControl ? controlModel.get('itemSize') : 0; 
 | 
    var controlGap = showControl ? controlModel.get('itemGap') : 0; 
 | 
    var sizePlusGap = controlSize + controlGap; 
 | 
    // Special label rotate. 
 | 
    var labelRotation = timelineModel.get(['label', 'rotate']) || 0; 
 | 
    labelRotation = labelRotation * PI / 180; // To radian. 
 | 
    var playPosition; 
 | 
    var prevBtnPosition; 
 | 
    var nextBtnPosition; 
 | 
    var controlPosition = controlModel.get('position', true); 
 | 
    var showPlayBtn = showControl && controlModel.get('showPlayBtn', true); 
 | 
    var showPrevBtn = showControl && controlModel.get('showPrevBtn', true); 
 | 
    var showNextBtn = showControl && controlModel.get('showNextBtn', true); 
 | 
    var xLeft = 0; 
 | 
    var xRight = mainLength; 
 | 
    // position[0] means left, position[1] means middle. 
 | 
    if (controlPosition === 'left' || controlPosition === 'bottom') { 
 | 
      showPlayBtn && (playPosition = [0, 0], xLeft += sizePlusGap); 
 | 
      showPrevBtn && (prevBtnPosition = [xLeft, 0], xLeft += sizePlusGap); 
 | 
      showNextBtn && (nextBtnPosition = [xRight - controlSize, 0], xRight -= sizePlusGap); 
 | 
    } else { 
 | 
      // 'top' 'right' 
 | 
      showPlayBtn && (playPosition = [xRight - controlSize, 0], xRight -= sizePlusGap); 
 | 
      showPrevBtn && (prevBtnPosition = [0, 0], xLeft += sizePlusGap); 
 | 
      showNextBtn && (nextBtnPosition = [xRight - controlSize, 0], xRight -= sizePlusGap); 
 | 
    } 
 | 
    var axisExtent = [xLeft, xRight]; 
 | 
    if (timelineModel.get('inverse')) { 
 | 
      axisExtent.reverse(); 
 | 
    } 
 | 
    return { 
 | 
      viewRect: viewRect, 
 | 
      mainLength: mainLength, 
 | 
      orient: orient, 
 | 
      rotation: rotationMap[orient], 
 | 
      labelRotation: labelRotation, 
 | 
      labelPosOpt: parsedLabelPos, 
 | 
      labelAlign: timelineModel.get(['label', 'align']) || labelAlignMap[orient], 
 | 
      labelBaseline: timelineModel.get(['label', 'verticalAlign']) || timelineModel.get(['label', 'baseline']) || labelBaselineMap[orient], 
 | 
      // Based on mainGroup. 
 | 
      playPosition: playPosition, 
 | 
      prevBtnPosition: prevBtnPosition, 
 | 
      nextBtnPosition: nextBtnPosition, 
 | 
      axisExtent: axisExtent, 
 | 
      controlSize: controlSize, 
 | 
      controlGap: controlGap 
 | 
    }; 
 | 
  }; 
 | 
  SliderTimelineView.prototype._position = function (layoutInfo, timelineModel) { 
 | 
    // Position is be called finally, because bounding rect is needed for 
 | 
    // adapt content to fill viewRect (auto adapt offset). 
 | 
    // Timeline may be not all in the viewRect when 'offset' is specified 
 | 
    // as a number, because it is more appropriate that label aligns at 
 | 
    // 'offset' but not the other edge defined by viewRect. 
 | 
    var mainGroup = this._mainGroup; 
 | 
    var labelGroup = this._labelGroup; 
 | 
    var viewRect = layoutInfo.viewRect; 
 | 
    if (layoutInfo.orient === 'vertical') { 
 | 
      // transform to horizontal, inverse rotate by left-top point. 
 | 
      var m = matrix.create(); 
 | 
      var rotateOriginX = viewRect.x; 
 | 
      var rotateOriginY = viewRect.y + viewRect.height; 
 | 
      matrix.translate(m, m, [-rotateOriginX, -rotateOriginY]); 
 | 
      matrix.rotate(m, m, -PI / 2); 
 | 
      matrix.translate(m, m, [rotateOriginX, rotateOriginY]); 
 | 
      viewRect = viewRect.clone(); 
 | 
      viewRect.applyTransform(m); 
 | 
    } 
 | 
    var viewBound = getBound(viewRect); 
 | 
    var mainBound = getBound(mainGroup.getBoundingRect()); 
 | 
    var labelBound = getBound(labelGroup.getBoundingRect()); 
 | 
    var mainPosition = [mainGroup.x, mainGroup.y]; 
 | 
    var labelsPosition = [labelGroup.x, labelGroup.y]; 
 | 
    labelsPosition[0] = mainPosition[0] = viewBound[0][0]; 
 | 
    var labelPosOpt = layoutInfo.labelPosOpt; 
 | 
    if (labelPosOpt == null || isString(labelPosOpt)) { 
 | 
      // '+' or '-' 
 | 
      var mainBoundIdx = labelPosOpt === '+' ? 0 : 1; 
 | 
      toBound(mainPosition, mainBound, viewBound, 1, mainBoundIdx); 
 | 
      toBound(labelsPosition, labelBound, viewBound, 1, 1 - mainBoundIdx); 
 | 
    } else { 
 | 
      var mainBoundIdx = labelPosOpt >= 0 ? 0 : 1; 
 | 
      toBound(mainPosition, mainBound, viewBound, 1, mainBoundIdx); 
 | 
      labelsPosition[1] = mainPosition[1] + labelPosOpt; 
 | 
    } 
 | 
    mainGroup.setPosition(mainPosition); 
 | 
    labelGroup.setPosition(labelsPosition); 
 | 
    mainGroup.rotation = labelGroup.rotation = layoutInfo.rotation; 
 | 
    setOrigin(mainGroup); 
 | 
    setOrigin(labelGroup); 
 | 
    function setOrigin(targetGroup) { 
 | 
      targetGroup.originX = viewBound[0][0] - targetGroup.x; 
 | 
      targetGroup.originY = viewBound[1][0] - targetGroup.y; 
 | 
    } 
 | 
    function getBound(rect) { 
 | 
      // [[xmin, xmax], [ymin, ymax]] 
 | 
      return [[rect.x, rect.x + rect.width], [rect.y, rect.y + rect.height]]; 
 | 
    } 
 | 
    function toBound(fromPos, from, to, dimIdx, boundIdx) { 
 | 
      fromPos[dimIdx] += to[dimIdx][boundIdx] - from[dimIdx][boundIdx]; 
 | 
    } 
 | 
  }; 
 | 
  SliderTimelineView.prototype._createAxis = function (layoutInfo, timelineModel) { 
 | 
    var data = timelineModel.getData(); 
 | 
    var axisType = timelineModel.get('axisType'); 
 | 
    var scale = createScaleByModel(timelineModel, axisType); 
 | 
    // Customize scale. The `tickValue` is `dataIndex`. 
 | 
    scale.getTicks = function () { 
 | 
      return data.mapArray(['value'], function (value) { 
 | 
        return { 
 | 
          value: value 
 | 
        }; 
 | 
      }); 
 | 
    }; 
 | 
    var dataExtent = data.getDataExtent('value'); 
 | 
    scale.setExtent(dataExtent[0], dataExtent[1]); 
 | 
    scale.calcNiceTicks(); 
 | 
    var axis = new TimelineAxis('value', scale, layoutInfo.axisExtent, axisType); 
 | 
    axis.model = timelineModel; 
 | 
    return axis; 
 | 
  }; 
 | 
  SliderTimelineView.prototype._createGroup = function (key) { 
 | 
    var newGroup = this[key] = new graphic.Group(); 
 | 
    this.group.add(newGroup); 
 | 
    return newGroup; 
 | 
  }; 
 | 
  SliderTimelineView.prototype._renderAxisLine = function (layoutInfo, group, axis, timelineModel) { 
 | 
    var axisExtent = axis.getExtent(); 
 | 
    if (!timelineModel.get(['lineStyle', 'show'])) { 
 | 
      return; 
 | 
    } 
 | 
    var line = new graphic.Line({ 
 | 
      shape: { 
 | 
        x1: axisExtent[0], 
 | 
        y1: 0, 
 | 
        x2: axisExtent[1], 
 | 
        y2: 0 
 | 
      }, 
 | 
      style: extend({ 
 | 
        lineCap: 'round' 
 | 
      }, timelineModel.getModel('lineStyle').getLineStyle()), 
 | 
      silent: true, 
 | 
      z2: 1 
 | 
    }); 
 | 
    group.add(line); 
 | 
    var progressLine = this._progressLine = new graphic.Line({ 
 | 
      shape: { 
 | 
        x1: axisExtent[0], 
 | 
        x2: this._currentPointer ? this._currentPointer.x : axisExtent[0], 
 | 
        y1: 0, 
 | 
        y2: 0 
 | 
      }, 
 | 
      style: defaults({ 
 | 
        lineCap: 'round', 
 | 
        lineWidth: line.style.lineWidth 
 | 
      }, timelineModel.getModel(['progress', 'lineStyle']).getLineStyle()), 
 | 
      silent: true, 
 | 
      z2: 1 
 | 
    }); 
 | 
    group.add(progressLine); 
 | 
  }; 
 | 
  SliderTimelineView.prototype._renderAxisTick = function (layoutInfo, group, axis, timelineModel) { 
 | 
    var _this = this; 
 | 
    var data = timelineModel.getData(); 
 | 
    // Show all ticks, despite ignoring strategy. 
 | 
    var ticks = axis.scale.getTicks(); 
 | 
    this._tickSymbols = []; 
 | 
    // The value is dataIndex, see the customized scale. 
 | 
    each(ticks, function (tick) { 
 | 
      var tickCoord = axis.dataToCoord(tick.value); 
 | 
      var itemModel = data.getItemModel(tick.value); 
 | 
      var itemStyleModel = itemModel.getModel('itemStyle'); 
 | 
      var hoverStyleModel = itemModel.getModel(['emphasis', 'itemStyle']); 
 | 
      var progressStyleModel = itemModel.getModel(['progress', 'itemStyle']); 
 | 
      var symbolOpt = { 
 | 
        x: tickCoord, 
 | 
        y: 0, 
 | 
        onclick: bind(_this._changeTimeline, _this, tick.value) 
 | 
      }; 
 | 
      var el = giveSymbol(itemModel, itemStyleModel, group, symbolOpt); 
 | 
      el.ensureState('emphasis').style = hoverStyleModel.getItemStyle(); 
 | 
      el.ensureState('progress').style = progressStyleModel.getItemStyle(); 
 | 
      enableHoverEmphasis(el); 
 | 
      var ecData = getECData(el); 
 | 
      if (itemModel.get('tooltip')) { 
 | 
        ecData.dataIndex = tick.value; 
 | 
        ecData.dataModel = timelineModel; 
 | 
      } else { 
 | 
        ecData.dataIndex = ecData.dataModel = null; 
 | 
      } 
 | 
      _this._tickSymbols.push(el); 
 | 
    }); 
 | 
  }; 
 | 
  SliderTimelineView.prototype._renderAxisLabel = function (layoutInfo, group, axis, timelineModel) { 
 | 
    var _this = this; 
 | 
    var labelModel = axis.getLabelModel(); 
 | 
    if (!labelModel.get('show')) { 
 | 
      return; 
 | 
    } 
 | 
    var data = timelineModel.getData(); 
 | 
    var labels = axis.getViewLabels(); 
 | 
    this._tickLabels = []; 
 | 
    each(labels, function (labelItem) { 
 | 
      // The tickValue is dataIndex, see the customized scale. 
 | 
      var dataIndex = labelItem.tickValue; 
 | 
      var itemModel = data.getItemModel(dataIndex); 
 | 
      var normalLabelModel = itemModel.getModel('label'); 
 | 
      var hoverLabelModel = itemModel.getModel(['emphasis', 'label']); 
 | 
      var progressLabelModel = itemModel.getModel(['progress', 'label']); 
 | 
      var tickCoord = axis.dataToCoord(labelItem.tickValue); 
 | 
      var textEl = new graphic.Text({ 
 | 
        x: tickCoord, 
 | 
        y: 0, 
 | 
        rotation: layoutInfo.labelRotation - layoutInfo.rotation, 
 | 
        onclick: bind(_this._changeTimeline, _this, dataIndex), 
 | 
        silent: false, 
 | 
        style: createTextStyle(normalLabelModel, { 
 | 
          text: labelItem.formattedLabel, 
 | 
          align: layoutInfo.labelAlign, 
 | 
          verticalAlign: layoutInfo.labelBaseline 
 | 
        }) 
 | 
      }); 
 | 
      textEl.ensureState('emphasis').style = createTextStyle(hoverLabelModel); 
 | 
      textEl.ensureState('progress').style = createTextStyle(progressLabelModel); 
 | 
      group.add(textEl); 
 | 
      enableHoverEmphasis(textEl); 
 | 
      labelDataIndexStore(textEl).dataIndex = dataIndex; 
 | 
      _this._tickLabels.push(textEl); 
 | 
    }); 
 | 
  }; 
 | 
  SliderTimelineView.prototype._renderControl = function (layoutInfo, group, axis, timelineModel) { 
 | 
    var controlSize = layoutInfo.controlSize; 
 | 
    var rotation = layoutInfo.rotation; 
 | 
    var itemStyle = timelineModel.getModel('controlStyle').getItemStyle(); 
 | 
    var hoverStyle = timelineModel.getModel(['emphasis', 'controlStyle']).getItemStyle(); 
 | 
    var playState = timelineModel.getPlayState(); 
 | 
    var inverse = timelineModel.get('inverse', true); 
 | 
    makeBtn(layoutInfo.nextBtnPosition, 'next', bind(this._changeTimeline, this, inverse ? '-' : '+')); 
 | 
    makeBtn(layoutInfo.prevBtnPosition, 'prev', bind(this._changeTimeline, this, inverse ? '+' : '-')); 
 | 
    makeBtn(layoutInfo.playPosition, playState ? 'stop' : 'play', bind(this._handlePlayClick, this, !playState), true); 
 | 
    function makeBtn(position, iconName, onclick, willRotate) { 
 | 
      if (!position) { 
 | 
        return; 
 | 
      } 
 | 
      var iconSize = parsePercent(retrieve2(timelineModel.get(['controlStyle', iconName + 'BtnSize']), controlSize), controlSize); 
 | 
      var rect = [0, -iconSize / 2, iconSize, iconSize]; 
 | 
      var btn = makeControlIcon(timelineModel, iconName + 'Icon', rect, { 
 | 
        x: position[0], 
 | 
        y: position[1], 
 | 
        originX: controlSize / 2, 
 | 
        originY: 0, 
 | 
        rotation: willRotate ? -rotation : 0, 
 | 
        rectHover: true, 
 | 
        style: itemStyle, 
 | 
        onclick: onclick 
 | 
      }); 
 | 
      btn.ensureState('emphasis').style = hoverStyle; 
 | 
      group.add(btn); 
 | 
      enableHoverEmphasis(btn); 
 | 
    } 
 | 
  }; 
 | 
  SliderTimelineView.prototype._renderCurrentPointer = function (layoutInfo, group, axis, timelineModel) { 
 | 
    var data = timelineModel.getData(); 
 | 
    var currentIndex = timelineModel.getCurrentIndex(); 
 | 
    var pointerModel = data.getItemModel(currentIndex).getModel('checkpointStyle'); 
 | 
    var me = this; 
 | 
    var callback = { 
 | 
      onCreate: function (pointer) { 
 | 
        pointer.draggable = true; 
 | 
        pointer.drift = bind(me._handlePointerDrag, me); 
 | 
        pointer.ondragend = bind(me._handlePointerDragend, me); 
 | 
        pointerMoveTo(pointer, me._progressLine, currentIndex, axis, timelineModel, true); 
 | 
      }, 
 | 
      onUpdate: function (pointer) { 
 | 
        pointerMoveTo(pointer, me._progressLine, currentIndex, axis, timelineModel); 
 | 
      } 
 | 
    }; 
 | 
    // Reuse when exists, for animation and drag. 
 | 
    this._currentPointer = giveSymbol(pointerModel, pointerModel, this._mainGroup, {}, this._currentPointer, callback); 
 | 
  }; 
 | 
  SliderTimelineView.prototype._handlePlayClick = function (nextState) { 
 | 
    this._clearTimer(); 
 | 
    this.api.dispatchAction({ 
 | 
      type: 'timelinePlayChange', 
 | 
      playState: nextState, 
 | 
      from: this.uid 
 | 
    }); 
 | 
  }; 
 | 
  SliderTimelineView.prototype._handlePointerDrag = function (dx, dy, e) { 
 | 
    this._clearTimer(); 
 | 
    this._pointerChangeTimeline([e.offsetX, e.offsetY]); 
 | 
  }; 
 | 
  SliderTimelineView.prototype._handlePointerDragend = function (e) { 
 | 
    this._pointerChangeTimeline([e.offsetX, e.offsetY], true); 
 | 
  }; 
 | 
  SliderTimelineView.prototype._pointerChangeTimeline = function (mousePos, trigger) { 
 | 
    var toCoord = this._toAxisCoord(mousePos)[0]; 
 | 
    var axis = this._axis; 
 | 
    var axisExtent = numberUtil.asc(axis.getExtent().slice()); 
 | 
    toCoord > axisExtent[1] && (toCoord = axisExtent[1]); 
 | 
    toCoord < axisExtent[0] && (toCoord = axisExtent[0]); 
 | 
    this._currentPointer.x = toCoord; 
 | 
    this._currentPointer.markRedraw(); 
 | 
    var progressLine = this._progressLine; 
 | 
    if (progressLine) { 
 | 
      progressLine.shape.x2 = toCoord; 
 | 
      progressLine.dirty(); 
 | 
    } 
 | 
    var targetDataIndex = this._findNearestTick(toCoord); 
 | 
    var timelineModel = this.model; 
 | 
    if (trigger || targetDataIndex !== timelineModel.getCurrentIndex() && timelineModel.get('realtime')) { 
 | 
      this._changeTimeline(targetDataIndex); 
 | 
    } 
 | 
  }; 
 | 
  SliderTimelineView.prototype._doPlayStop = function () { 
 | 
    var _this = this; 
 | 
    this._clearTimer(); 
 | 
    if (this.model.getPlayState()) { 
 | 
      this._timer = setTimeout(function () { 
 | 
        // Do not cache 
 | 
        var timelineModel = _this.model; 
 | 
        _this._changeTimeline(timelineModel.getCurrentIndex() + (timelineModel.get('rewind', true) ? -1 : 1)); 
 | 
      }, this.model.get('playInterval')); 
 | 
    } 
 | 
  }; 
 | 
  SliderTimelineView.prototype._toAxisCoord = function (vertex) { 
 | 
    var trans = this._mainGroup.getLocalTransform(); 
 | 
    return graphic.applyTransform(vertex, trans, true); 
 | 
  }; 
 | 
  SliderTimelineView.prototype._findNearestTick = function (axisCoord) { 
 | 
    var data = this.model.getData(); 
 | 
    var dist = Infinity; 
 | 
    var targetDataIndex; 
 | 
    var axis = this._axis; 
 | 
    data.each(['value'], function (value, dataIndex) { 
 | 
      var coord = axis.dataToCoord(value); 
 | 
      var d = Math.abs(coord - axisCoord); 
 | 
      if (d < dist) { 
 | 
        dist = d; 
 | 
        targetDataIndex = dataIndex; 
 | 
      } 
 | 
    }); 
 | 
    return targetDataIndex; 
 | 
  }; 
 | 
  SliderTimelineView.prototype._clearTimer = function () { 
 | 
    if (this._timer) { 
 | 
      clearTimeout(this._timer); 
 | 
      this._timer = null; 
 | 
    } 
 | 
  }; 
 | 
  SliderTimelineView.prototype._changeTimeline = function (nextIndex) { 
 | 
    var currentIndex = this.model.getCurrentIndex(); 
 | 
    if (nextIndex === '+') { 
 | 
      nextIndex = currentIndex + 1; 
 | 
    } else if (nextIndex === '-') { 
 | 
      nextIndex = currentIndex - 1; 
 | 
    } 
 | 
    this.api.dispatchAction({ 
 | 
      type: 'timelineChange', 
 | 
      currentIndex: nextIndex, 
 | 
      from: this.uid 
 | 
    }); 
 | 
  }; 
 | 
  SliderTimelineView.prototype._updateTicksStatus = function () { 
 | 
    var currentIndex = this.model.getCurrentIndex(); 
 | 
    var tickSymbols = this._tickSymbols; 
 | 
    var tickLabels = this._tickLabels; 
 | 
    if (tickSymbols) { 
 | 
      for (var i = 0; i < tickSymbols.length; i++) { 
 | 
        tickSymbols && tickSymbols[i] && tickSymbols[i].toggleState('progress', i < currentIndex); 
 | 
      } 
 | 
    } 
 | 
    if (tickLabels) { 
 | 
      for (var i = 0; i < tickLabels.length; i++) { 
 | 
        tickLabels && tickLabels[i] && tickLabels[i].toggleState('progress', labelDataIndexStore(tickLabels[i]).dataIndex <= currentIndex); 
 | 
      } 
 | 
    } 
 | 
  }; 
 | 
  SliderTimelineView.type = 'timeline.slider'; 
 | 
  return SliderTimelineView; 
 | 
}(TimelineView); 
 | 
function createScaleByModel(model, axisType) { 
 | 
  axisType = axisType || model.get('type'); 
 | 
  if (axisType) { 
 | 
    switch (axisType) { 
 | 
      // Buildin scale 
 | 
      case 'category': 
 | 
        return new OrdinalScale({ 
 | 
          ordinalMeta: model.getCategories(), 
 | 
          extent: [Infinity, -Infinity] 
 | 
        }); 
 | 
      case 'time': 
 | 
        return new TimeScale({ 
 | 
          locale: model.ecModel.getLocaleModel(), 
 | 
          useUTC: model.ecModel.get('useUTC') 
 | 
        }); 
 | 
      default: 
 | 
        // default to be value 
 | 
        return new IntervalScale(); 
 | 
    } 
 | 
  } 
 | 
} 
 | 
function getViewRect(model, api) { 
 | 
  return layout.getLayoutRect(model.getBoxLayoutParams(), { 
 | 
    width: api.getWidth(), 
 | 
    height: api.getHeight() 
 | 
  }, model.get('padding')); 
 | 
} 
 | 
function makeControlIcon(timelineModel, objPath, rect, opts) { 
 | 
  var style = opts.style; 
 | 
  var icon = graphic.createIcon(timelineModel.get(['controlStyle', objPath]), opts || {}, new BoundingRect(rect[0], rect[1], rect[2], rect[3])); 
 | 
  // TODO createIcon won't use style in opt. 
 | 
  if (style) { 
 | 
    icon.setStyle(style); 
 | 
  } 
 | 
  return icon; 
 | 
} 
 | 
/** 
 | 
 * Create symbol or update symbol 
 | 
 * opt: basic position and event handlers 
 | 
 */ 
 | 
function giveSymbol(hostModel, itemStyleModel, group, opt, symbol, callback) { 
 | 
  var color = itemStyleModel.get('color'); 
 | 
  if (!symbol) { 
 | 
    var symbolType = hostModel.get('symbol'); 
 | 
    symbol = createSymbol(symbolType, -1, -1, 2, 2, color); 
 | 
    symbol.setStyle('strokeNoScale', true); 
 | 
    group.add(symbol); 
 | 
    callback && callback.onCreate(symbol); 
 | 
  } else { 
 | 
    symbol.setColor(color); 
 | 
    group.add(symbol); // Group may be new, also need to add. 
 | 
    callback && callback.onUpdate(symbol); 
 | 
  } 
 | 
  // Style 
 | 
  var itemStyle = itemStyleModel.getItemStyle(['color']); 
 | 
  symbol.setStyle(itemStyle); 
 | 
  // Transform and events. 
 | 
  opt = merge({ 
 | 
    rectHover: true, 
 | 
    z2: 100 
 | 
  }, opt, true); 
 | 
  var symbolSize = normalizeSymbolSize(hostModel.get('symbolSize')); 
 | 
  opt.scaleX = symbolSize[0] / 2; 
 | 
  opt.scaleY = symbolSize[1] / 2; 
 | 
  var symbolOffset = normalizeSymbolOffset(hostModel.get('symbolOffset'), symbolSize); 
 | 
  if (symbolOffset) { 
 | 
    opt.x = (opt.x || 0) + symbolOffset[0]; 
 | 
    opt.y = (opt.y || 0) + symbolOffset[1]; 
 | 
  } 
 | 
  var symbolRotate = hostModel.get('symbolRotate'); 
 | 
  opt.rotation = (symbolRotate || 0) * Math.PI / 180 || 0; 
 | 
  symbol.attr(opt); 
 | 
  // FIXME 
 | 
  // (1) When symbol.style.strokeNoScale is true and updateTransform is not performed, 
 | 
  // getBoundingRect will return wrong result. 
 | 
  // (This is supposed to be resolved in zrender, but it is a little difficult to 
 | 
  // leverage performance and auto updateTransform) 
 | 
  // (2) All of ancesters of symbol do not scale, so we can just updateTransform symbol. 
 | 
  symbol.updateTransform(); 
 | 
  return symbol; 
 | 
} 
 | 
function pointerMoveTo(pointer, progressLine, dataIndex, axis, timelineModel, noAnimation) { 
 | 
  if (pointer.dragging) { 
 | 
    return; 
 | 
  } 
 | 
  var pointerModel = timelineModel.getModel('checkpointStyle'); 
 | 
  var toCoord = axis.dataToCoord(timelineModel.getData().get('value', dataIndex)); 
 | 
  if (noAnimation || !pointerModel.get('animation', true)) { 
 | 
    pointer.attr({ 
 | 
      x: toCoord, 
 | 
      y: 0 
 | 
    }); 
 | 
    progressLine && progressLine.attr({ 
 | 
      shape: { 
 | 
        x2: toCoord 
 | 
      } 
 | 
    }); 
 | 
  } else { 
 | 
    var animationCfg = { 
 | 
      duration: pointerModel.get('animationDuration', true), 
 | 
      easing: pointerModel.get('animationEasing', true) 
 | 
    }; 
 | 
    pointer.stopAnimation(null, true); 
 | 
    pointer.animateTo({ 
 | 
      x: toCoord, 
 | 
      y: 0 
 | 
    }, animationCfg); 
 | 
    progressLine && progressLine.animateTo({ 
 | 
      shape: { 
 | 
        x2: toCoord 
 | 
      } 
 | 
    }, animationCfg); 
 | 
  } 
 | 
} 
 | 
export default SliderTimelineView; 
 |