text: // TODO Batch by color
  
  define(function (require) {
  
      var graphic = require('../../util/graphic');
  
      var quadraticContain = require('zrender/contain/quadratic');
      var lineContain = require('zrender/contain/line');
  
      var LargeLineShape = graphic.extendShape({
          shape: {
              polyline: false,
  
              segs: []
          },
  
          buildPath: function (path, shape) {
              var segs = shape.segs;
              var isPolyline = shape.polyline;
  
              for (var i = 0; i < segs.length; i++) {
                  var seg = segs[i];
                  if (isPolyline) {
                      path.moveTo(seg[0][0], seg[0][1]);
                      for (var j = 1; j < seg.length; j++) {
                          path.lineTo(seg[j][0], seg[j][1]);
                      }
                  }
                  else {
                      path.moveTo(seg[0][0], seg[0][1]);
                      if (seg.length > 2) {
                          path.quadraticCurveTo(seg[2][0], seg[2][1], seg[1][0], seg[1][1]);
                      }
                      else {
                          path.lineTo(seg[1][0], seg[1][1]);
                      }
                  }
              }
          },
  
          findDataIndex: function (x, y) {
              var shape = this.shape;
              var segs = shape.segs;
              var isPolyline = shape.polyline;
              var lineWidth = Math.max(this.style.lineWidth, 1);
  
              // Not consider transform
              for (var i = 0; i < segs.length; i++) {
                  var seg = segs[i];
                  if (isPolyline) {
                      for (var j = 1; j < seg.length; j++) {
                          if (lineContain.containStroke(
                              seg[j - 1][0], seg[j - 1][1], seg[j][0], seg[j][1], lineWidth, x, y
                          )) {
                              return i;
                          }
                      }
                  }
                  else {
                      if (seg.length > 2) {
                          if (quadraticContain.containStroke(
                              seg[0][0], seg[0][1], seg[2][0], seg[2][1], seg[1][0], seg[1][1], lineWidth, x, y
                          )) {
                              return i;
                          }
                      }
                      else {
                          if (lineContain.containStroke(
                              seg[0][0], seg[0][1], seg[1][0], seg[1][1], lineWidth, x, y
                          )) {
                              return i;
                          }
                      }
                  }
              }
  
              return -1;
          }
      });
  
      function LargeLineDraw() {
          this.group = new graphic.Group();
  
          this._lineEl = new LargeLineShape();
      }
  
      var largeLineProto = LargeLineDraw.prototype;
  
      /**
       * Update symbols draw by new data
       * @param {module:echarts/data/List} data
       */
      largeLineProto.updateData = function (data) {
          this.group.removeAll();
  
          var lineEl = this._lineEl;
  
          var seriesModel = data.hostModel;
  
          lineEl.setShape({
              segs: data.mapArray(data.getItemLayout),
              polyline: seriesModel.get('polyline')
          });
  
          lineEl.useStyle(
              seriesModel.getModel('lineStyle.normal').getLineStyle()
          );
  
          var visualColor = data.getVisual('color');
          if (visualColor) {
              lineEl.setStyle('stroke', visualColor);
          }
          lineEl.setStyle('fill');
  
          // Enable tooltip
          // PENDING May have performance issue when path is extremely large
          lineEl.seriesIndex = seriesModel.seriesIndex;
          lineEl.on('mousemove', function (e) {
              lineEl.dataIndex = null;
              var dataIndex = lineEl.findDataIndex(e.offsetX, e.offsetY);
              if (dataIndex > 0) {
                  // Provide dataIndex for tooltip
                  lineEl.dataIndex = dataIndex;
              }
          });
  
          // Add back
          this.group.add(lineEl);
      };
  
      largeLineProto.updateLayout = function (seriesModel) {
          var data = seriesModel.getData();
          this._lineEl.setShape({
              segs: data.mapArray(data.getItemLayout)
          });
      };
  
      largeLineProto.remove = function () {
          this.group.removeAll();
      };
  
      return LargeLineDraw;
  });