0

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

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

4

1 回答 1

3

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

于 2014-04-26T11:02:33.510 回答