text: /**
   * echarts图表类：事件河流图
   *
   * @desc echarts基于Canvas，纯Javascript图表库，提供直观，生动，可交互，可个性化定制的数据统计图表。
   * @author clmtulip  (车丽美, chelimei@baidu.com)
   *
   */
  define(function (require) {
      var ComponentBase = require('../component/base');
      var ChartBase = require('./base');
  
      var eventRiverLayout = require('../layout/eventRiver');
  
      // 图形依赖
      var PolygonShape = require('zrender/shape/Polygon');
  
      // 组件依赖
      require('../component/axis');
      require('../component/grid');
      require('../component/dataZoom');
  
      var ecConfig = require('../config');
      var ecData = require('../util/ecData');
      var ecDate = require('../util/date');
      var zrUtil = require('zrender/tool/util');
      var zrColor = require('zrender/tool/color');
  
      /**
       * 构造函数
       * @param {Object} messageCenter echart消息中心
       * @param {ZRender} zr zrender实例
       * @param {Object} option 数据
       * @param {Object} component 组件
       */
       function EventRiver(ecTheme, messageCenter, zr, option, myChart) {
           // 基类
           ComponentBase.call(this, ecTheme, messageCenter, zr, option, myChart);
           // 图表基类
           ChartBase.call(this);
           
           var self = this;
           self._ondragend = function () {
               self.isDragend = true;
           };
           this.refresh(option);
       }
  
       EventRiver.prototype = {
           type: ecConfig.CHART_TYPE_EVENTRIVER,
           
           _buildShape: function() {
               var series = this.series;
               this.selectedMap = {};
               
               // 数据预处理
               this._dataPreprocessing();
              
               var legend = this.component.legend;
               // 调用布局算法计算事件在Y轴上的位置
               var eventRiverSeries = [];
               for (var i = 0; i < series.length; i++) {
                   if (series[i].type === this.type) {
                       series[i] = this.reformOption(series[i]);
                       this.legendHoverLink = series[i].legendHoverLink || this.legendHoverLink;
                       var serieName = series[i].name || '';
                       // 系列图例开关
                       this.selectedMap[serieName] = legend ? legend.isSelected(serieName) : true;
                       if (!this.selectedMap[serieName]) {
                           continue;
                       }
                       this.buildMark(i);
                       eventRiverSeries.push(this.series[i]);
                   }
               }
               
               eventRiverLayout(
                   eventRiverSeries,
                   this.component.grid.getArea()
               );
               
               // 绘制事件河
               this._drawEventRiver();
               
               this.addShapeList();
           },
  
           /**
            * 处理数据
            */
           _dataPreprocessing: function() {
               // 将年月日的时间转化为平面坐标
               var series = this.series;
               var xAxis;
               var evolutionList;
               for (var i = 0, iLen = series.length; i < iLen; i++) {
                   if (series[i].type === this.type) {
                       xAxis = this.component.xAxis.getAxis(series[i].xAxisIndex || 0);
                       for (var j = 0, jLen = series[i].eventList.length; j < jLen; j++) {
                           evolutionList = series[i].eventList[j].evolution;
                           for (var k = 0, kLen = evolutionList.length; k < kLen; k++) {
                               evolutionList[k].timeScale = xAxis.getCoord(
                                   ecDate.getNewDate(evolutionList[k].time) - 0
                               );
                               evolutionList[k].valueScale = evolutionList[k].value;
                           }
                       }
                   }
               }
               // 尾迹长度
               this._intervalX = Math.round(this.component.grid.getWidth() / 15);
           },
  
           /**
            * 绘制事件河流
            */
           _drawEventRiver: function(){
               var series = this.series;
               for (var i = 0; i < series.length; i++) {
                   var serieName = series[i].name || '';
                   if (series[i].type === this.type && this.selectedMap[serieName]) {
                       for (var j = 0; j < series[i].eventList.length; j++) {
                           this._drawEventBubble(series[i].eventList[j], i, j);
                       }
                   }
               }
           },
  
           /**
            * 绘制气泡图
            */
           _drawEventBubble: function(oneEvent, seriesIndex, dataIndex) {
               var series = this.series;
               var serie = series[seriesIndex];
               var serieName = serie.name || '';
               var data = serie.eventList[dataIndex];
               var queryTarget = [data, serie];
  
               var legend = this.component.legend;
               var defaultColor = legend ? legend.getColor(serieName) : this.zr.getColor(seriesIndex);
               
               // 多级控制
               var normal = this.deepMerge(queryTarget, 'itemStyle.normal') || {};
               var emphasis = this.deepMerge(queryTarget, 'itemStyle.emphasis') || {};
               var normalColor = this.getItemStyleColor(normal.color, seriesIndex, dataIndex, data)
                                 || defaultColor;
               
               var emphasisColor = this.getItemStyleColor(
                                       emphasis.color, seriesIndex, dataIndex, data
                                   )
                                   || (typeof normalColor === 'string'
                                       ? zrColor.lift(normalColor, -0.2)
                                       : normalColor
                                   );
              
               var pts = this._calculateControlPoints(oneEvent);
               
               var eventBubbleShape = {
                   zlevel: this._zlevelBase,
                   clickable: this.deepQuery(queryTarget, 'clickable'),
                   style: {
                       pointList: pts,
                       smooth: 'spline',
                       brushType: 'both',
                       lineJoin : 'round',
                       color: normalColor,
                       lineWidth: normal.borderWidth,
                       strokeColor: normal.borderColor
                   },
                   highlightStyle:{
                       color: emphasisColor,
                       lineWidth: emphasis.borderWidth,
                       strokeColor: emphasis.borderColor
                   },
                   draggable: 'vertical',
                   ondragend : this._ondragend
               };
               
               eventBubbleShape = new PolygonShape(eventBubbleShape);
               
               this.addLabel(eventBubbleShape, serie, data, oneEvent.name);
               ecData.pack(
                   eventBubbleShape,
                   series[seriesIndex], seriesIndex,
                   series[seriesIndex].eventList[dataIndex], dataIndex,
                   series[seriesIndex].eventList[dataIndex].name
               );
               this.shapeList.push(eventBubbleShape);
           },
  
           /**
           * 根据时间-热度，计算气泡形状的控制点
           */
           _calculateControlPoints: function(oneEvent) {
               var intervalX = this._intervalX;
               var posY = oneEvent.y;
               
               var evolution = oneEvent.evolution;
               var n = evolution.length;
               if (n < 1) {
                   return;
               }
               
               var time = [];
               var value = [];
               for (var i = 0; i < n; i++) {
                   time.push(evolution[i].timeScale);
                   value.push(evolution[i].valueScale);
               }
               
               var pts = [];
               
               // 从左向右绘制气泡的上半部分控制点
               // 第一个矩形的左端点
               pts.push([time[0], posY]);
               // 从一个矩形 到 倒数第二个矩形 上半部分的中点
               var i = 0;
               for (i = 0; i < n - 1; i++) {
                   pts.push([(time[i] + time[i + 1]) / 2.0, value[i] / -2.0 + posY]);
               }
               // 最后一个矩形上半部分的中点
               pts.push([(time[i] + (time[i] + intervalX)) / 2.0, value[i] / -2.0 + posY]);
               // 最后一个矩形的右端点
               pts.push([time[i] + intervalX, posY]);
  
               // 从右向左绘制气泡的下半部分控制点
               // 最后一个矩形下半部分的中点
               pts.push([(time[i] + (time[i] + intervalX)) / 2.0, value[i] / 2.0 + posY]);
               // 从倒数第二个矩形 到 一个矩形 下半部分的中点，由于polygon是闭合的，故不需要再加入左端点
               for (i = n - 1; i > 0; i--) {
                   pts.push([(time[i] + time[i - 1]) / 2.0, value[i - 1] / 2.0 + posY]);
               }
               
               return pts;
           },
           
          /**
           * 数据项被拖拽出去
           */
          ondragend : function (param, status) {
              if (!this.isDragend || !param.target) {
                  // 没有在当前实例上发生拖拽行为则直接返回
                  return;
              }
  
              // 别status = {}赋值啊！！
              status.dragOut = true;
              status.dragIn = true;
              status.needRefresh = false; // 会有消息触发fresh，不用再刷一遍
              // 处理完拖拽事件后复位
              this.isDragend = false;
          },
  
           /**
           * 刷新
           */
           refresh: function(newOption) {
               if (newOption) {
                  this.option = newOption;
                  this.series = newOption.series;
              }
  
              this.backupShapeList();
              this._buildShape();
           }
  
       };
  
       zrUtil.inherits(EventRiver, ChartBase);
       zrUtil.inherits(EventRiver, ComponentBase);
  
       // 图表注册
       require('../chart').define('eventRiver', EventRiver);
  
       return EventRiver;
  });