F.S*_*SO7 6 charts dart flutter flutter-dependencies flutter-layout
我正在尝试构建一个饼图,如下所示:
我已经尝试过Flutter_Charts和FL_Chart,但似乎都不支持饼图中的圆角和间隔项目。
有谁知道实现这种饼图设计的最佳方法是什么?
谢谢你!
小智 1
使用CustomPaint小部件可以轻松实现与图表非常相似的版本。
要实现这一点,您只需要一个非常基本的CustomPainter,它可以在画布上绘制弧线。舍入效果是通过用于绘制描边的Paint的StrokeCap属性来实现的。遗憾的是StrokeCap仅支持圆形和方形笔画结尾。
通过这种方式无法实现像您的屏幕截图中那样的圆角矩形效果。
颜色是通过对每个笔画使用单独的Paint来实现的。
// this is used to pass data about chart values to the widget
class PieChartData {
const PieChartData(this.color, this.percent);
final Color color;
final double percent;
}
// our pie chart widget
class PieChart extends StatelessWidget {
PieChart({
required this.data,
required this.radius,
this.strokeWidth = 8,
this.child,
Key? key,
}) : // make sure sum of data is never ovr 100 percent
assert(data.fold<double>(0, (sum, data) => sum + data.percent) <= 100),
super(key: key);
final List<PieChartData> data;
// radius of chart
final double radius;
// width of stroke
final double strokeWidth;
// optional child; can be used for text for example
final Widget? child;
@override
Widget build(context) {
return CustomPaint(
painter: _Painter(strokeWidth, data),
size: Size.square(radius),
child: SizedBox.square(
// calc diameter
dimension: radius * 2,
child: Center(
child: child,
),
),
);
}
}
// responsible for painting our chart
class _PainterData {
const _PainterData(this.paint, this.radians);
final Paint paint;
final double radians;
}
class _Painter extends CustomPainter {
_Painter(double strokeWidth, List<PieChartData> data) {
// convert chart data to painter data
dataList = data
.map((e) => _PainterData(
Paint()
..color = e.color
..style = PaintingStyle.stroke
..strokeWidth = strokeWidth
..strokeCap = StrokeCap.round,
// remove padding from stroke
(e.percent - _padding) * _percentInRadians,
))
.toList();
}
static const _percentInRadians = 0.062831853071796;
// this is the gap between strokes in percent
static const _padding = 4;
static const _paddingInRadians = _percentInRadians * _padding;
// 0 radians is to the right, but since we want to start from the top
// we'll use -90 degrees in radians
static const _startAngle = -1.570796 + _paddingInRadians / 2;
late final List<_PainterData> dataList;
@override
void paint(Canvas canvas, Size size) {
final rect = Offset.zero & size;
// keep track of start angle for next stroke
double startAngle = _startAngle;
for (final data in dataList) {
final path = Path()..addArc(rect, startAngle, data.radians);
startAngle += data.radians + _paddingInRadians;
canvas.drawPath(path, data.paint);
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return oldDelegate != this;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以查看dartpad来尝试一个工作示例。
我确信您在该图片中提供的相同图表可以使用 CustomPainter 实现,但这会复杂得多。
| 归档时间: |
|
| 查看次数: |
2492 次 |
| 最近记录: |