この記事は、ニフティグループ Advent Calendar 2023 14日目の記事です。
はじめまして。新卒1年目の高田です。
弊社にはジョブローテーションという制度があり、新卒で入社した社員は様々な部署を数ヶ月単位で横断します。
その中で私は未経験でアプリ開発に着手させていただいており、今回はそこでの学びの一つをブログとして執筆していきたいと思います。
作るもの
それでは、タイトル通り円グラフを描画してみます。
今回は、下図のような図形を作っていきます。
アニメーションをつけるとこんな感じ
まずは円弧を描いてみる
まずは、円弧を描くところから始めましょう。
描画にはCanvasのdrawArcを使用します。
startAngleで開始地点を指定して、sweepAngleで弧の角度を指定します。そうすると、指定した開始地点から時計回りに描画をしてくれます。例えば、開始地点を0度、角度を270度に設定すると下図のような円を描くことができます。
1 2 3 4 5 6 7 8 9 10 11 |
Canvas(modifier = Modifier.size(200.dp)) { drawArc( color = Color.Red, startAngle = 0f, sweepAngle = 270f, useCenter = false, style = Stroke( width = 20.dp.toPx() ) ) } |
グラフっぽくする
円弧の描画を少し応用して、グラフを作ってみます。
以下の実装では、それぞれの円弧を組み合わせて、円を構成させるということをしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// テスト用のデータを用意する val data :List<Float> = listOf(20f, 15f, 5f, 10f) // 描画用のデータに変換する val sweepAngleList: List<Float> = data.map { 360f * it / data.sum() } val colorList: List<Color> = listOf( Color.Red, Color.Blue, Color.Green, Color.LightGray, ) val pieChartData: List<Pair<Color, Float>> = colorList.zip(sweepAngleList) // グラフを描画する pieChartData.forEachIndexed { _, data -> drawArc( color = data.first, startAngle = -90f, sweepAngle = data.second, useCenter = false, style = Stroke(width = chartBarWidth.toPx(), cap = StrokeCap.Butt) ) startAngle += data.second } |
円グラフっぽくなりましたね!?
静止画だけで良い人はここまで。
最後にアニメーションをつけて少し豪華にしていきます。
アニメーションもつけて豪華にする
ここからアニメーションをつけて少し豪華にします。
もっと良い実装方法があるのかな〜とは思いますが、筆者は以下のように実装を進めてみました。
以下の実装では、Animatable
のリストを作成し、それぞれの円弧に対して遅延して順番にアニメーションを適用することで、円弧が描画されているようなアニメーションを実現しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
// Animatableのlistを作成する val animaTableList = List(datasets.size) { remember { Animatable(0f) } } animaTableList.forEachIndexed { index, animaTable -> LaunchedEffect(animaTable) { // 各アニメーションを遅延させる delay(index * 600L) animaTable.animateTo( targetValue = 1f, animationSpec = tween( durationMillis = 600, easing = LinearEasing ) ) } } Canvas(modifier = Modifier.size(radiusOuter)) { var startAngle = -90f // 各円弧に順番にanimaTableListを適用して、描画順にアニメーションを再生させる pieChartData.forEachIndexed { index, data -> drawArc( color = data.first, startAngle = startAngle, sweepAngle = data.second * animaTableList[index].value, useCenter = false, style = Stroke( width = chartBarWidth.toPx(), cap = StrokeCap.Butt ) ) startAngle += data.second } } |
どうでしょうか?それっぽいアニメーションになってますかね!?
最後に
「Androidでアニメーション付き円グラフを作ってみよう」ということで、円弧の描画から円グラフへのちょっとした応用までやってみました。
もっといい方法をお前に教えてやるぜ!という方がいましたら、下記リンクからコンタクトをどうぞ!
(冗談です)
明日は、dev-shimadaさんの「ログのエラー検知をノーコードでslackに通知してみる」です。
お楽しみに!