Swiftで円グラフを描画!たったの10ステップで解説

Swiftで円グラフを描画するイラストSwift
この記事は約30分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

この記事を読めば、Swiftで円グラフを描画することができるようになります。

SwiftはAppleが開発したプログラミング言語で、iOSやmacOSなどのアプリケーション開発に使用されます。

円グラフはデータの比較や割合を視覚的に表現するためのグラフの一種です。

今回はSwiftを使って、円グラフを簡単に描画する手法を、初心者の方でもわかりやすく解説していきます。

●Swiftとは?

SwiftはAppleが2014年に発表した新しいプログラミング言語です。

Objective-Cに変わる新たな言語として導入され、iOSやmacOSなどのアプリケーション開発で広く利用されています。

○Swiftの基本概要

Swiftは、安全性、速度、そして表現力に重点を置いて設計されています。

これにより、開発者は効率的にコードを書くことができ、同時にそのコードは高速で実行されます。

また、Swiftは学びやすい言語であり、初心者から経験豊富な開発者まで幅広い層に対応しています。

○Swiftの特長

  1. 安全性: Swiftは、プログラマのミスを減少させるための多くの機能を持っています。例えば、変数がnilの可能性がある場合、明示的にそれを示す必要があります。
  2. 速度: Swiftは高速なLLVMコンパイラを使用しています。これにより、CやObjective-Cと比較しても、高いパフォーマンスを発揮します。
  3. モダン: Swiftは、現代のプログラミング言語の特徴を取り入れており、読みやすく、保守しやすいコードを書くことができます。
  4. プレイグラウンド: Swiftには、コードを即座に実行して結果を確認できる「プレイグラウンド」という機能があり、これにより学習や実験が非常に簡単になります。

●円グラフとは?

円グラフは、情報を視覚的に理解しやすくするための有効な手段として利用されるグラフィック表現の一つです。

その名の通り、円形のグラフにデータの比率を色やセクションで表示することで、全体としての比率や関係性を一目で理解できるように設計されています。

○円グラフの特性

円グラフは、全体を100%として、各項目の占める比率を表現します。

このため、全体に対する各項目の比率が直感的にわかるというメリットがあります。

ただし、具体的な数値や細かな比較が目的の場合は、棒グラフや折れ線グラフの方が適していることもあります。

また、円グラフは色の組み合わせやデザインによっても、視覚的な印象が大きく変わるため、デザインの選択も重要です。

○円グラフの利用シーン

  1. 予算や支出の内訳:企業の年間予算や家計の支出内訳など、全体に対する各項目の割合を知りたいときに便利です。
  2. アンケート結果の表示:ある質問に対する回答の分布を示す際に、円グラフを使うことで視覚的に分かりやすくなります。
  3. Webサイトのアクセス解析:どのページがどれだけのアクセスを集めているのか、全体に対するページごとのアクセス比率を表すのに適しています。

円グラフを効果的に使用するためには、何を目的として情報を伝えたいのか、そして受け手がどういった情報を求めているのかをしっかりと考慮することが重要です。

適切なシーンで円グラフを使用することで、情報の伝わりやすさが大幅に向上します。

●Swiftで円グラフを描画する手順

Swiftで円グラフを描画する過程は、非常に直感的で簡潔なコーディングが可能です。

初心者でも容易に取り組める内容となっています。

○サンプルコード1:基本的な円グラフの描画

Swiftで円グラフを描画するためには、UIBezierPathとCAShapeLayerを主に利用します。

UIBezierPathで円のパスを作成し、CAShapeLayerでそのパスに沿ってグラフを描画する、という手順です。

このサンプルコードは、基本的な円グラフを描画するためのものです。

import UIKit

class CircleGraphViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        drawCircleGraph(percentage: 75)
    }

    func drawCircleGraph(percentage: Int) {
        let circlePath = UIBezierPath(arcCenter: view.center, radius: 100, startAngle: .pi * -0.5, endAngle: .pi * 1.5, clockwise: true)

        // 背景のサークル
        let backgroundLayer = CAShapeLayer()
        backgroundLayer.path = circlePath.cgPath
        backgroundLayer.strokeColor = UIColor.lightGray.cgColor
        backgroundLayer.fillColor = UIColor.clear.cgColor
        backgroundLayer.lineWidth = 10
        view.layer.addSublayer(backgroundLayer)

        // パーセント表示のサークル
        let progressLayer = CAShapeLayer()
        progressLayer.path = circlePath.cgPath
        progressLayer.strokeColor = UIColor.red.cgColor
        progressLayer.fillColor = UIColor.clear.cgColor
        progressLayer.lineWidth = 10
        progressLayer.strokeEnd = CGFloat(percentage) / 100.0
        view.layer.addSublayer(progressLayer)
    }
}

このコードでは、UIBezierPathを使って円のパスを作成しています。

arcCenterで円グラフの中心位置を、radiusで半径を指定しています。

また、startAngleとendAngleで描画する角度を指定しています。

CAShapeLayerでストローク色、塗りつぶし色、線の太さなどを指定した後、viewのレイヤーに追加することで、円グラフが描画されます。

strokeEndプロパティを使って、円グラフの塗りつぶしの割合を指定しています。

ここには0.0から1.0の値を設定することで、円グラフの完成度を表現できます。

○サンプルコード2:色分けをした円グラフの描画

次に、円グラフに色分けを加える手法を紹介します。

各内訳に異なる色を割り当て、データのカテゴリを視覚的に分かりやすく表現することができます。

import UIKit

class ColoredCircleGraphViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        drawColoredCircleGraph(data: [30, 25, 45])
    }

    func drawColoredCircleGraph(data: [Int]) {
        let colors = [UIColor.red, UIColor.green, UIColor.blue]
        var startAngle = CGFloat.pi * -0.5
        let radius = CGFloat(100)

        for (index, value) in data.enumerated() {
            let circlePath = UIBezierPath(arcCenter: view.center, radius: radius, startAngle: startAngle, endAngle: startAngle + CGFloat(Double(value) / 100.0 * 2.0 * Double.pi), clockwise: true)

            let progressLayer = CAShapeLayer()
            progressLayer.path = circlePath.cgPath
            progressLayer.strokeColor = colors[index % colors.count].cgColor
            progressLayer.fillColor = UIColor.clear.cgColor
            progressLayer.lineWidth = 10
            view.layer.addSublayer(progressLayer)

            startAngle += CGFloat(Double(value) / 100.0 * 2.0 * Double.pi)
        }
    }
}

このコードでは、data配列にそれぞれの内訳のデータを格納し、それに応じて円グラフの内訳を描画しています。

UIColorの配列を用意して、それぞれの内訳に色を割り当てています。

パスの開始角度と終了角度を動的に計算して、データの割合に応じた内訳を描画しています。

それぞれの内訳が異なる色で描画され、データのカテゴリが一目で識別可能になります。

これにより、円グラフのデータが視覚的に理解しやすくなります。

○サンプルコード3:データを動的に更新する円グラフ

動的なデータの変化に対応して円グラフを更新することは、リアルタイムな情報の反映やユーザーの操作によるデータ変更など、多くのシーンで求められます。

Swiftを用いて、このような動的なデータ更新を円グラフに反映する手法を紹介します。

このサンプルコードは、ボタンをタップする度に、円グラフのデータがランダムに更新されるものです。

import UIKit

class DynamicCircleGraphViewController: UIViewController {

    var progressLayer: CAShapeLayer!

