source: branches/feature-module-update/data/class/graph/SC_GraphBase.php @ 15639

Revision 15639, 14.6 KB checked in by nanasess, 17 years ago (diff)

コメント修正

  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-httpd-php; charset=UTF-8
Line 
1<?php
2/*
3 * Copyright(c) 2000-2007 LOCKON CO.,LTD. All Rights Reserved.
4 *
5 * http://www.lockon.co.jp/
6 */
7
8/** TTFフォントファイル */
9define("FONT_PATH", DATA_PATH . "fonts/wlmaru20044.ttf");
10
11/** フォントサイズ */
12define("FONT_SIZE", 8);
13
14/** タイトルフォントサイズ */
15define("TITLE_FONT_SIZE", 11);
16
17/** 背景幅 */
18define("BG_WIDTH", 720);
19
20/** 背景高さ */
21define("BG_HEIGHT", 400);
22
23/** 行間 */
24define("LINE_PAD", 5);
25
26/** フォント補正値(実際の描画幅/フォントサイズ) */
27define("TEXT_RATE", 0.75);
28
29// -----------------------------------------------------------------------------
30// 円グラフ
31// -----------------------------------------------------------------------------
32/** 円グラフ位置 */
33define("PIE_LEFT", 200);
34
35/** 円グラフ位置 */
36define("PIE_TOP", 150);
37
38/** 円グラフ幅 */
39define("PIE_WIDTH", 230);
40
41/** 円グラフ高さ */
42define("PIE_HEIGHT", 100);
43
44/** 円グラフ太さ */
45define("PIE_THICK", 30);
46
47/** 円グラフのラベル位置を上にあげる */
48define("PIE_LABEL_UP", 20);
49
50/** 値が大きいほど影が長くなる */
51define("PIE_SHADE_IMPACT", 0.1);
52
53// -----------------------------------------------------------------------------
54// 折れ線グラフ
55// -----------------------------------------------------------------------------
56/** Y軸の目盛り数 */
57define("LINE_Y_SCALE", 10);
58
59/** X軸の目盛り数 */
60define("LINE_X_SCALE", 10);
61
62/** 線グラフ位置 */
63define("LINE_LEFT", 60);
64
65/** 線グラフ位置 */
66define("LINE_TOP", 50);
67
68/** 線グラフ背景のサイズ */
69define("LINE_AREA_WIDTH", 600);
70
71/** 線グラフ背景のサイズ */
72define("LINE_AREA_HEIGHT", 300);
73
74/** 線グラフマークのサイズ */
75define("LINE_MARK_SIZE", 6);
76
77/** 目盛り幅 */
78define("LINE_SCALE_SIZE", 6);
79
80/** X軸のラベルの表示制限数 */
81define("LINE_XLABEL_MAX", 30);
82
83/** X軸のタイトルと軸の間隔 */
84define("LINE_XTITLE_PAD", -5);
85
86/** Y軸のタイトルと軸の間隔 */
87define("LINE_YTITLE_PAD", 15);
88
89// -----------------------------------------------------------------------------
90//  棒グラフ
91// -----------------------------------------------------------------------------
92/** グラフと目盛りの間隔 */
93define("BAR_PAD", 6);
94
95// -----------------------------------------------------------------------------
96//  タイトルラベル
97// -----------------------------------------------------------------------------
98/** 背景枠との上幅 */
99define("TITLE_TOP", 10);
100
101// -----------------------------------------------------------------------------
102//  凡例
103// -----------------------------------------------------------------------------
104/** 背景枠との上幅 */
105define("LEGEND_TOP", 10);
106
107/** 背景枠との右幅 */
108define("LEGEND_RIGHT", 10);
109
110/**
111 * SC_Graph共通クラス.
112 *
113 * @package Graph
114 * @author LOCKON CO.,LTD.
115 * @version $Id$
116 */
117class SC_GraphBase {
118
119    // {{{ properties
120
121    var $arrRGB;
122    var $arrColor;
123    var $arrDarkColor;
124    var $image;
125    var $left;
126    var $top;
127    var $shade_color;
128    var $flame_color;
129    var $shade_on;
130    var $text_color;
131    var $labelbg_color;
132    var $bgw;
133    var $bgh;
134    var $clabelbg_color;
135    var $title_color;
136    var $text_top;
137    var $mark_color;
138    var $arrLegend;
139
140    /** グラフ背景 */
141    var $ARR_GRAPH_RGB;
142
143    /** 背景色 */
144    var $ARR_BG_COLOR;
145
146    /** 影の色 */
147    var $ARR_SHADE_COLOR;
148
149    /** 縁の色 */
150    var $ARR_FLAME_COLOR;
151
152    /** 文字色 */
153    var $ARR_TEXT_COLOR;
154
155    /** ラベル背景 */
156    var $ARR_LABELBG_COLOR;
157
158    /** 凡例背景 */
159    var $ARR_LEGENDBG_COLOR;
160
161    /** タイトル文字色 */
162    var $ARR_TITLE_COLOR;
163
164    /** グリッド線色 */
165    var $ARR_GRID_COLOR;
166
167    // コンストラクタ
168    function SC_GraphBase($bgw = BG_WIDTH, $bgh = BG_HEIGHT, $left, $top) {
169        $this->init();
170        // 画像作成
171        $this->bgw = $bgw;
172        $this->bgh = $bgh;
173        $this->image = imagecreatetruecolor($bgw, $bgh);
174        // アンチエイリアス有効
175        if (function_exists("imageantialias")) imageantialias($this->image, true);
176        // 背景色をセット
177        imagefill($this->image, 0, 0, $this->lfGetImageColor($this->image, $this->ARR_BG_COLOR));
178
179        // 使用色の生成
180        $this->setColorList($this->ARR_GRAPH_RGB);
181        // グラフ描画位置の設定
182        $this->left = $left;
183        $this->top = $top;
184        $this->shade_color = $this->lfGetImageColor($this->image, $this->ARR_SHADE_COLOR);
185        $this->flame_color = $this->lfGetImageColor($this->image, $this->ARR_FLAME_COLOR);
186        $this->text_color = $this->lfGetImageColor($this->image, $this->ARR_TEXT_COLOR);
187        $this->labelbg_color = $this->lfGetImageColor($this->image, $this->ARR_LABELBG_COLOR);
188        $this->clabelbg_color = $this->lfGetImageColor($this->image, $this->ARR_LEGENDBG_COLOR);
189        $this->title_color = $this->lfGetImageColor($this->image, $this->ARR_TITLE_COLOR);
190        $this->grid_color = $this->lfGetImageColor($this->image, $this->ARR_GRID_COLOR);
191
192        // 影あり
193        $this->shade_on = true;
194    }
195
196    // リサンプル(画像を滑らかに縮小する)
197    function resampled() {
198        $new_width = $this->bgw * 0.8;
199        $new_height = $this->bgh * 0.8;
200        $tmp_image = imagecreatetruecolor($new_width, $new_height);
201        if(imagecopyresampled($tmp_image, $this->image, 0, 0, 0, 0, $new_width, $new_height, $this->bgw, $this->bgh)) {
202            $this->image = $tmp_image;
203        }
204    }
205
206
207    // オブジェクトカラーの設定
208    function setColorList($arrRGB) {
209        $this->arrRGB = $arrRGB;
210        $count = count($this->arrRGB);
211        // 通常色の設定
212        for($i = 0; $i < $count; $i++) {
213            $this->arrColor[$i] = $this->lfGetImageColor($this->image, $this->arrRGB[$i]);
214        }
215        // 暗色の設定
216        for($i = 0; $i < $count; $i++) {
217            $this->arrDarkColor[$i] = $this->lfGetImageDarkColor($this->image, $this->arrRGB[$i]);
218        }
219    }
220
221    // 影のありなし
222    function setShadeOn($shade_on) {
223        $this->shade_on = $shade_on;
224    }
225
226    // 画像を出力する
227    function outputGraph($header = true, $filename = "") {
228        if($header) {
229            header('Content-type: image/png');
230        }
231
232        if ($filename != "") {
233            imagepng($this->image, $filename);
234        }else{
235            imagepng($this->image);
236        }
237
238        imagedestroy($this->image);
239    }
240
241    // 描画時のテキスト幅を求める
242    function getTextWidth($text, $font_size) {
243        $text_len = strlen($text);
244        $ret = $font_size * $text_len * TEXT_RATE;
245        /*
246            ※正確な値が取得できなかったので廃止
247            // テキスト幅の取得
248            $arrPos = imagettfbbox($font_size, 0, FONT_PATH, $text);
249            $ret = $arrPos[2] - $arrPos[0];
250        */
251        return $ret;
252    }
253
254    // テキストを出力する
255    function setText($font_size, $left, $top, $text, $color = NULL, $angle = 0, $labelbg = false) {
256        // 時計回りに角度を変更
257        $angle = -$angle;
258        // ラベル背景
259        if($labelbg) {
260            $text_width = $this->getTextWidth($text, $font_size);
261            imagefilledrectangle($this->image, $left - 2, $top - 2, $left + $text_width + 2, $top + $font_size + 2, $this->labelbg_color);
262        }
263        /*
264         * XXX EUC-JP にしないと Warning がでる.
265         *     --enable-gd-jis-conv も関係していそうだが, このオプションを
266         *     つけなくても出る.
267         *
268         *     Warning: imagettftext() [function.imagettftext]:
269         *     any2eucjp(): something happen in
270         *
271         *     PHP Bugs: #42218
272         *
273         *     http://www.php.net/imagettftext を見ると, UTF-8 にしろと
274         *     書いてあるのに...
275         *
276         */
277        $text = mb_convert_encoding($text, "EUC-JP", CHAR_CODE);
278        //$text = mb_convert_encoding($text, CHAR_CODE);
279        if($color != NULL) {
280            ImageTTFText($this->image, $font_size, $angle, $left, $top + $font_size, $color, FONT_PATH, $text);
281        } else {
282            ImageTTFText($this->image, $font_size, $angle, $left, $top + $font_size, $this->text_color, FONT_PATH, $text);
283        }
284    }
285
286    // タイトルを出力する
287    function drawTitle($text, $font_size = TITLE_FONT_SIZE) {
288        // 出力位置の算出
289        $text_width = $this->getTextWidth($text, $font_size);
290        $left = ($this->bgw - $text_width) / 2;
291        $top = TITLE_TOP;
292        $this->setText($font_size, $left, $top, $text, $this->title_color);
293    }
294
295    // ログを出力する
296    function debugPrint($text) {
297        $text = mb_convert_encoding($text, "UTF-8", CHAR_CODE);
298        if(!isset($this->text_top)) {
299            $this->text_top = FONT_SIZE + LINE_PAD;
300        }
301        // テキスト描画
302        ImageTTFText($this->image, FONT_SIZE, 0, LINE_PAD, $this->text_top, $this->text_color, FONT_PATH, $text);
303        $this->text_top += FONT_SIZE + LINE_PAD;
304    }
305
306    // カラーラベルを描画
307    function drawLegend($legend_max = "", $clabelbg = true) {
308        // 凡例が登録されていなければ中止
309        if(count($this->arrLegend) <= 0) {
310            return;
311        }
312
313        if($legend_max != "") {
314            $label_max = $legend_max;
315        } else {
316            $label_max = count($this->arrLegend);
317        }
318
319        $height_max = 0;
320        $text_max = 0;
321        $width_max = 0;
322
323        // 一番文字数が多いものを取得
324        for($i = 0; $i < $label_max; $i++) {
325            $text_len = strlen($this->arrLegend[$i]);
326            if($text_max < $text_len) {
327                $text_max = $text_len;
328            }
329            $height_max += FONT_SIZE + LINE_PAD;
330        }
331        $width_max = FONT_SIZE * $text_max * TEXT_RATE;
332
333        //  カラーアイコンと文字間を含めた幅
334        $width_max += FONT_SIZE + (LINE_PAD * 2);
335        $left = $this->bgw - $width_max - LEGEND_RIGHT;
336        $top = LEGEND_TOP;
337        // カラーラベル背景の描画
338        if($clabelbg) {
339            $this->drawClabelBG($left - LINE_PAD, $top, $left + $width_max, $top + $height_max + LINE_PAD);
340        }
341        $top += LINE_PAD;
342
343        // 色数の取得
344        $c_max = count($this->arrColor);
345        for($i = 0; $i < $label_max; $i++) {
346            // カラーアイコンの表示
347            imagerectangle($this->image, $left, $top, $left + FONT_SIZE, $top + FONT_SIZE, $this->flame_color);
348            imagefilledrectangle($this->image, $left + 1, $top + 1, $left + FONT_SIZE - 1, $top + FONT_SIZE - 1, $this->arrColor[($i % $c_max)]);
349            // ラベルの表示
350            $this->setText(FONT_SIZE, $left + FONT_SIZE + LINE_PAD, $top, $this->arrLegend[$i]);
351            $top += FONT_SIZE + LINE_PAD;
352        }
353    }
354
355    // カラーラベル背景の描画
356    function drawClabelBG($left, $top, $right, $bottom) {
357        // 影の描画
358        if($this->shade_on) {
359            imagefilledrectangle($this->image, $left + 2, $top + 2, $right + 2, $bottom + 2, $this->shade_color);
360        }
361        // カラーラベル背景の描画
362        imagefilledrectangle($this->image, $left, $top, $right, $bottom, $this->clabelbg_color);
363        imagerectangle($this->image, $left, $top, $right, $bottom, $this->flame_color);
364    }
365
366    // 凡例をセットする
367    function setLegend($arrLegend) {
368        $this->arrLegend = array_values((array)$arrLegend);
369    }
370
371    // }}}
372    // {{{ protected functions
373
374    /**
375     * クラスの初期化を行う.
376     *
377     * 表示色をメンバ変数にセットする.
378     *
379     * @access protected
380     * @return void
381     */
382    function init() {
383        // 凡例背景
384        $this->ARR_LEGENDBG_COLOR = array(245,245,245);
385        // ラベル背景
386        $this->ARR_LABELBG_COLOR = array(255,255,255);
387        // グラフカラー
388        $this->ARR_GRAPH_RGB = array(
389                               array(200,50,50),
390                               array(50,50,200),
391                               array(50,200,50),
392                               array(255,255,255),
393                               array(244,200,200),
394                               array(200,200,255),
395                               array(50,200,50),
396                               array(255,255,255),
397                               array(244,244,244),
398                               );
399        // 影の色
400        $this->ARR_SHADE_COLOR = array(100,100,100);
401        // 縁の色
402        $this->ARR_FLAME_COLOR = array(0, 0, 0);
403        // 文字色
404        $this->ARR_TEXT_COLOR = array(0, 0, 0);
405        // 背景カラー
406        $this->ARR_BG_COLOR = array(255,255,255);
407        // タイトル文字色
408        $this->ARR_TITLE_COLOR = array(0, 0, 0);
409        // グリッド線色
410        $this->ARR_GRID_COLOR = array(200, 200, 200);
411        // マークの色
412        $this->ARR_MARK_COLOR = array(130, 130, 255);
413    }
414
415    /**
416     * 円の中心点と直径から弧の終端座標を算出する.
417     *
418     * @param integer $cx 中心点X座標
419     * @param integer $cy 中心点Y座標
420     * @param integer $r 半径
421     * @param integer $e 角度
422     * @return array 円の中心点と直径から弧の終端座標の配列
423     */
424    function lfGetArcPos($cx, $cy, $cw, $ch, $e) {
425        // 三角関数用の角度を求める
426        $s = 90 - $e;
427        $r = $cw / 2;
428        // 位置を求める
429        $x = $cx + ($r * cos(deg2rad($s)));
430        $y = $cy - (($r * sin(deg2rad($s))) * ($ch / $cw));
431        return array(round($x), round($y));
432    }
433
434    /** 画像にテキストを描画する */
435    function lfImageText($dst_image, $text, $font_size, $left, $top, $font, $arrRGB) {
436        $color = ImageColorAllocate($dst_image, $arrRGB[0], $arrRGB[1], $arrRGB[2]);
437        $text = mb_convert_encoding($text, "UTF-8", CHAR_CODE);
438        // 表示角度
439        $angle = 0;
440        // テキスト描画
441        ImageTTFText($dst_image, $font_size, $angle, $left, $top, $color, $font, $text);
442    }
443
444    /** 表示色の取得 */
445    function lfGetImageColor($image, $array) {
446        if(count($array) != 3) {
447            return NULL;
448        }
449        $ret = imagecolorallocate($image, $array[0], $array[1], $array[2]);
450        return $ret;
451    }
452
453    /** 影用表示色の取得 */
454    function lfGetImageDarkColor($image, $array) {
455        if(count($array) != 3) {
456            return NULL;
457        }
458        $i = 0;
459        foreach($array as $val) {
460            $dark[$i] = $val - 45;
461            if($dark[$i] < 0) {
462                $dark[$i] = 0;
463            }
464            $i++;
465        }
466        $ret = imagecolorallocate($image, $dark[0], $dark[1], $dark[2]);
467        return $ret;
468    }
469}
470?>
Note: See TracBrowser for help on using the repository browser.