init method

  1. @override
void init(
  1. ChartsState state
)

初始化 耗时的方法都可以放到这里

Implementation

@override
void init(ChartsState state) {
  _ChartCircularCoordinateState layout = state.layout as _ChartCircularCoordinateState;

  super.init(state);
  _linePathList.clear();
  _borderLinePaths.clear();
  _textPainterList.clear();
  _dataLinePathList.clear();

  int itemLength = data.length;
  double percent = 1 / itemLength;
  // 计算出每个数据所占的弧度值
  _sweepAngle = percent * math.pi * 2 * (direction == RotateDirection.forward ? 1 : -1);

  if (fillColors != null) {
    _fillDataLinePaint = Paint()
      ..isAntiAlias = true
      ..style = PaintingStyle.fill;
  }

  //图例
  List<dynamic>? legendList = legendFormatter?.call();
  Offset center = layout.center;
  double radius = layout.radius;
  //开始点
  double startAngle = this.startAngle;

  if (borderStyle == RadarBorderStyle.polygon) {
    _borderLinePaths = List.generate(count, (index) => Path());
  }
  double dividerRadius = layout.radius / count;

  for (int i = 0; i < itemLength; i++) {
    T itemData = data[i];
    //画边框
    final x = math.cos(startAngle) * radius + center.dx;
    final y = math.sin(startAngle) * radius + center.dy;
    _linePathList.add(Path()
      ..moveTo(center.dx, center.dy)
      ..lineTo(x, y));

    //画分隔线
    if (borderStyle == RadarBorderStyle.polygon) {
      for (int ii = 0; ii < count; ii++) {
        final r = dividerRadius * (ii + 1);
        final x1 = math.cos(startAngle) * r + center.dx;
        final y1 = math.sin(startAngle) * r + center.dy;
        if (i == 0) {
          _borderLinePaths[ii].moveTo(x1, y1);
        } else {
          _borderLinePaths[ii].lineTo(x1, y1);
        }
      }
    }
    if (legendList != null) {
      String legend = legendList[i].toString();
      TextPainter legendTextPainter = TextPainter(
        textAlign: TextAlign.center,
        text: TextSpan(
          text: legend,
          style: legendTextStyle,
        ),
        textDirection: TextDirection.ltr,
      )..layout(
          minWidth: 0,
          maxWidth: layout.size.width,
        );
      bool isLeft = x < center.dx;
      bool isBottom = y >= center.dy;
      Offset textOffset = Offset(isLeft ? (x - legendTextPainter.width) : x, isBottom ? y : y - legendTextPainter.height);
      //最后再绘制,防止被挡住
      _textPainterList.add(RadarTextPainter(textPainter: legendTextPainter, offset: textOffset));
    }

    //画value线
    List<num> pos = values.call(itemData);
    List<dynamic>? valueLegendList = valueFormatter?.call(itemData);
    assert(valueLegendList == null || pos.length == valueLegendList.length);
    for (int j = 0; j < pos.length; j++) {
      Path? dataLinePath = _dataLinePathList[j];
      if (dataLinePath == null) {
        dataLinePath = Path();
        _dataLinePathList[j] = dataLinePath;
      }
      num subPos = pos[j];
      double vp = subPos / max;
      double newRadius = radius * vp;
      final dataX = math.cos(startAngle) * newRadius + center.dx;
      final dataY = math.sin(startAngle) * newRadius + center.dy;
      if (i == 0) {
        dataLinePath.moveTo(dataX, dataY);
      } else {
        dataLinePath.lineTo(dataX, dataY);
      }

      //画文案
      if (valueLegendList != null) {
        String legend = valueLegendList[j].toString();
        TextPainter legendTextPainter = TextPainter(
          textAlign: TextAlign.center,
          text: TextSpan(
            text: legend,
            style: legendTextStyle,
          ),
          textDirection: TextDirection.ltr,
        )..layout(
            minWidth: 0,
            maxWidth: layout.size.width,
          );
        bool isLeft = dataX < center.dx;
        bool isTop = dataY <= (center.dy - radius) && legendList != null;
        Offset textOffset = Offset(isLeft ? (dataX - legendTextPainter.width) : dataX, isTop ? dataY : dataY - legendTextPainter.height);
        //最后再绘制,防止被挡住
        _textPainterList.add(RadarTextPainter(textPainter: legendTextPainter, offset: textOffset));
      }
    }
    //继续下一个
    startAngle = startAngle + _sweepAngle;
  }

  if (borderStyle == RadarBorderStyle.polygon) {
    for (var element in _borderLinePaths) {
      element.close();
    }
  }
}