goo blog サービス終了のお知らせ 

中年サラリーマンのC#プログラミング勉強日記

プログラミング超初心者(おっさん)のC#勉強日記です。同じ境遇でがんばっている人がいたらコメントもらえるとうれしいです。

折れ線グラフを書く(その1)

2014-05-28 22:22:27 | 日記
今回は、前回作った体重データの配列から、折れ線グラフを作ろうと思う。
僕の会社は健康診断があったばかり。30歳を過ぎてからなんとなくな感じで年々体重が増えていて、なんだか寂しい。

今回参考にしたのは下記のWebサイト。いつも同じ人のサイトを参考にしてるとあまり自分のブログの存在価値無いな。。。

DOBON.NET 線を描く
http://dobon.net/vb/dotnet/graphics/drawline.html


今回の折れ線グラフの作成は、以下の1)~5)の手順でやってみる。

1)画像を貼り付けるPictureBoxをデザイン画面でフォームに貼り付け


2)画像データを貼り付けるビットマップオブジェクトを作成
canvas = new Bitmap(TaijyuPictureBox.Width, TaijyuPictureBox.Height);


3)更にここに貼り付けるグラフィックオブジェクトを生成し、
g = Graphics.FromImage(canvas);


4)そのオブジェクト(g)に描画
g.DrawLines(Pens.Black, ps);


この中のDrawLinesというメソッドに、使用する線の太さとか色とかを指定したオブジェクトと(下の例ではPens.Black)、折れ線の各頂点の座標をいれた配列を渡すことで(同じくps)で折れ線を書いてくれるみたいだ。

ちなみに話がちょっとそれるけど、DrawLines(最後のsがポイント)という折れ線に対して、DrawLineは直線を描くらしい。このLinesを使うより、Lineを繰り返した方が処理速度は速いようだ。
上級レベルになったらそういうところも気にしないといけないけど、今回はあきらめよう。

5)さらに、デザインでフォームに貼り付けたPictureBoxにビットマップを代入して完了。
TaijyuPictureBox.Image = canvas;


よくわからないけど、gオブジェクトは自分で消さないといけないらしい。
これまた詳しい理解は、今後の課題にする。
g.Dispose();



では、この流れで実装していく。
元データとなる体重をいれたdouble配列を新しく作るのも大変なので、前回作ったOyajiLinqプロジェクトに追加していく。。


始めに、4)で折れ線作成メソッドに入れてる頂点の座標をPoint型で、前回作った体重情報から作成する必要があるので、これをOyajiLogicで実装する。

前準備として、Pointオブジェクトを使うための下記ライブラリを追加。
using System.Drawing;


Pointを作るメソッドを作る。
今回は(別にやり方はいろいろだと思うけど)頂点を入れる座標のPoint配列psを受け取り、これに第2、3引数の書き込むPictureBoxの横の長さ(x)と縦の長さ(y)似合わせて、Taijyuデータを入れてあげることにする。
public void CreatPoint(Point[] ps, int x, int y)
{
for (int i = 0; i < taijyuLists.Count; i++)
{
ps[i] = new Point(x/taijyuLists.Count * i, y - (int)((taijyuLists[i].Taijyu - 60.0))*10);
}
}

(細かい座標の求め方は、諸事情により次回に回します。。)
注意点は体重の値から、Point(x, y)を計算していること、
x,yは代入するPictureBoxの左上からの差分になるというところです。なので、xが大きくなるほど右に、yが大きくなるほど上に座標が移動します。(僕のような初心者には、ややこしい)
この辺を考慮して、
x=PictureBoxの横幅÷データの数
y=PictureBoxの下限からデータの値を引いた位置(を見やすく更に調整)
にしています。

後はForm1に必要なオブジェクトを追加します。

まず、Form1の全てのメソッドから見えるように最初に下記を定義。

public partial class Form1 : Form
{
OyajiLogic _logic; //既存
Bitmap canvas; //★新規(1)
Graphics g; //★新規(2)
Point[] ps; //★新規(3)

コンストラクタで1,2をインスタンス化
public Form1()
{
canvas = new Bitmap(TaijyuPictureBox.Width, TaijyuPictureBox.Height);
g = Graphics.FromImage(canvas);



さらに、画像データの作成1)と描画2)メソッド(これから作成)もコンストラクタ~呼び出してしまう。
drawTaijyuLines(); //1)
drawBase(); //今回は無視
drawForm(); //2)


その呼び出される1)はこれ、
private void drawTaijyuLines()
{
ps = new Point[_logic.TaijyuLists.Count];
_logic.CreatPoint(ps, TaijyuPictureBox.Width, TaijyuPictureBox.Height);
g.DrawLines(Pens.Black, ps);
}


DrawLinesで使用する折れ線の頂点、psを先ほど作ったメソッドで、体重データから作成。
g.DrawLinesに渡す。

さらに2)はこれ、
不要なリソースを開放し、bitmapデータ(canvas)をPictureBoxに貼り付ける。
private void drawForm()
{
g.Dispose();
TaijyuPictureBox.Image = canvas;
}



実行してみる。
図2


ここでは、触れませんでしたが、目盛の作成も行おうと一応試みています。
だけど、これが意外と難しい。例えば体重データが無い日をどう扱うかとか。。。
なので、その辺は次回の持ち越しにします。。。

とりあえず、今回はここまでで。。。


最新の画像もっと見る

コメントを投稿