text: import { deepMix, clone, each, isString, mix } from '@antv/util';
  var ANCHOR_OFFSET = 0; // 锚点偏移量
  var INFLECTION_OFFSET = 15; // 拐点偏移量
  var DEFAULT_COLOR = '#CCC';
  var LABEL1_OFFSETY = 2;
  var LABEL2_OFFSETY = -2;
  var ADJUSTOFFSET = 15;
  function getEndPoint(center, angle, r) {
      return {
          x: center.x + r * Math.cos(angle),
          y: center.y + r * Math.sin(angle),
      };
  }
  var SpiderLabel = /** @class */ (function () {
      function SpiderLabel(cfg) {
          this.destroyed = false;
          this.view = cfg.view;
          this.options = deepMix({}, this.getDefaultOptions(), cfg);
          this._adjustOptions(this.options);
          this.init();
      }
      SpiderLabel.prototype.init = function () {
          var _this = this;
          this.container = this.view.geometries[0].labelsContainer;
          this.view.on('beforerender', function () {
              _this.clear();
          });
      };
      SpiderLabel.prototype.render = function () {
          var _this = this;
          if (!this.view || this.view.destroyed) {
              return;
          }
          /** 如果有formatter则事先处理数据 */
          var data = clone(this.view.getData());
          this.halves = [[], []];
          var shapes = [];
          var elements = this.view.geometries[0].elements;
          each(elements, function (ele) {
              shapes.push(ele.shape);
          });
          this.coord = this.view.geometries[0].coordinate;
          var angleField = this.options.fields[0];
          var scale = this.view.getScalesByDim('y')[angleField];
          var center = this.coord.getCenter();
          var startAngle = this.coord.startAngle;
          var radius = this.coord.polarRadius;
          var _a = this.view.coordinateBBox, width = _a.width, height = _a.height;
          this.width = width;
          this.height = height;
          var angle = startAngle;
          var _loop_1 = function (idx) {
              var d = data[idx];
              // 计算每个切片的middle angle
              var angleValue = scale.scale(d[angleField]);
              var targetAngle = angle + Math.PI * 2 * angleValue;
              var middleAngle = angle + (targetAngle - angle) / 2;
              angle = targetAngle;
              // 根据middle angle计算锚点和拐点距离
              var anchorPoint = getEndPoint(center, middleAngle, radius + ANCHOR_OFFSET);
              var inflectionPoint = getEndPoint(center, middleAngle, radius + INFLECTION_OFFSET);
              // 获取对应shape的color
              var color = DEFAULT_COLOR;
              if (this_1.options.fields.length === 2) {
                  var colorField = this_1.options.fields[1];
                  var colorScale = this_1.view.geometries[0].scales[colorField];
                  var colorIndex = colorScale.scale(d[colorField]);
                  var shapeIndex = Math.floor(colorIndex * (shapes.length - 1));
                  color = shapes[shapeIndex].attr('fill');
              }
              // 组装label数据
              var label = {
                  _anchor: anchorPoint,
                  _inflection: inflectionPoint,
                  _data: d,
                  x: inflectionPoint.x,
                  y: inflectionPoint.y,
                  r: radius + INFLECTION_OFFSET,
                  fill: color,
                  textGroup: null,
                  _side: null,
              };
              // 创建label文本
              var texts = [];
              each(this_1.options.fields, function (f) {
                  texts.push(d[f]);
              });
              if (this_1.options.formatter) {
                  var formatted = this_1.options.formatter(d[angleField], { _origin: d, color: color }, idx);
                  if (isString(formatted)) {
                      formatted = [formatted];
                  }
                  texts = formatted;
              }
              var textGroup = this_1.container.addGroup({
                  capture: false,
              });
              var textAttrs = {
                  x: 0,
                  y: 0,
                  fontSize: this_1.options.text.fontSize,
                  lineHeight: this_1.options.text.fontSize,
                  fontWeight: this_1.options.text.fontWeight,
                  fill: this_1.options.text.fill,
              };
              // label1:下部label
              var lowerText = d[angleField];
              if (this_1.options.formatter) {
                  lowerText = texts[0];
              }
              var lowerTextAttrs = clone(textAttrs);
              if (texts.length === 2) {
                  lowerTextAttrs.fontWeight = 700;
              }
              var lowerTextShape = textGroup.addShape('text', {
                  attrs: mix({
                      textBaseline: texts.length === 2 ? 'top' : 'middle',
                      text: lowerText,
                  }, lowerTextAttrs),
                  data: d,
                  offsetY: texts.length === 2 ? LABEL1_OFFSETY : 0,
                  name: 'label',
              });
              lowerTextShape.name = 'label'; // 用于事件标记 shapeName
              /** label2:上部label */
              if (texts.length === 2) {
                  var topTextShape = textGroup.addShape('text', {
                      attrs: mix({
                          textBaseline: 'bottom',
                          text: texts[1],
                      }, textAttrs),
                      data: d,
                      offsetY: LABEL2_OFFSETY,
                      name: 'label',
                  });
                  topTextShape.name = 'label'; // 用于事件标记 shapeName
              }
              label.textGroup = textGroup;
              /** 将label分组 */
              if (anchorPoint.x < center.x) {
                  label._side = 'left';
                  this_1.halves[0].push(label);
              }
              else {
                  label._side = 'right';
                  this_1.halves[1].push(label);
              }
          };
          var this_1 = this;
          // tslint:disable-next-line: prefer-for-of
          for (var idx = 0; idx < data.length; idx++) {
              _loop_1(idx);
          }
          /** 绘制label */
          var maxCountForOneSide = Math.floor(height / this.options.lineHeight);
          each(this.halves, function (half) {
              if (half.length > maxCountForOneSide) {
                  half.splice(maxCountForOneSide, half.length - maxCountForOneSide);
              }
              half.sort(function (a, b) {
                  return a.y - b.y;
              });
              _this._antiCollision(half);
          });
          this.view.canvas.draw();
      };
      SpiderLabel.prototype.clear = function () {
          if (this.container) {
              this.container.clear();
          }
      };
      SpiderLabel.prototype.hide = function () {
          this.container.set('visible', false);
          this.view.canvas.draw();
      };
      SpiderLabel.prototype.show = function () {
          this.container.set('visible', true);
          this.view.canvas.draw();
      };
      SpiderLabel.prototype.destroy = function () {
          if (this.container) {
              this.container.remove();
          }
          this.destroyed = true;
      };
      SpiderLabel.prototype.getDefaultOptions = function () {
          return {
              text: {
                  fill: 'rgba(0, 0, 0, 0.65)',
                  fontSize: 12,
              },
              line: {
                  lineWidth: 0.5,
                  stroke: 'rgba(0, 0, 0, 0.45)',
              },
              lineHeight: 32,
              /** distance between label and edge */
              sidePadding: 20,
          };
      };
      SpiderLabel.prototype._antiCollision = function (half) {
          var _this = this;
          var coord = this.coord;
          var canvasHeight = coord.getHeight();
          var center = coord.center;
          var radius = coord.getRadius();
          var startY = center.y - radius - INFLECTION_OFFSET - this.options.lineHeight;
          var overlapping = true;
          var totalH = canvasHeight;
          var i;
          var maxY = 0;
          var minY = Number.MIN_VALUE;
          var maxLabelWidth = 0;
          var boxes = half.map(function (label) {
              var labelY = label.y;
              if (labelY > maxY) {
                  maxY = labelY;
              }
              if (labelY < minY) {
                  minY = labelY;
              }
              var textGroup = label.textGroup;
              var labelWidth = textGroup.getBBox().width;
              if (labelWidth >= maxLabelWidth) {
                  maxLabelWidth = labelWidth;
              }
              return {
                  size: _this.options.lineHeight,
                  targets: [labelY - startY],
              };
          });
          if (maxY - startY > totalH) {
              totalH = maxY - startY;
          }
          var iteratorBoxed = function (items) {
              items.forEach(function (box) {
                  var target = (Math.min.apply(minY, box.targets) + Math.max.apply(minY, box.targets)) / 2;
                  box.pos = Math.min(Math.max(minY, target - box.size / 2), totalH - box.size);
              });
          };
          while (overlapping) {
              iteratorBoxed(boxes);
              // detect overlapping and join boxes
              overlapping = false;
              i = boxes.length;
              while (i--) {
                  if (i > 0) {
                      var previousBox = boxes[i - 1];
                      var box = boxes[i];
                      if (previousBox.pos + previousBox.size > box.pos) {
                          // overlapping
                          previousBox.size += box.size;
                          previousBox.targets = previousBox.targets.concat(box.targets);
                          // overflow, shift up
                          if (previousBox.pos + previousBox.size > totalH) {
                              previousBox.pos = totalH - previousBox.size;
                          }
                          boxes.splice(i, 1); // removing box
                          overlapping = true;
                      }
                  }
              }
          }
          i = 0;
          boxes.forEach(function (b) {
              var posInCompositeBox = startY; // middle of the label
              b.targets.forEach(function () {
                  half[i].y = b.pos + posInCompositeBox + _this.options.lineHeight / 2;
                  posInCompositeBox += _this.options.lineHeight;
                  i++;
              });
          });
          var drawnLabels = [];
          half.forEach(function (label) {
              var textGroup = _this._drawLabel(label);
              _this._drawLabelLine(label, maxLabelWidth, textGroup);
              drawnLabels.push(textGroup);
          });
      };
      SpiderLabel.prototype._drawLabel = function (label) {
          var coord = this.coord;
          var center = coord.getCenter();
          var radius = coord.getRadius();
          var y = label.y, textGroup = label.textGroup;
          var children = textGroup.get('children');
          var x_dir = label._side === 'left' ? 1 : -1;
          var textAttrs = {
              textAlign: label._side === 'left' ? 'right' : 'left',
              x: label._side === 'left'
                  ? center.x - radius - this.options.sidePadding
                  : center.x + radius + this.options.sidePadding,
          };
          if (this.options.offsetX) {
              textAttrs.x += this.options.offsetX * x_dir;
          }
          children.forEach(function (child) {
              var offsetY = child.get('offsetY');
              var yPosition = y + offsetY;
              child.attr(textAttrs);
              child.attr('y', yPosition);
          });
          return textGroup;
      };
      SpiderLabel.prototype._drawLabelLine = function (label, maxLabelWidth, container) {
          var _anchor = [label._anchor.x, label._anchor.y];
          var _inflection = [label._inflection.x, label._inflection.y];
          var y = label.y, textGroup = label.textGroup;
          if (!textGroup)
              return;
          var lastPoint = [label._side === 'left' ? textGroup.getBBox().maxX + 4 : textGroup.getBBox().minX - 4, y];
          var points = [_anchor, _inflection, lastPoint];
          if (_inflection[1] !== y) {
              // 展示全部文本文本位置做过调整
              if ((_inflection[1] < this.height / 2 && _inflection[1] < y) ||
                  (_inflection[1] >= this.height / 2 && _inflection[1] > y)) {
                  // 文本被调整下去了，则添加拐点连接线
                  var point1 = _inflection;
                  var leftPoint = lastPoint[0] + ADJUSTOFFSET;
                  var rightPoint = lastPoint[0] - ADJUSTOFFSET;
                  var point2 = [label._side === 'left' ? leftPoint : rightPoint, _inflection[1]];
                  points = [_anchor, point1, point2, lastPoint];
                  if ((label._side === 'right' && point2[0] < point1[0]) || (label._side === 'left' && point2[0] > point1[0])) {
                      points = [_anchor, point1, lastPoint];
                  }
              }
              else {
                  points = [_anchor, [_inflection[0], y], lastPoint];
              }
          }
          var path = [];
          for (var i = 0; i < points.length; i++) {
              var p = points[i];
              var starter = 'L';
              if (i === 0) {
                  starter = 'M';
              }
              path.push([starter, p[0], p[1]]);
          }
          container.addShape('path', {
              attrs: {
                  path: path,
                  lineWidth: this.options.line.lineWidth,
                  stroke: this.options.line.stroke,
              },
          });
          // 绘制锚点
          // container.addShape('circle', {
          //   attrs: {
          //     x: _anchor[0],
          //     y: _anchor[1],
          //     r: this.config.anchorSize,
          //     fill,
          //   },
          // });
      };
      SpiderLabel.prototype._adjustOptions = function (config) {
          if (config.text.fontSize) {
              config.lineHeight = config.text.fontSize * 3;
          }
      };
      return SpiderLabel;
  }());
  export default SpiderLabel;
  //# sourceMappingURL=spider-label.js.map