    override func viewDidLoad() {
        super.viewDidLoad()

        drawInitialCircleGraph()

        let updateButton = UIButton(frame: CGRect(x: 50, y: 400, width: 200, height: 40))
        updateButton.setTitle("データ更新", for: .normal)
        updateButton.addTarget(self, action: #selector(updateGraphData), for: .touchUpInside)
        view.addSubview(updateButton)
    }

    func drawInitialCircleGraph() {
        let circlePath = UIBezierPath(arcCenter: view.center, radius: 100, startAngle: .pi * -0.5, endAngle: .pi * 1.5, clockwise: true)

        // 背景のサークル
        let backgroundLayer = CAShapeLayer()
        backgroundLayer.path = circlePath.cgPath
        backgroundLayer.strokeColor = UIColor.lightGray.cgColor
        backgroundLayer.fillColor = UIColor.clear.cgColor
        backgroundLayer.lineWidth = 10
        view.layer.addSublayer(backgroundLayer)

        // パーセント表示のサークル
        progressLayer = CAShapeLayer()
        progressLayer.path = circlePath.cgPath
        progressLayer.strokeColor = UIColor.red.cgColor
        progressLayer.fillColor = UIColor.clear.cgColor
        progressLayer.lineWidth = 10
        view.layer.addSublayer(progressLayer)
    }

    @objc func updateGraphData() {
        let randomPercentage = CGFloat(arc4random_uniform(101)) / 100.0
        progressLayer.strokeEnd = randomPercentage
    }
}

最初に、円グラフの初期表示を行うdrawInitialCircleGraph関数を呼び出しています。

この関数内で、背景のサークルとデータを表示するためのサークルのレイヤーを準備しています。

次に、データを更新するためのボタンを画面に配置しています。

このボタンをタップすると、updateGraphData関数が呼び出され、円グラフのデータ部分がランダムなパーセントに更新されます。

○サンプルコード4:タップイベントを追加する

円グラフの内訳をタップすることで、該当するデータの詳細を表示する機能は、円グラフをさらに使いやすくする要素となります。

Swiftを使用して、タップイベントを円グラフに追加する方法をご紹介します。

このサンプルコードは、円グラフの内訳をタップした際に、該当するデータの詳細をポップアップで表示するものです。

import UIKit

class TapEventCircleGraphViewController: UIViewController {

    // 仮のデータセット
    let data = [30, 25, 45]
    let colors = [UIColor.red, UIColor.green, UIColor.blue]

    override func viewDidLoad() {
        super.viewDidLoad()
        drawCircleGraphWithTapEvent()
    }

    func drawCircleGraphWithTapEvent() {
        var startAngle = CGFloat.pi * -0.5
        let radius = CGFloat(100)

        for (index, value) in data.enumerated() {
            let endAngle = startAngle + CGFloat(Double(value) / 100.0 * 2.0 * Double.pi)
            let circlePath = UIBezierPath(arcCenter: view.center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true)

            let progressLayer = CAShapeLayer()
            progressLayer.path = circlePath.cgPath
            progressLayer.strokeColor = colors[index % colors.count].cgColor
            progressLayer.fillColor = UIColor.clear.cgColor
            progressLayer.lineWidth = 10
            view.layer.addSublayer(progressLayer)

            let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(showDataDetail(_:)))
            progressLayer.name = "Section \(index)"
            progressLayer.addGestureRecognizer(tapRecognizer)
            view.layer.addSublayer(progressLayer)

            startAngle = endAngle
        }
    }

    @objc func showDataDetail(_ sender: UITapGestureRecognizer) {
        guard let tappedLayer = sender.view as? CAShapeLayer, let sectionName = tappedLayer.name else { return }
        let alert = UIAlertController(title: "データ詳細", message: "タップしたセクション: \(sectionName)", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default))
        present(alert, animated: true)
    }
}

このコードでは、円グラフを描画する際に、それぞれの内訳にタップイベントを追加しています。

タップイベントが発生すると、showDataDetail関数が呼び出され、タップされた内訳の名前がポップアップで表示されます。

CAShapeLayerには、名前を持つプロパティnameがあり、これを利用して各内訳に名前を付けています。

そのため、どの内訳がタップされたかを識別できます。

●Swiftでの円グラフの応用例

円グラフはそのシンプルな表示方法で情報を効果的に伝えることができますが、Swiftを用いてさらに高度な応用が可能です。

