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

Revision 15636, 14.6 KB checked in by nanasess, 15 years ago (diff)

bugfix

  • 画像が出力されない問題修正
  • 未定義変数の修正
  • 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         *     http://www.php.net/imagettftext を見ると, UTF-8 にしろと
272         *     書いてあるのに何故?
273         */
274        $text = mb_convert_encoding($text, "EUC-JP", CHAR_CODE);
275        //$text = mb_convert_encoding($text, CHAR_CODE);
276        if($color != NULL) {
277            ImageTTFText($this->image, $font_size, $angle, $left, $top + $font_size, $color, FONT_PATH, $text);
278        } else {
279            ImageTTFText($this->image, $font_size, $angle, $left, $top + $font_size, $this->text_color, FONT_PATH, $text);
280        }
281    }
282
283    // タイトルを出力する
284    function drawTitle($text, $font_size = TITLE_FONT_SIZE) {
285        // 出力位置の算出
286        $text_width = $this->getTextWidth($text, $font_size);
287        $left = ($this->bgw - $text_width) / 2;
288        $top = TITLE_TOP;
289        $this->setText($font_size, $left, $top, $text, $this->title_color);
290    }
291
292    // ログを出力する
293    function debugPrint($text) {
294        $text = mb_convert_encoding($text, "UTF-8", CHAR_CODE);
295        if(!isset($this->text_top)) {
296            $this->text_top = FONT_SIZE + LINE_PAD;
297        }
298        // テキスト描画
299        ImageTTFText($this->image, FONT_SIZE, 0, LINE_PAD, $this->text_top, $this->text_color, FONT_PATH, $text);
300        $this->text_top += FONT_SIZE + LINE_PAD;
301    }
302
303    // カラーラベルを描画
304    function drawLegend($legend_max = "", $clabelbg = true) {
305        // 凡例が登録されていなければ中止
306        if(count($this->arrLegend) <= 0) {
307            return;
308        }
309
310        if($legend_max != "") {
311            $label_max = $legend_max;
312        } else {
313            $label_max = count($this->arrLegend);
314        }
315
316        $height_max = 0;
317        $text_max = 0;
318        $width_max = 0;
319
320        // 一番文字数が多いものを取得
321        for($i = 0; $i < $label_max; $i++) {
322            $text_len = strlen($this->arrLegend[$i]);
323            if($text_max < $text_len) {
324                $text_max = $text_len;
325            }
326            $height_max += FONT_SIZE + LINE_PAD;
327        }
328        $width_max = FONT_SIZE * $text_max * TEXT_RATE;
329
330        //  カラーアイコンと文字間を含めた幅
331        $width_max += FONT_SIZE + (LINE_PAD * 2);
332        $left = $this->bgw - $width_max - LEGEND_RIGHT;
333        $top = LEGEND_TOP;
334        // カラーラベル背景の描画
335        if($clabelbg) {
336            $this->drawClabelBG($left - LINE_PAD, $top, $left + $width_max, $top + $height_max + LINE_PAD);
337        }
338        $top += LINE_PAD;
339
340        // 色数の取得
341        $c_max = count($this->arrColor);
342        for($i = 0; $i < $label_max; $i++) {
343            // カラーアイコンの表示
344            imagerectangle($this->image, $left, $top, $left + FONT_SIZE, $top + FONT_SIZE, $this->flame_color);
345            imagefilledrectangle($this->image, $left + 1, $top + 1, $left + FONT_SIZE - 1, $top + FONT_SIZE - 1, $this->arrColor[($i % $c_max)]);
346            // ラベルの表示
347            $this->setText(FONT_SIZE, $left + FONT_SIZE + LINE_PAD, $top, $this->arrLegend[$i]);
348            $top += FONT_SIZE + LINE_PAD;
349        }
350    }
351
352    // カラーラベル背景の描画
353    function drawClabelBG($left, $top, $right, $bottom) {
354        // 影の描画
355        if($this->shade_on) {
356            imagefilledrectangle($this->image, $left + 2, $top + 2, $right + 2, $bottom + 2, $this->shade_color);
357        }
358        // カラーラベル背景の描画
359        imagefilledrectangle($this->image, $left, $top, $right, $bottom, $this->clabelbg_color);
360        imagerectangle($this->image, $left, $top, $right, $bottom, $this->flame_color);
361    }
362
363    // 凡例をセットする
364    function setLegend($arrLegend) {
365        $this->arrLegend = array_values((array)$arrLegend);
366    }
367
368    // }}}
369    // {{{ protected functions
370
371    /**
372     * クラスの初期化を行う.
373     *
374     * 表示色をメンバ変数にセットする.
375     *
376     * @access protected
377     * @return void
378     */
379    function init() {
380        // 凡例背景
381        $this->ARR_LEGENDBG_COLOR = array(245,245,245);
382        // ラベル背景
383        $this->ARR_LABELBG_COLOR = array(255,255,255);
384        // グラフカラー
385        $this->ARR_GRAPH_RGB = array(
386                               array(200,50,50),
387                               array(50,50,200),
388                               array(50,200,50),
389                               array(255,255,255),
390                               array(244,200,200),
391                               array(200,200,255),
392                               array(50,200,50),
393                               array(255,255,255),
394                               array(244,244,244),
395                               );
396        // 影の色
397        $this->ARR_SHADE_COLOR = array(100,100,100);
398        // 縁の色
399        $this->ARR_FLAME_COLOR = array(0, 0, 0);
400        // 文字色
401        $this->ARR_TEXT_COLOR = array(0, 0, 0);
402        // 背景カラー
403        $this->ARR_BG_COLOR = array(255,255,255);
404        // タイトル文字色
405        $this->ARR_TITLE_COLOR = array(0, 0, 0);
406        // グリッド線色
407        $this->ARR_GRID_COLOR = array(200, 200, 200);
408        // マークの色
409        $this->ARR_MARK_COLOR = array(130, 130, 255);
410    }
411
412    /**
413     * 円の中心点と直径から弧の終端座標を算出する.
414     *
415     * @param integer $cx 中心点X座標
416     * @param integer $cy 中心点Y座標
417     * @param integer $r 半径
418     * @param integer $e 角度
419     * @return array 円の中心点と直径から弧の終端座標の配列
420     */
421    function lfGetArcPos($cx, $cy, $cw, $ch, $e) {
422        // 三角関数用の角度を求める
423        $s = 90 - $e;
424        $r = $cw / 2;
425        // 位置を求める
426        $x = $cx + ($r * cos(deg2rad($s)));
427        $y = $cy - (($r * sin(deg2rad($s))) * ($ch / $cw));
428        return array(round($x), round($y));
429    }
430
431    /** 画像にテキストを描画する */
432    function lfImageText($dst_image, $text, $font_size, $left, $top, $font, $arrRGB) {
433        $color = ImageColorAllocate($dst_image, $arrRGB[0], $arrRGB[1], $arrRGB[2]);
434        $text = mb_convert_encoding($text, "UTF-8", CHAR_CODE);
435        // 表示角度
436        $angle = 0;
437        // テキスト描画
438        ImageTTFText($dst_image, $font_size, $angle, $left, $top, $color, $font, $text);
439    }
440
441    /** 表示色の取得 */
442    function lfGetImageColor($image, $array) {
443        if(count($array) != 3) {
444            return NULL;
445        }
446        $ret = imagecolorallocate($image, $array[0], $array[1], $array[2]);
447        return $ret;
448    }
449
450    /** 影用表示色の取得 */
451    function lfGetImageDarkColor($image, $array) {
452        if(count($array) != 3) {
453            return NULL;
454        }
455        $i = 0;
456        foreach($array as $val) {
457            $dark[$i] = $val - 45;
458            if($dark[$i] < 0) {
459                $dark[$i] = 0;
460            }
461            $i++;
462        }
463        $ret = imagecolorallocate($image, $dark[0], $dark[1], $dark[2]);
464        return $ret;
465    }
466}
467?>
Note: See TracBrowser for help on using the repository browser.