init method
初始化 耗时的方法都可以放到这里
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();
}
}
}