source: branches/version-2_12-dev/data/class/graph/SC_Graph_Pie.php @ 21771

Revision 21771, 7.5 KB checked in by shutta, 12 years ago (diff)

#1766 拡張クラスの整備
拡張クラス(*_Ex)が抜けているものを補完(LC_Page_Upgrade_*, LC_Upgrade_helper_*以外)

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-httpd-php; charset=UTF-8
Line 
1<?php
2/*
3 * This file is part of EC-CUBE
4 *
5 * Copyright(c) 2000-2011 LOCKON CO.,LTD. All Rights Reserved.
6 *
7 * http://www.lockon.co.jp/
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22 */
23
24// 円グラフ生成クラス
25class SC_Graph_Pie extends SC_Graph_Base_Ex{
26    var $cw;
27    var $ch;
28    var $cz;
29    var $cx;
30    var $cy;
31    var $arrLabel;
32    var $arrData;
33
34    // コンストラクタ
35    function __construct($bgw = BG_WIDTH, $bgh = BG_HEIGHT, $left = PIE_LEFT, $top = PIE_TOP) {
36        parent::__construct($bgw, $bgh, $left, $top);
37        // サイズ設定
38        $this->setSize(PIE_WIDTH, PIE_HEIGHT, PIE_THICK);
39        // 位置設定
40        $this->setPosition($this->left + ($this->cw / 2), $this->top + ($this->ch / 2));
41    }
42
43    // データを360°値に変換する
44    function getCircleData($array) {
45        $total = '';
46        $new_total = '';
47        if (!is_array($array)) {
48            return;
49        }
50        $arrRet = array();
51        foreach ($array as $val) {
52            $total += $val;
53        }
54        if ($total <= 0) {
55            return;
56        }
57        $rate = 360 / $total;
58        // ラベル表示用
59        $p_rate = 100 / $total;
60        $cnt = 0;
61        foreach ($array as $val) {
62            $ret = round($val * $rate);
63            $new_total+= $ret;
64            $arrRet[] = $ret;
65            // パーセント表示用
66            $this->arrLabel[] = round($val * $p_rate) . ' %';
67            $cnt++;
68        }
69        // 合計が360になるように補正しておく
70        $arrRet[0] -= $new_total - 360;
71        return $arrRet;
72    }
73
74    // 円の位置設定を行う
75    function setPosition($cx, $cy) {
76        $this->cx = $cx;
77        $this->cy = $cy;
78    }
79
80    // 円のサイズ設定を行う
81    function setSize($cw, $ch, $cz = 0) {
82        $this->cw = $cw;
83        $this->ch = $ch;
84        $this->cz = $cz;
85    }
86
87    // 影の描画
88    function drawShade() {
89        $move = 1;
90        for ($i = ($this->cy + $this->cz); $i <= ($this->cy + $this->cz + ($this->cz * PIE_SHADE_IMPACT)); $i++) {
91            imagefilledarc($this->image, $this->cx + $move, $i, $this->cw, $this->ch, 0, 360, $this->shade_color, IMG_ARC_PIE);
92            $move += 0.5;
93        }
94    }
95
96    // データをセットする
97    function setData($arrData) {
98        $this->arrData = array_values($arrData);
99    }
100
101    // 円グラフを描画する
102    function drawGraph() {
103        $x = $this->cx;
104        $y = $this->cy;
105        $z = $this->cz;
106        $h = $this->ch;
107        $w = $this->cw;
108
109        // データの角度を取得する
110        $arrRad = $this->getCircleData($this->arrData);
111        $rd_max = count($arrRad);
112
113        // データが存在しない場合
114        if ($rd_max <= 0) {
115            return;
116        }
117
118        // 影の描画
119        if ($this->shade_on) {
120            $this->drawShade();
121        }
122
123        // 色数の取得
124        $c_max = count($this->arrColor);
125        $dc_max = count($this->arrDarkColor);
126
127        // 側面の描画
128        for ($i = ($y + $z - 1); $i >= $y; $i--) {
129            $start = 0;
130            for ($j = 0; $j < $rd_max; $j++) {
131                // 角度が0度以上の場合のみ側面を描画する。
132                if ($arrRad[$j] > 0) {
133                    $end = $start + $arrRad[$j];
134                    if ($start == 0 && $end == 360) {
135                        // -90~270で指定すると円が描画できないので0~360に指定
136                        imagearc($this->image, $x, $i, $w, $h, 0, 360, $this->arrDarkColor[($j % $dc_max)]);
137                    } else {
138                        // -90°は12時の位置から開始するように補正している
139                        imagearc($this->image, $x, $i, $w, $h, $start - 90, $end - 90, $this->arrDarkColor[($j % $dc_max)]);
140                    }
141                    $start = $end;
142                }
143            }
144        }
145        // 底面の描画
146        imagearc($this->image, $x, $y + $z, $w, $h, 0, 180 , $this->flame_color);
147
148        // 上面の描画
149        $start = 0;
150        for ($i = 0; $i < $rd_max; $i++) {
151            $end = $start + $arrRad[$i];
152            if ($start == 0 && $end == 360) {
153                // -90~270で指定すると円が描画できないので0~360に指定
154                imagefilledarc($this->image, $x, $y, $w, $h, 0, 360, $this->arrColor[($i % $c_max)], IMG_ARC_PIE);
155            } else {
156                // -90°は12時の位置から開始するように補正している。
157                imagefilledarc($this->image, $x, $y, $w, $h, $start - 90, $end - 90, $this->arrColor[($i % $c_max)], IMG_ARC_PIE);
158            }
159            $start = $end;
160        }
161
162        // 上面の縁取り
163        $start = 0;
164        for ($i = 0; $i < $rd_max; $i++) {
165            $end = $start + $arrRad[$i];
166            if ($start == 0 && $end == 360) {
167                // -90~270で指定すると円が描画できないので0~360に指定
168                imagearc($this->image, $x, $y, $w, $h, 0, 360 , $this->flame_color);
169            }
170            // -90°は12時の位置から開始するように補正している。
171            imagefilledarc($this->image, $x, $y, $w, $h, $start - 90, $end - 90, $this->flame_color, IMG_ARC_EDGED|IMG_ARC_NOFILL);
172            $start = $end;
173        }
174
175        // 側面の縁取り
176        imageline($this->image, $x + ($w / 2), $y, $x + ($w / 2), $y + $z, $this->flame_color);
177        imageline($this->image, $x - ($w / 2), $y, $x - ($w / 2), $y + $z, $this->flame_color);
178        $start = 0;
179        for ($i = 0; $i < $rd_max; $i++) {
180            $end = $start + $arrRad[$i];
181            // 前面のみ
182            if ($end > 90 && $end < 270) {
183                list($ax, $ay) = $this->lfGetArcPos($x, $y, $w, $h, $end);
184                // ラインのずれを補正する
185                if ($end > 180) {
186                    $ax = $ax + 1;
187                }
188                imageline($this->image, $ax, $ay, $ax, $ay + $z, $this->flame_color);
189            }
190            $start = $end;
191        }
192
193        // ラベルの描画
194        $this->drawLabel($arrRad);
195        // 凡例の描画
196        $this->drawLegend(count($this->arrData));
197    }
198
199    // 円グラフのラベルを描画する
200    function drawLabel($arrRad) {
201        $rd_max = count($arrRad);
202        $start = 0;
203        for ($i = 0; $i < $rd_max; $i++) {
204            $center = $start + ($arrRad[$i] / 2);
205            $end = $start + $arrRad[$i];
206            list($sx, $sy) = $this->lfGetArcPos($this->cx, $this->cy, ($this->cw / 1.5), ($this->ch / 1.5), $center);
207            list($ex, $ey) = $this->lfGetArcPos($this->cx, $this->cy, ($this->cw * 1.5), ($this->ch * 1.5), $center);
208            // 指示線の描画
209            imageline($this->image, $sx, $sy, $ex + 2, $ey - PIE_LABEL_UP, $this->flame_color);
210            $this->setText(FONT_SIZE, $ex - 10, $ey - PIE_LABEL_UP - FONT_SIZE, $this->arrLabel[$i], NULL, 0, true);
211            $start = $end;
212        }
213    }
214}
Note: See TracBrowser for help on using the repository browser.