まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

2018年03月

Chart.js は棒グラフや折れ線グラフなどの各種グラフやチャートを描画するための JavaScript ライブラリです。グラフを描くだけならかなり簡単に使うことができて便利です。また MIT ライセンスが採用されており、商用を含めた柔軟な利用が可能になっています。

今回はこの Chart.js を使って「ポーラーチャート」を作る例を紹介します:
ogp


ポーラーチャートは円グラフやドーナツグラフに似ています。円グラフやドーナツグラフでは円全体を 100% と見なして、その中の割合を(色別などに)分類表示する、というものです。 一方ポーラーチャートでは量が多いほど大きな面積で表示されます。存在している要素が全て同じ角度を持ったパイの形で表示されるため、仮に特定の要素の値がゼロでもゼロであることがわかりやすくなっている(※)という特徴があります。

※上図の例だと左上に紫色っぽい部分がほんの少しだけ存在しています。量が少なくてグラフ上ではほぼ見えていないのですが、ここに空間ができることで少なくともここにデータが存在していることが明確になっています。


このポーラーチャートを Chart.js で表示するには以下のようなコードを記述します。Chart 作成時の type 属性に 'polarArea' を指定することでポーラーチャートを描画します:
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.3/Chart.min.js"></script>

  :
  :

<canvas id="myChart"></canvas>

  :
  :

<script>
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart( ctx, {
  type: 'polarArea',
  data: {
    labels: [ "Red", "Yellow", "Green", "Cyan", "Blue", "Magenta" ],
    datasets: [{
      backgroundColor: [
        "#ff0000",
        "#ffff00",
        "#00ff00",
        "#00ffff",
        "#0000ff",
        "#ff00ff"
      ],
      data: [ 150, 100, 20, 80, 40, 5 ]
    }]
  }
});
</script>

  :
  :


この内容を実際にこのページ内に埋め込むと以下のようになります:


縦や横の積み上げ式の棒グラフに近い用途で使え、かつ最小値が小さくて、積み上げた時に潰れてしまうようなケースでもデータとしての存在を明確にできる、という特徴を持ったチャートだと思っています。

Chart.js は棒グラフや折れ線グラフなどの各種グラフやチャートを描画するための JavaScript ライブラリです。グラフを描くだけならかなり簡単に使うことができて便利です。また MIT ライセンスが採用されており、商用を含めた柔軟な利用が可能になっています。

今回はこの Chart.js を使って円グラフを作る例を紹介します:
2018030900


<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.3/Chart.min.js"></script>

  :
  :

<canvas id="myChart"></canvas>

  :
  :

<script>
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart( ctx, {
  type: 'pie',
  data: {
    labels: [ "Red", "Green", "Blue" ],
    datasets: [{
      backgroundColor: [
        "#ff0000",
        "#00ff00",
        "#0000ff"
      ],
      data: [ 150, 100, 20 ]
    }]
  }
});
</script>

  :
  :

キャンバスの 2D コンテキストを取得し、グラフ種類、ラベル、色、そして数値データを指定して描画しています。上記コードの "pie" という部分が円グラフを指定しており、ここを変更することで円グラフ以外のチャートを作ることもできます。

この内容を実際にこのページ内に埋め込むと以下のようになります: 




なんとなく直感的にというか、 ウェブで簡単に使えるグラフ描画ライブラリだと思ってます。

拙作マンホールマップの隠し(?)機能でも使っている手法の1つを紹介します。

マンホールマップで特定のマンホール画像を表示すると、このような画面になります(PC版の場合):

http://manholemap.juge.me/page.jsp?id=1125001 の例
2018030401


http://manholemap.juge.me/page.jsp?id=157009 の例
2018030402


注目していただきたいのは地図部分ではなくマンホール画像部分です。画像が色の付いた枠(上は青枠、下は赤枠)で囲われていることにお気づきでしょうか?

これ、実は画像全体の色味を表しています。つまり上の画像は「全体的に青っぽい」、下の画像は「全体的に赤っぽい」ことを自動判断して表示しているのです。なんとなく合ってます(よね)。実際のアプリケーションでは赤、青、緑、黄、紫、そしてマジェンタの6種類のいずれかと判断しています。

これをどうやって実現しているか、というのが今回のネタです。


マンホールマップは Java で開発していて、特にこの部分は Java の拡張クラスである ImageIO (javax.imageio.ImageIO)を使っています。具体的にはこのようなコードです:
	    :
  public String GetImageColor( byte[] img ){
    String r = null;
      :

    if( img != null ){
      BufferedImage image = null;

      try{
        InputStream is = new ByteArrayInputStream( img );
        image = ImageIO.read( is );
      }catch( IOException e ){
      }

      if( image != null ){
        //. 画像の大きさをチェック
        int w = image.getWidth();
        int h = image.getHeight();

        //. 1ピクセルずつ色を取り出す
        for( int x = 0; x < w; x ++ ){
          for( int y = 0; y < h; y ++ ){
            //. 特定ピクセルの RGB 情報を取り出す
            int rgb = image.getRGB( x, y );

              :						
          }
        }
      }else{
      }
    }

    return r;
  }

    :

この例では画像バイナリのバイト配列( byte[] img )を引数として受け取る GetImageColor() 関数を定義しています。その中でまず ImageIO.read を使って、画像の BufferedImage を取り出します。

正しく取り出すことができたら、画像の幅と高さをピクセル単位で取得し、2重の for ループ内で1ピクセルずつ BufferedImage.getRGB 関数を実行し、RGB 値を取り出す、という処理を実行しています。これで1ピクセル毎の RGB 値を取り出すことができます。

あとはこの結果から、赤、青、緑、黄、紫、そしてマジェンタのどの色が多く使われているか、、、を調べるわけですが、そのあたりの細かなアルゴリズムは秘密(というか面倒なので省略)、ということで(苦笑)。


ちなみに白と黒が含まれていない理由は「マンホールの色が黒(または白)」というのは「普通過ぎてつまらないから、黒と白を除いて近い色を探す」という工夫をしているからでした。


この方法を応用することで、色んな画像の色情報(RGB値)を1ピクセル毎に取り出して判断することができるようになります。


このページのトップヘ