有没有使用 StageXL 绘制饼图的简单方法?
我想唯一的其他选择(如果我希望空切片是透明的)是绘制一个矢量饼图并填充它。
我不知道是否有更简单的方法,但您可以使用 ArcTo() 实现一个,如下所示:
import 'dart:math' as Math;
import 'package:stagexl/stagexl.dart';
void main() {
// setup the Stage and RenderLoop
var canvas = html.querySelector('#stage');
var stage = new Stage(canvas);
var renderLoop = new RenderLoop();
renderLoop.addStage(stage);
List<Entry> entries = new List<Entry>();
for(int i=1;i<=5;i++){
entries.add(new Entry(i, "fgfgfgfgf ${i}"));
}
PieChart c = new PieChart(200, 200, 100, entries);
stage.addChild(c);
}
class Entry {
num val;
String name;
Entry(this.val, this.name);
}
class PieChart extends DisplayObjectContainer{
num centerX;
num centerY;
num radius;
List<int> _colors = [Color.Red, Color.Blue, Color.Green, Color.Yellow, Color.Cyan];
int _c_index = 0;
int get nextColor => _colors[_c_index=(++_c_index%_colors.length)];
List<Entry> entries;
PieChart(this.centerX, this.centerY, this.radius, this.entries){
num sum = 0;
for(Entry e in entries){
sum+=e.val;
}
num angle = 0;
for(Entry e in entries){
addChild(new LabledPiePiece(this, angle, angle+=(e.val/sum)*360, nextColor, e));
}
}
}
class LabledPiePiece extends DisplayObjectContainer{
LabledPiePiece(PieChart pie, num startAngleDeg, num endAngleDeg, int color, Entry e){
num hDeg = (startAngleDeg+endAngleDeg)/2;
addChild(new PiePieceHalf(pie, startAngleDeg, hDeg, color));
addChild(new PiePieceHalf(pie, hDeg, endAngleDeg, color));
TextField t = new TextField(e.name);
t.defaultTextFormat = new TextFormat('Arial', 16, Color.Black, align:TextFormatAlign.CENTER);
t.y = pie.centerY+(pie.radius+t.textHeight)*Math.sin(hDeg/180*Math.PI);
t.x = pie.centerX+(pie.radius+t.textHeight)*Math.cos(hDeg/180*Math.PI);
t.rotation = hDeg/180*Math.PI+Math.PI/2;
t.y = t.y - t.width*Math.sin(t.rotation)/2;
t.x = t.x - t.width*Math.cos(t.rotation)/2;
addChild(t);
}
}
/**
* draws a pie piece with max 180deg;
*/
class PiePieceHalf extends Shape{
PieChart pie;
num get centerX => pie.centerX;
num get centerY => pie.centerY;
num get radius => pie.radius;
num startAngleRad;
num endAngleRad;
int color;
PiePieceHalf(this.pie, num startAngleDeg, num endAngleDeg, this.color){
this.startAngleRad = startAngleDeg/180*Math.PI;
this.endAngleRad = endAngleDeg/180*Math.PI;
draw();
}
void draw() {
num controlAngle = (startAngleRad+endAngleRad)/2;
num controlDist = radius/(Math.cos(startAngleRad-controlAngle));
num controlX = centerX+Math.cos(controlAngle)*controlDist;
num controlY = centerY+Math.sin(controlAngle)*controlDist;
graphics.beginPath();
graphics.moveTo(centerX, centerY);
graphics.lineTo(centerX+Math.cos(startAngleRad)*radius, centerY+Math.sin(startAngleRad)*radius);
graphics.arcTo(controlX, controlY, centerX+Math.cos(endAngleRad)*radius, centerY+Math.sin(endAngleRad)*radius, radius);
graphics.lineTo(centerX, centerY);
graphics.closePath();
graphics.strokeColor(color);
graphics.fillColor(color);
}
}
这段代码并不完美,但它可以工作......除非你只添加一个馅饼......但处理这种情况应该不难......而且添加 EmptyPiePieces 应该不难...... .你只需要扩展条目......也许通过条目使颜色可配置也不会太糟糕......