チャートを作ってみる
ここまでで基本的なCanvasの使い方は分かったと思うので、ここからはより具体的な例として、折れ線チャートを作成してみます。
折れ線チャートを作成する
図7のような折れ線チャートを記述する場合の例を紹介します。
リスト5がサンプルコードです。
class LineChartPainter extends CustomPainter{
@override
void paint(Canvas canvas, Size size) {
// (1)Gridを記述するために変更
canvas.save();
canvas.translate(20, size.height - 20);
canvas.scale(1, -1);
// (2)軸を記述する
// Grid線を記述する
for(double i = 0.0; i < size.width - 40; i = i + 20.0) {
canvas.drawLine(Offset(i,0), Offset(i,size.height - 40) , paint1);
}
for(double i = 0.0; i < size.height - 40; i += 20.0){
canvas.drawLine(Offset(0,i), Offset(size.width - 40,i) , paint1);
}
// (省略)
canvas.drawLine(const Offset(0,0),Offset(size.width - 40,0),paint2);
canvas.drawLine(const Offset(0,0),Offset(0,size.height - 40),paint2);
// (3)線を指定
Paint paint3 = Paint()
..color = Colors.red
..style = PaintingStyle.stroke
..strokeWidth = 2
..strokeCap = StrokeCap.square;
// (4)折れ線を記述
Path path = Path()
..moveTo(0.0, 0.0)
..lineTo(80.0, 140.0)
..lineTo(160.0, 60.0)
..lineTo(250.0, 430.0)
..lineTo(300.0, 130.0);
canvas.drawPath(path, paint3);
Paint paint4 = Paint()
..color = Colors.white;
// (5)プロットを記述
canvas.drawCircle(const Offset(80.0,140.0), 5, paint4);
// 点を記述
// : 省略
// (6)テキストを記述
canvas.restore();
drawPointText(canvas, 80.0, 140.0, size);
// : 省略
}
// (7)文字の描写
void drawPointText(Canvas canvas,double x,double y, Size size){
String label = "($x,$y)";
TextSpan span = TextSpan(
style: const TextStyle(
// (省略)
),
children: [
TextSpan(text: label)
]
);
// (8)テキストの表示
TextPainter tp = TextPainter(
text: span,
textDirection: TextDirection.ltr
);
// (9)テキストのレイアウト制約
tp.layout(minWidth: 0,maxWidth: double.infinity);
// (10)テキストの描写
tp.paint(canvas, Offset(x + 20.0,( size.height - 40 ) - y));
}
// : (省略)
}
(1)では、まず最初にsaveメソッドでCanvasの状態を保存します。これは、この後行う中心点の移動や、また、Y座標を反転させるなどを行う前の状態が(6)以降のテキスト描写で必要になるためです。
前述したように、y軸の向きを逆にしていますので、文字を描写する際にこのままでは文字も反転してしまいます。そこで、文字を描写する前に(1)の状態をsaveメソッドで保存しておき、(6)では、そのときの状態にもどすrestoreメソッドを使います。
続いて(2)では、チャートの背景となるグリッド線とX軸とY軸の線を描写します。そして、折れ線を描写する際には、(3)でPaintのstyleをPaintingStyle.strokeに変更します。これをしないと図8のようになってしまいパスを閉じるように色が塗られてしまいます。
そして、(4)で折れ線を記述し、(5)で各点のプロットを記述しています。(6)では先ほども説明した(7)で表示するテキストが反転しないようにy軸の反転を戻しています。また、そのため、これ以降はy軸がいままでと考え方が変わってしまいますのでご注意ください。
Canvasにテキスト描写するには、(8)TextPainterを使います。また、(9)ではテキストの横幅のレイアウトを指定します。今回はデフォルトと同じ値を指定していますが、maxWidthを小さくすればテキストが改行されるようになります。そして、(10)でテキストの位置を指定して描写します。
まとめ
実際にCanvasを扱っているとAPI操作よりも数学や物理知識のほうが必要と感じることもあります。しかし、簡単なチャート程度ならライブラリを使わずとも十分なことが実感してもらえたのではないかと思います。
実際、作成するアプリのニーズに沿ったチャートを作成する場合、既存ライブラリを使った場合のデザインとの整合性やちょっと違和感の差を埋めることに時間を費やす労力を考えると自作してしまった方が楽なケースもあります。また、Canvasを使えば、既存のWidgetクラスの組み合わせでは実現が難しいアプリも作りやすくなるはずです。
