SYNCERのロゴ
アイキャッチ画像

円グラフを描く方法

Canvasで円グラフ(pie chart)を描くには、arc()の開始角度と終了角度を調整しましょう。

サンプルコード

例えば、A(50%)、B(33%)、C(17%)という3つのデータを円グラフにするには、まずは360度を100%とした時の角度に換算しましょう。

// A: 50%
var angleA = 360 * ( 50 / 100 ) ;

// B: 33%
var angleB = 360 * ( 33 / 100 ) ;

// C: 17%
var angleC = 360 * ( 17 / 100 ) ;

角度が判明したら、各データの角度を、円の開始角度と終了角度に反映していくだけです。欠けた円の集まりが円グラフになるというわけです。

// element = <canvas width="200" height="200"></canvas>
var context = element.getContext( "2d" ) ;

// A: (0〜angleA)
context.beginPath () ;
context.arc( 100, 100, 100, 0 * Math.PI / 180, angleA * Math.PI / 180, false ) ;
context.lineTo( 100, 100 ) ;
context.fillStyle = "red" ;
context.fill() ;

// B: (angleA〜(angleA + angleB))
context.beginPath () ;
context.arc( 100, 100, 100, angleA * Math.PI / 180, (angleA + angleB) * Math.PI / 180, false ) ;
context.lineTo( 100, 100 ) ;
context.fillStyle = "blue" ;
context.fill() ;

// C: ((angleA + angleB)〜(angleA + angleB + angleC))
context.beginPath () ;
context.arc( 100, 100, 100, (angleA + angleB) * Math.PI / 180, (angleA + angleB + angleC) * Math.PI / 180, false ) ;
context.lineTo( 100, 100 ) ;
context.fillStyle = "green" ;
context.fill() ;

デモ

処理を分かりやすくするために冗長なコードになっていますが、似た処理は関数などにしてまとめて下さいね。

円グラフの作成例

// element = <canvas id="target" width="200" height="200"></canvas>
var element = document.getElementById( "target" ) ;
var context = element.getContext( "2d" ) ;

var angleA = 360 * ( 50 / 100 ) ;
var angleB = 360 * ( 33 / 100 ) ;
var angleC = 360 * ( 17 / 100 ) ;

context.beginPath () ;
context.arc( 100, 100, 100, 0 * Math.PI / 180, angleA * Math.PI / 180, false ) ;
context.lineTo( 100, 100 ) ;
context.fillStyle = "red" ;
context.fill() ;

context.beginPath () ;
context.arc( 100, 100, 100, angleA * Math.PI / 180, (angleA + angleB) * Math.PI / 180, false ) ;
context.lineTo( 100, 100 ) ;
context.fillStyle = "blue" ;
context.fill() ;

context.beginPath () ;
context.arc( 100, 100, 100, (angleA + angleB) * Math.PI / 180, (angleA + angleB + angleC) * Math.PI / 180, false ) ;
context.lineTo( 100, 100 ) ;
context.fillStyle = "green" ;
context.fill() ;

200x200のキャンパスです。

全体の角度を調整する

Canvasでは開始位置(0度)は真上ではなく右です。これだと不自然という場合は、各角度から90度を減算しましょう。そうではなく、一番最後に全体の角度を傾ける方法もあります。都合の良い方法を採用して下さい。

// element = <canvas id="target" width="200" height="200"></canvas>
var element = document.getElementById( "target" ) ;
var context = element.getContext( "2d" ) ;

context.beginPath () ;

var angleA = 360 * ( 50 / 100 ) ;
var angleB = 360 * ( 33 / 100 ) ;
var angleC = 360 * ( 17 / 100 ) ;

context.beginPath () ;
context.arc( 100, 100, 100, (0 - 90) * Math.PI / 180, (angleA - 90) * Math.PI / 180, false ) ;
context.lineTo( 100, 100 ) ;
context.fillStyle = "red" ;
context.fill() ;

context.beginPath () ;
context.arc( 100, 100, 100, (angleA - 90) * Math.PI / 180, ((angleA + angleB) - 90) * Math.PI / 180, false ) ;
context.lineTo( 100, 100 ) ;
context.fillStyle = "blue" ;
context.fill() ;

context.beginPath () ;
context.arc( 100, 100, 100, ((angleA + angleB) - 90) * Math.PI / 180, ((angleA + angleB + angleC) - 90) * Math.PI / 180, false ) ;
context.lineTo( 100, 100 ) ;
context.fillStyle = "green" ;
context.fill() ;

200x200のキャンパスです。

枠線を付ける

枠線を付けるには、全てを塗りつぶした後に全く同じパスで線を描きましょう。

// element = <canvas id="target" width="200" height="200"></canvas>
var element = document.getElementById( "target" ) ;
var context = element.getContext( "2d" ) ;

context.beginPath () ;

var angleA = 360 * ( 50 / 100 ) ;
var angleB = 360 * ( 33 / 100 ) ;
var angleC = 360 * ( 17 / 100 ) ;

// 塗りつぶし
context.beginPath () ;
context.arc( 100, 100, 100, (0 - 90) * Math.PI / 180, (angleA - 90) * Math.PI / 180, false ) ;
context.lineTo( 100, 100 ) ;
context.fillStyle = "red" ;
context.fill() ;

context.beginPath () ;
context.arc( 100, 100, 100, (angleA - 90) * Math.PI / 180, ((angleA + angleB) - 90) * Math.PI / 180, false ) ;
context.lineTo( 100, 100 ) ;
context.fillStyle = "blue" ;
context.fill() ;

context.beginPath () ;
context.arc( 100, 100, 100, ((angleA + angleB) - 90) * Math.PI / 180, ((angleA + angleB + angleC) - 90) * Math.PI / 180, false ) ;
context.lineTo( 100, 100 ) ;
context.fillStyle = "green" ;
context.fill() ;

// 線
context.beginPath () ;
context.arc( 100, 100, 100, (0 - 90) * Math.PI / 180, (angleA - 90) * Math.PI / 180, false ) ;
context.lineTo( 100, 100 ) ;
context.lineWidth = 3 ;
context.strokeStyle = "white" ;
context.stroke() ;

context.beginPath () ;
context.arc( 100, 100, 100, (angleA - 90) * Math.PI / 180, ((angleA + angleB) - 90) * Math.PI / 180, false ) ;
context.lineTo( 100, 100 ) ;
context.lineWidth = 3 ;
context.strokeStyle = "white" ;
context.stroke() ;

context.beginPath () ;
context.arc( 100, 100, 100, ((angleA + angleB) - 90) * Math.PI / 180, ((angleA + angleB + angleC) - 90) * Math.PI / 180, false ) ;
context.lineTo( 100, 100 ) ;
context.lineWidth = 3 ;
context.strokeStyle = "white" ;
context.stroke() ;

200x200のキャンパスです。

  • Twitterでシェア
  • Facebookでシェア
  • Google+でシェア
  • はてなブックマークでシェア
  • pocketに保存
  • LINEでシェア
更新履歴
2017年8月6日 (日)
コンテンツを公開しました。