棒グラフ、円グラフ

  1. 目的

    与えられた名前と大きさから、棒グラフと円グラフを百分率で表示します。グラフは、エクセルなどのアプリケーションでも作成可能ですが、このプログラムは特殊な円や同時に複数のグラフを描きたい場合の基礎的道具になります。

  2. 手法

    1. データ形式

      テキストフィールドに、名前、値、の組で表現します。


      1月,20,4月,30,7月,30,10月,20,
      このデータから棒グラフの場合、次のようにグラフ表示します。


    2. データ配列

      文字列stのデータを , で区切りながら読み込み、名前を String data_label[]=new String[20]; データを int data_set[]=new int[20]; に記録します。
      このとき、","で分割されたデータを読みとるには、以下のような、文字の検索と部分文字列の抽出方法があります。
       nindex=st.indexOf(",",pindex);
      で、pindex以後で、文字 , の場所を調べnindexに記録します。次に
       sust=st.substring(pindex,nindex)
      で、pindexとnindexの間の文字列をsustに切り出します。
       この種の処理は多いので、専門の StringTokenizer クラスが用意されています。st から、"," で切り出しを行う、stkn を作成します。stkn.hasMoreTokens() で次の切り出しが可能かどうかの判断、stkn.nextToken() で、次の","までの切り出しができます。

          StringTokenizer stkn=new StringTokenizer(st,",");
          while(stkn.hasMoreTokens()){
            //System.out.println("subst:"+sust+" :"+pindex+" :"+nindex);
            data_label[dsx]=stkn.nextToken();
            data_set[dsx++]=Integer.parseInt(stkn.nextToken());
            if(dsx >= 19) dsx--;
          }

    3. 棒グラフ

      データの合計を計算し、各データを百分率で表示します。また、X軸、Y軸とその目盛り、データの名前と百分率の値を表示します。データの間隔は、データの個数で変化します。したがって、データの間隔より、名前が長いときは名前が重なって表示されます。

    4. 円グラフ

      データの百分率を計算し、それから360度に対する角度を割合 pie_sizeを計算します。円グラフの扇形は次のグラフィックメソッドを利用します。最初が中心の位置、次が、xとY方向の半径、最後が360度単位の開始角と扇形の角度です。

      g.fillArc(Graph_offsetx, Graph_offsety, Graph_Diameter,
        Graph_Diameter, start_angle, pie_size);

      円グラフでは、名前はグラフ中ではなく、その横に色と名前を対比させて表示します。一般に、小さなデータの名前をグラフ中に表示することは困難だからです。

       

    5. 色の生成

      円グラフでは、データ毎に色を自動生成します。ここでは、HSBカラーを利用し、S:飽和度と B:明るさは最大の1.0とし、色をデータの番号より、(float)i/dsx で与えます。dsxはデータの数、iがデータの番号です。
       c1=Color.getHSBColor((float)i/dsx,(float)1.0,(float)1.0);
      これで、赤から緑、青、に変化し、赤に戻り色環に沿って、色が生成できます。

    6. 文字列の切り出し

       特定の記号で分離された文字列を順に取り出すには、StringTokenizerクラスを利用すると便利です。
      まず、String stに対して、StringTokenizerのインスタンスを tkn として生成します。ここで、"," は区切り記号を指定しています。
       StringTokenizer tkn=new StringTokenizer(st,",");
      これで、区切り記号までの文字列を tkn.nextToken() で取り出すことができます。読みとる文字列が残っているかの判断は tkn.hasMoreTokens() で行います。
       このクラスを利用するには、先頭に
       import java.util.*;
      が必要です。

  3. プロジェクト

    1. レイアウト

      データを編集するテキストフィールド、円グラフ・棒グラフを生成するボタンを配置します。

    2. 変数

      int data_set[]=new int[20]; データの大きさを記録します
      String data_label[]=new String[20]; データの名前を記録します
      int dsx=0; データの個数を記録します
      boolean Pief=false,Barf=false; 円グラフ、棒グラフを表示するとき、trueとします。

    3. メソッド

      1. paint()
        Pief、Barf、がtrueのとき、drawPie(Graphics g)または drawBar(Graphics g) を呼び出します。

      2. drawPie(Graphics g)
        円グラフを表示します。

      3. drawBar(Graphics g)
        棒グラフを表示します。

      4. SetData()
         テキルトフィールドのデータを , で分割し、データをdata_set[]、名前をdata_label[]に記録します。StringTokenizerを利用すると、次のようにデータを取り出すことができます。

            while(tkn.hasMoreTokens()){
              /*if(stf)
                data_label[dsx]=sust;
              else
                  data_set[dsx++]=Integer.parseInt(sust);*/
              data_label[dsx]=tkn.nextToken();
              data_set[dsx++]=Integer.parseInt(tkn.nextToken());
              pindex=nindex+1;
            }

        StringTokenizerを利用しない場合、pindexとnindexの間の文字列を切り出し、名前の場合はそのまま、データの場合は整数に変換して記録します。
            while(nindex+1<st.length()){
              nindex=st.indexOf(",",pindex);
              sust=st.substring(pindex,nindex);
              //System.out.println("subst:"+sust+" :"+pindex+" :"+nindex);
              if(stf)
                data_label[dsx]=sust;
              else
                  data_set[dsx++]=Integer.parseInt(sust);
        
              pindex=nindex+1;
              if(dsx >= 19) dsx--;
              stf=!stf;
            }

  4. 実行

    テキストフィールドに、<名前、データ>の繰返しで、グラフ表示したいデータを記録/編集します。ボタンを押すと、円または棒グラフを表示します。



  5. ダウンロード

    このプログラムのソースはここにあります。
    また、このプロジェクト(Jbuilder用)をダウンロードできます。次の行をクリックして、chart.exeファイルを適当なフォルダに保存します。
    ダウンロード開始
    このファイルは自己解凍型の圧縮ファイルです。このファイルを実行すると指定したフォルダに必要なファイルが生成されます。