Gambas 2.0で簡単なグラフを描く
まず、Gambasの最新版をダウンロードしインストールする。起動はコマンドラインから。コマンドはgambas2だ。起動したGambas 2.0のツールボックスを見ると、Containerセクションに、この版から導入された新しいオブジェクトDrawingAreaがある。新しいフォームを作って、このDrawingAreaオブジェクトを挿入する。新しいGUIのスナップショットを用意したので、参考にして欲しい。
ここで、DrawingAreaオブジェクトのプロパティーを一部設定しておく必要がある。オブジェクトを右クリックしPropertiesを選ぶ。あるいは、F4キーを押す。プロパティーが表示されたら、その一つCachedをTrueにする。こうしないと、グラフを作ってもオブジェクトには何も表示されないのだ。なお、ここでグラフの背景色を設定しておいてもよい。場所はBackgroundセクション。色はSystemタブ(あらかじめGambasが用意した色の中から選択)またはFreeタブ(自分で色を作成する)で指定する。
以上で、グラフを作成する準備が整った。新しいフォームをダブルクリックすると、コード・エディターが開く。ここにサブルーチンを書いていくのだが、次に示すForm_Openの骨格はあらかじめ用意されている。
PUBLIC SUB Form_Open() draw_chart() END SUB draw_chart() END
まず、draw_chartの骨格を作ろう。冒頭でDrawingAreaオブジェクトを初期化し、
DrawingArea1.Clear draw.Begin(DrawingArea1)
(データを描画し)、最後に描画セッションを終了する。
draw.End
これにグラフのX軸とY軸の描画を加え、実行可能なサブルーチンにすると、次のようになる。
SUB draw_chart() 'Define the variables that we'll need DIM origin_x AS Integer DIM origin_y AS Integer DIM max_x AS Integer DIM max_y AS Integer DIM x_string AS String DIM y_string AS String 'Initialize the DrawingArea object DrawingArea1.Clear draw.Begin(DrawingArea1) 'Set the text that we're going to use for the axis titles x_string = "Value" y_string = "Date" 'Define the origin for the chart origin_x = Len(x_string) * 10 origin_y = DrawingArea1.ClientHeight - 30 'Define the length or each axis max_x = DrawingArea1.Width max_y = DrawingArea1.Height * -1 'Draw each axis draw.Line(origin_x, origin_y, max_x, origin_y) draw.Line(origin_x, origin_y, origin_x, max_y) 'Finish with the DrawingArea object draw.End END
ここでオブジェクトを実行すると、画面に水平線と垂直線が描かれるはずだ。
次に、縦軸と横軸の名称を追加しよう。場所は、draw.End文の前だ。
draw.Text(x_string, 0, origin_y + max_y * 0.90) draw.Text(y_string, max_x * 0.90, origin_y + 10)
次にデータを用意する。ここでは、Yahoo! Financeの財務情報データベースを利用することにし、一例として、Novellの株価をMySQLデータベースに取り込もう。
/*Start of file*/ drop database if exists gambas_data; /*Create the database*/ create database if not exists gambas_data; /*Create the data structure*/ create table if not exists gambas_data.company_details ( id int auto_increment, name varchar(50), code varchar(10), primary key (id) ); create table if not exists gambas_data.company_history ( id int auto_increment, company_id int, value float, date date, primary key (id) ); /*Create user accounts*/ GRANT select,insert,delete,update ON gambas_data.* TO bainm@localhost IDENTIFIED BY 'mypassword'; /*Load default data*/ insert into gambas_data.company_details (name, code) values ('Novell', 'NOVL'); insert into gambas_data.company_history (company_id, date, value) values (1,'07/10/01',7.65); insert into gambas_data.company_history (company_id, date, value) values (1,'07/10/02',7.72); insert into gambas_data.company_history (company_id, date, value) values (1,'07/10/03',7.57); insert into gambas_data.company_history (company_id, date, value) values (1,'07/10/04',7.67); insert into gambas_data.company_history (company_id, date, value) values (1,'07/10/05',7.66); insert into gambas_data.company_history (company_id, date, value) values (1,'07/10/08',7.79); insert into gambas_data.company_history (company_id, date, value) values (1,'07/10/09',7.93); insert into gambas_data.company_history (company_id, date, value) values (1,'07/10/10',8.06); insert into gambas_data.company_history (company_id, date, value) values (1,'07/10/11',7.86); insert into gambas_data.company_history (company_id, date, value) values (1,'07/10/12',7.89); insert into gambas_data.company_history (company_id, date, value) values (1,'07/10/15',7.88); insert into gambas_data.company_history (company_id, date, value) values (1,'07/10/16',7.86); insert into gambas_data.company_history (company_id, date, value) values (1,'07/10/17',7.85); insert into gambas_data.company_history (company_id, date, value) values (1,'07/10/18',7.82); insert into gambas_data.company_history (company_id, date, value) values (1,'07/10/19',7.6); insert into gambas_data.company_history (company_id, date, value) values (1,'07/10/22',7.65); insert into gambas_data.company_history (company_id, date, value) values (1,'07/10/23',7.62); insert into gambas_data.company_history (company_id, date, value) values (1,'07/10/24',7.53); insert into gambas_data.company_history (company_id, date, value) values (1,'07/10/25',7.51); insert into gambas_data.company_history (company_id, date, value) values (1,'07/10/26',7.5); /*End of file*/
このデータを使うには、gb.dbをアプリケーションのコンポーネントとして追加しておかなければならない。Project→Properties→Componentsの順にクリックし、データベースに接続する。
PRIVATE conn AS NEW Connection PRIVATE FUNCTION make_connection() AS Boolean WITH conn .Type = "mysql" .Host = "localhost" .Login = "bainm" .Password = "mypassword" .Name = "gambas_data" END WITH TRY conn.Open IF ERROR THEN Message("Cannot Open Database. Error = " & Error.Text) RETURN FALSE END IF RETURN TRUE END
次に、この接続が使えるようにForm_Openサブルーチンを変更する。
PUBLIC SUB Form_Open() IF make_connection() = TRUE THEN draw_chart() END IF END
このコードは、データベースに接続できたことを確認してグラフを描く。接続に失敗したときは、エラーの発生を通知するメッセージ・ボックスを表示する。
これで、SQL文を使ってデータベースから情報を取り出せるはずだ。
DIM sql AS String DIM res AS Result sql = " select date,value from company_history" res = conn.Exec(sql)
結果はResultに格納される。プログラムの中では、このResultのデータを使う。
FOR EACH res 'process your results here. NEXT
さて、取得したデータをグラフにしよう。だが、その前に縦軸と横軸の目盛りを決めておかなければならない。X軸の目盛りは表示する項目の数によって、Y軸の目盛りはデータベースから取得したデータの最大値によって変わるからだ。
sql = "select max(value) as max_val from company_history" res = conn.Exec(sql) max_val = res!max_val y_interval = 0.90 * origin_y / max_val sql = " select date,value from company_history" res = conn.Exec(sql) x_interval = Int(0.85 * max_x / res.Count)
見やすくするため、Y軸は高さの90%、X軸は幅の85%の範囲内にデータが納まるようにする。これで棒グラフを描く準備ができた。
FOR EACH res x_pos = x_pos + x_interval y_pos = origin_y - res!value * y_interval draw.LineWidth = 0.90 * x_interval draw.ForeColor = color.red draw.Line(origin_x + x_pos, origin_y, origin_x + x_pos, y_pos) NEXT
ここで、LineWidthとForeColorは棒の幅と色だ。この状態で実行すると、次のようなグラフが表示されるはずだ。
次に、X軸とY軸に数字を入れよう。Y軸は簡単だ。
draw.ForeColor = color.black draw.Text(Round(max_val, -2), 0, origin_y - max_val * y_interval)
ラベルが多すぎると重なってしまうが、X軸は要注意だ。そこで、ラベルを飛び飛びに入れることにする。ここでは4つごとにした。
x_pos = 0 y_miss = 0 FOR EACH res x_pos = x_pos + x_interval y_miss = y_miss + 1 SELECT CASE y_miss CASE 1 draw.ForeColor = color.black draw.Text(res!date, origin_x + x_pos, origin_y) CASE 4 y_miss = 0 END SELECT NEXT
これで完成した。実行すれば、きれいな棒グラフが描かれるはずだ。
折れ線グラフも同じようにして描ける。棒グラフではX軸から上にデータの高さまで棒を描いたが、折れ線グラフでは1つ前の位置から現在の位置に直線を描くという違いがあるだけだ。
draw.LineWidth = 1 draw.ForeColor = color.black y_last = origin_y x_pos = origin_x FOR EACH res y_pos = origin_y - res!value * y_interval x_pos = x_pos + x_interval IF (x_pos - x_interval) > origin_x THEN draw.Line(x_pos - x_interval, y_last, x_pos, y_pos) END IF y_last = y_pos NEXT
これに、いろいろな飾りを付けることもできる。
- 表示データを切り替えるためのコンボ・ボックス
- 折れ線グラフと棒グラフを切り替えるためのラジオ・ボタン
- 表題
- 複数のデータ系列の色分け
データ系列が複数ある場合のグラフ
次に、複数のデータ系列をグラフにしてみよう。ここでは、NovellとMicrosoftなど、数社の株価を比較できるようにする。まず、draw_chart
サブルーチンを、企業コードが指定できるように変更する。
SUB draw_chart(company_symbols AS String[])
次に、Form_Open
を、draw_chart
が必要なデータを入手できるように変更する。
PUBLIC SUB Form_Open() IF make_connection() = TRUE THEN draw_chart(Array("NOVL", "MSFT")) END IF END
Y軸の目盛りを計算する際に使う最高値は、ここではグラフにする企業の株価全体で考える必要がある。そこで、SQL文を次のように変更する。
sql = "select max(value) as max_val from company_history where" & " company_id in (select id from company_details where " & " code in ( '" & company_symbols.Join("','") & "'))"
SQLに不慣れな場合はPRINT (sql)
を挿入するとよい。実行時に、次のようにSQL文がGambasコンソール・ウィンドウに表示される。
select max(value) as max_val from company_history where company_id in (select id from company_details where code in ( 'NOVL','MSFT'))
これをコピーして直接データベースに適用すれば、求めているデータが得られたかどうかを確認できる。
次に、棒グラフを描くコードを削除(あるいはコメント化)し、折れ線グラフを描くコードを挿入する。FOR EACH
ループの中に入っているのは、各企業のデータを描くためだ。
FOR EACH symbol IN company_symbols 'All of our code for displaying the line chart for the relevant company NEXT
そして、データを入手するSQLを変更する。
sql = "select date,value from company_history where" & " company_id in (select id from company_details where " & " code = '" & symbol & "')"
ここで、アプリケーションを実行してみよう。企業の数だけ折れ線が描かれるはずだ。しかし、どの折れ線がどの企業を表しているのかわからない。そこで、簡単なSELECT CASE
文を挿入して色分けしよう。ループで折れ線を描くたびに線の色を順次変更するのだ。
SELECT CASE chart_color CASE color.black chart_color = color.red CASE color.red chart_color = color.green CASE color.green chart_color = color.yellow CASE ELSE chart_color = color.black END SELECT draw.ForeColor = chart_color
もちろん、このコードはFOR EACH
ループの中、各企業の折れ線を描く直前に置く必要がある。そして、各企業の記号を対応する色で表示すれば完成だ。
IF x_pos = origin_x THEN draw.Text(symbol, 0, y_pos) END IF
ここでIF
文になっているのは、記号が初回の反復でだけ表示されるようにするためだ。コードは新しいxとyの位置が計算された直後に置く必要がある。これで、指定した企業の株価を比較する簡易なグラフは完成だ。
このように、Gambas 2.0アプリケーションでは、データを簡単かつ短時間でグラフにすることができる。
簡単なものからずっと凝ったものまで、さまざまなグラフを含むGambas 2.0プロジェクトを用意した。私のサイトから入手できるので、参考にして欲しい。