饼图使用StageXL?

时间:2014-04-25 15:42:49

标签: dart stagexl

使用StageXL绘制饼图有简单的方法吗?

我想唯一的另一个选择(如果我希望空切片是透明的)是绘制一个矢量饼图并填充它。

1 个答案:

答案 0 :(得分:2)

我不知道是否有更简单的方法,但你可以使用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 ...你只需要扩展条目...也许通过条目使颜色可配置也​​不会太糟糕...