ここでは、アニメーションの追加や複数の円グラフの重ね表示、ドラッグによる値の変更など、円グラフの魅力的な応用例を紹介します。

○サンプルコード5:アニメーションを追加する

円グラフにアニメーションを追加することで、データの変化やトランジションを視覚的に表現できます。

このコードでは、円グラフのデータが変更された際に滑らかなアニメーションで変化する様子を表しています。

import UIKit

class AnimatedCircleGraphViewController: UIViewController {

    var progressLayer: CAShapeLayer!

    override func viewDidLoad() {
        super.viewDidLoad()
        setupCircleGraph()

        let animateButton = UIButton(frame: CGRect(x: 50, y: 400, width: 200, height: 40))
        animateButton.setTitle("アニメーション開始", for: .normal)
        animateButton.addTarget(self, action: #selector(animateGraph), for: .touchUpInside)
        view.addSubview(animateButton)
    }

    func setupCircleGraph() {
        let circlePath = UIBezierPath(arcCenter: view.center, radius: 100, startAngle: .pi * -0.5, endAngle: .pi * 1.5, clockwise: true)

        progressLayer = CAShapeLayer()
        progressLayer.path = circlePath.cgPath
        progressLayer.strokeColor = UIColor.red.cgColor
        progressLayer.fillColor = UIColor.clear.cgColor
        progressLayer.lineWidth = 10
        progressLayer.strokeEnd = 0
        view.layer.addSublayer(progressLayer)
    }

    @objc func animateGraph() {
        let animation = CABasicAnimation(keyPath: "strokeEnd")
        animation.fromValue = 0
        animation.toValue = 1
        animation.duration = 2
        progressLayer.strokeEnd = 1
        progressLayer.add(animation, forKey: "graphAnimation")
    }
}

setupCircleGraph関数で円グラフをセットアップし、animateGraph関数が呼ばれると、円グラフがアニメーションと共に描画されます。

アニメーションは2秒間で行われ、円グラフが0%から100%まで表示されます。

○サンプルコード6:複数の円グラフを重ねて表示

複数のデータセットを一つの円グラフ上に重ねて表示することで、異なるデータの関係や比較を一目で理解しやすくなります。

import UIKit

class MultiCircleGraphViewController: UIViewController {

    let dataSets = [[40, 30, 30], [20, 50, 30]]
    let colors = [[UIColor.red, UIColor.green, UIColor.blue], [UIColor.cyan, UIColor.yellow, UIColor.magenta]]

    override func viewDidLoad() {
        super.viewDidLoad()
        drawMultipleCircleGraphs()
    }

    func drawMultipleCircleGraphs() {
        var startAngle = CGFloat.pi * -0.5
        let radius = CGFloat(100)

        for dataSet in dataSets {
            var currentStartAngle = startAngle
            for (index, value) in dataSet.enumerated() {
                let endAngle = currentStartAngle + CGFloat(Double(value) / 100.0 * 2.0 * Double.pi)
                let circlePath = UIBezierPath(arcCenter: view.center, radius: radius, startAngle: currentStartAngle, endAngle: endAngle, clockwise: true)

                let progressLayer = CAShapeLayer()
                progressLayer.path = circlePath.cgPath
                progressLayer.strokeColor = colors[index % colors.count].cgColor
                progressLayer.fillColor = UIColor.clear.cgColor
                progressLayer.lineWidth = 10
                view.layer.addSublayer(progressLayer)

                currentStartAngle = endAngle
            }
        }
    }
}

このコードでは、2つのデータセットを用いて、円グラフを2つ重ねて描画しています。

それぞれのデータセットに対して異なる色を使用していますので、2つの円グラフがどのように重なっているかが分かります。

○サンプルコード7:ドラッグでの値の変更を実現

ユーザーが直接グラフ上でドラッグ操作を行うことで、データの値を変更することができる円グラフも実装することが可能です。

このような機能は、リアルタイムでのデータの変更やアジャストが求められる場面で非常に役立ちます。

import UIKit

class DraggableCircleGraphViewController: UIViewController {

    var currentValue: CGFloat = 0.5
    let circleLayer = CAShapeLayer()

    override func viewDidLoad() {
        super.viewDidLoad()
        setupCircleGraph()
        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan))
        view.addGestureRecognizer(panGesture)
    }

    func setupCircleGraph() {
        let circlePath = UIBezierPath(arcCenter: view.center, radius: 100, startAngle: .pi * -0.5, endAngle: .pi * 1.5, clockwise: true)

        circleLayer.path = circlePath.cgPath
        circleLayer.strokeColor = UIColor.red.cgColor
        circleLayer.fillColor = UIColor.clear.cgColor
        circleLayer.lineWidth = 10
        circleLayer.strokeEnd = currentValue
        view.layer.addSublayer(circleLayer)
    }

    @objc func handlePan(gesture: UIPanGestureRecognizer) {
        let location = gesture.location(in: view)
        let dx = location.x - view.center.x
        let dy = location.y - view.center.y
        let angle = atan2(dy, dx)
        let normalizedValue = (angle + .pi * 0.5) / (2 * .pi)
        currentValue = max(0, min(1, normalizedValue))

        circleLayer.strokeEnd = currentValue
    }
}

handlePan関数が呼ばれると、ユーザーがドラッグした位置に基づいて円グラフの値が変更されます。

この方法で、円グラフ上でのドラッグ操作による値の変更をリアルタイムで反映させることができます。

●注意点と対処法

Swiftを使用して円グラフを描画する際には、いくつか注意点があります。

正確なデータの表示や、円グラフの描画時のパフォーマンスに関してのヒントも合わせて解説します。

○データの正確性を保つ方法

円グラフはデータの比率を視覚的に表現するのに適していますが、不正確なデータや間違った計算に基づく円グラフは、誤った情報を伝えてしまう恐れがあります。

そのため、次のような手順でデータの正確性を保つことが推奨されます。

  1. ソースとなるデータの信頼性を確認する:使用するデータの出典や信頼性をしっかりと確認してください。
  2. 計算の際の丸め誤差に注意する:データの比率を計算する際に生じる丸め誤差に注意し、可能な限り正確な計算を行うよう努力します。特に、多くのデータセットを扱う場合には、丸め誤差が積み重なることで大きな誤差が生じる可能性があります。
  3. データの更新を定期的に行う:情報が変わる可能性がある場合、定期的なデータの更新を行うことで、円グラフの情報を常に正確に保つことができます。

○パフォーマンスの向上のためのヒント

特に大量のデータや複数の円グラフを同時に表示する場合、円グラフの描画に時間がかかることがあります。

下記のヒントを参考に、円グラフの描画パフォーマンスを向上させることができます。

  1. 描画範囲の最適化:必要な部分だけを描画することで、無駄な計算や描画を省き、パフォーマンスを向上させることができます。
  2. 描画品質の調整:高品質な描画は時間がかかるため、表示の品質とパフォーマンスのバランスを考慮し、必要な品質での描画を心がけてください。
  3. データの前処理:データの計算や変換を事前に行うことで、描画時の負荷を軽減することができます。

●円グラフのカスタマイズ方法

円グラフはその形状や色、ラベルなど、多岐にわたる部分をカスタマイズすることができます。

Swiftを用いた円グラフのカスタマイズ方法について、詳しく解説していきます。

○サンプルコード8:ラベルのスタイル変更

円グラフのラベルは、データの値やカテゴリ名を表示する重要な要素です。

下記のサンプルコードでは、ラベルのフォントサイズや色を変更しています。

import UIKit

class GraphViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        let pieChartView = PieChartView()
        pieChartView.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
        pieChartView.center = view.center

        // データセットの作成
        let dataEntries = [PieChartDataEntry(value: 40, label: "A"), 
                           PieChartDataEntry(value: 30, label: "B"), 
                           PieChartDataEntry(value: 30, label: "C")]

        let dataSet = PieChartDataSet(entries: dataEntries)
        dataSet.colors = [UIColor.red, UIColor.blue, UIColor.green]

        // ラベルのスタイル変更
        dataSet.valueFont = UIFont(name: "Arial", size: 14)!
        dataSet.valueTextColor = UIColor.black

        pieChartView.data = PieChartData(dataSet: dataSet)
        view.addSubview(pieChartView)
    }
}

このコードでは、Arialフォントのサイズ14でラベルを表示し、ラベルのテキストカラーを黒に設定しています。

結果として、円グラフの各セクションにはA、B、Cというラベルが、指定したスタイルで表示されます。

○サンプルコード9:円グラフの大きさや位置の調整

円グラフの大きさや位置を調整することで、画面のレイアウトに合わせて最適な表示を実現できます。

下記のコードは、円グラフの大きさと位置を変更する例を表しています。

import UIKit

class GraphViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        let pieChartView = PieChartView()

        // 円グラフの大きさと位置を設定
        pieChartView.frame = CGRect(x: 50, y: 100, width: 250, height: 250)

        // データセットの作成と設定
        let dataEntries = [PieChartDataEntry(value: 40, label: "A"), 
                           PieChartDataEntry(value: 30, label: "B"), 
                           PieChartDataEntry(value: 30, label: "C")]
        let dataSet = PieChartDataSet(entries: dataEntries)
        dataSet.colors = [UIColor.red, UIColor.blue, UIColor.green]

        pieChartView.data = PieChartData(dataSet: dataSet)
        view.addSubview(pieChartView)
    }
}

このコードの結果、円グラフは画面の左上から(x: 50, y: 100)の位置に、幅250、高さ250の大きさで表示されます。

○サンプルコード10:独自のデザインを適用する

Swiftと関連ライブラリを使用することで、独自のデザインやアニメーションを円グラフに適用することも可能です。

ここでは、独特なグラデーションの色をセクションに適用するサンプルコードを紹介します。

import UIKit

class GraphViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        let pieChartView = PieChartView()
        pieChartView.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
        pieChartView.center = view.center

        // データセットの作成
        let dataEntries = [PieChartDataEntry(value: 40, label: "A"), 
                           PieChartDataEntry(value: 30, label: "B"), 
                           PieChartDataEntry(value: 30, label: "C")]

        let dataSet = PieChartDataSet(entries: dataEntries)

        // グラデーションの色を設定
        let color1 = UIColor.red
        let color2 = UIColor.blue
        let gradientColor = [color1.cgColor, color2.cgColor] as CFArray
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColor, locations: [0.0, 1.0])!

        dataSet.setColors(UIColor(patternImage: gradient.createImage()!), UIColor.green, UIColor.yellow)

        pieChartView.data = PieChartData(dataSet: dataSet)
        view.addSubview(pieChartView)
    }
}

このコードでは、Aのセクションに赤と青のグラデーションを適用し、他のセクションにはそれぞれ緑と黄色を適用しています。

これにより、一つのセクションに異なる色のグラデーションを持つ独自のデザインの円グラフが表示されます。

まとめ

Swiftを使用して円グラフを描画する方法は、初心者でも手軽に実現できることを今回の記事で解説してきました。

具体的なサンプルコードを通じて、基本的な円グラフの描画から、さまざまなカスタマイズ方法までを詳しく解説しました。

特に、独自のデザインやアニメーションの適用方法は、アプリのユーザビリティやデザイン性を向上させる上で非常に役立ちます。

また、円グラフの表示に関する注意点やパフォーマンスの向上のためのヒント、データの正確性を保つ方法など、円グラフのクオリティを向上させるための情報も提供しました。

これらの情報をもとに、ユーザーが円グラフのデータを正確に理解できるような円グラフを作成することができます。

円グラフは、データの比較や分析を視覚的に伝える強力なツールです。

Swiftを活用して、自分のアプリやサービスに最適な円グラフを実装し、より多くのユーザーに情報を効果的に伝えることができるでしょう。