GDを使ったレーダーチャートの作成 - PHPプロ!Q&A掲示板

2567

  • 0P

GDを使ったレーダーチャートの作成

質問日時 / 2010年2月24日 21:36    回答数 / 4件

Questioner:  hayato0210  このエントリーをはてなブックマークに追加 

キーワード / キーワードが設定されていません

レーダーチャート用の画像を作成しようとしております。
画像は作成できたのですがこのソース上でprint関数を使うと
画像が表示されなくなってしまいます。

なぜなのでしょうか・・・。

  1. <?php
  2.  
  3. /**
  4.  * エンコードタイプ
  5.  * @const ENCODE_TYPE
  6.  */
  7. define('ENCODE_TYPE''UTF-8');
  8.  
  9. /**
  10.  * レーダーサイズ
  11.  * @const CHART_SIZE
  12.  */
  13. define('CHART_SIZE'100);
  14.  
  15. /**
  16.  * キャラクタサイズ
  17.  * @const CHAR_SIZE
  18.  */
  19. define('CHAR_SIZE'4);
  20.  
  21. /**
  22.  * 組み込みフォント
  23.  * @const CHAR_SIZE
  24.  */
  25. define('FONT_BUILT_IN'0);
  26.  
  27. /**
  28.  * TrueTypeフォント
  29.  * @const FONT_TRUE_TYPE
  30.  */
  31. define('FONT_TRUE_TYPE'1);
  32.  
  33. /**
  34.  *レーダーチャートの出力
  35.  *
  36.  * @author 高橋 裕志郎 <yujiro@rakuto.net>
  37.  * @package RKT_radar
  38.  * @access public
  39.  * @version 1.1
  40.  */
  41. class RKT_radar
  42. {
  43.     /**
  44.      * イメージリソース
  45.      * @var resource
  46.      */
  47.     var $rscimg = null;
  48.  
  49.     /**
  50.      * イメージリソースのサイズ
  51.      * @var array
  52.      *   $canvas['width']   描画領域の幅
  53.      *   $canvas['height']  描画領域の高さ
  54.      */
  55.     var $canvas = array();
  56.  
  57.     /**
  58.      * 編集用の座標配列
  59.      * @var array
  60.      *   $point['x']    X軸座標
  61.      *   $point['y']    Y軸座標
  62.      */
  63.     var $point = array();
  64.  
  65.     /**
  66.      * 原点
  67.      * @var array
  68.      *   $origin['x']   X軸座標
  69.      *   $origin['y']   Y軸座標
  70.      */
  71.     var $origin = array();
  72.  
  73.     /**
  74.      * 項目数(頂点の数)
  75.      * @var integer
  76.      */
  77.     var $num_column = 0;
  78.  
  79.     /**
  80.      * 角度幅
  81.      * @var integer
  82.      */
  83.     var $theta = 0;
  84.  
  85.     /**
  86.      * 項目データ
  87.      * @var array
  88.      */
  89.     var $columns = array();
  90.  
  91.     /**
  92.      * 現在選択している色
  93.      * @var integer
  94.      */
  95.     var $color = 0;
  96.  
  97.     /**
  98.      * フォントサイズ
  99.      * @var integer
  100.      */
  101.     var $font_size = 9;
  102.  
  103.     /**
  104.      * フォントタイプ
  105.      * @var string
  106.      */
  107.     var $fontfile = '';
  108.  
  109.     /**
  110.      * フォントID
  111.      * @var integer
  112.      */
  113.     var $font_id = 2;
  114.  
  115.     /**
  116.      * テキスト出力モード
  117.      * @var integer
  118.      */
  119.     var $font_mode = 5;
  120.  
  121.     /**
  122.      * コンストラクタ
  123.      *
  124.      * @access public
  125.      * @param integer [$width] 描画領域の幅
  126.      * @param integer [$height] 描画領域の高さ
  127.      */
  128.     function RKT_radar($width=256,$height=256)
  129.     {
  130.         /* 描画領域 */
  131.         $this->canvas['width']  = $width;
  132.         $this->canvas['height'] = $height;
  133.         /* 計算用原点 */
  134.         $this->origin['x'] = (int)($width/2);
  135.         $this->origin['y'] = (int)($height/2);        
  136.  
  137.         /* フォントの設定 */
  138.         $this->font_size = 10;
  139.         /* OS毎に読み込み方を変更 */
  140.         if (strtoupper(substr(PHP_OS0,3) == 'WIN')) {
  141.             $this->fontfile = 'C:/WINDOWS/Fonts/msgothic.ttc';
  142.         } else {
  143.             $this->fontfile = '/usr/share/fonts/ja/TrueType/kochi-gothic.ttf';
  144.         }
  145.  
  146.         $this->font_mode = FONT_BUILT_IN;
  147.     }
  148.  
  149.     /**
  150.      * 描画領域のリソースを新規に作成する
  151.      *
  152.      * @access public
  153.      */
  154.     function createImage()
  155.     {
  156.         $this->rscimg = @imagecreatetruecolor($this->canvas['width'],$this->canvas['height']);
  157.     }
  158.  
  159.     /**
  160.      * 描画領域のリソースを設定
  161.      *
  162.      * @access public
  163.      * @param resource $rscimg 描画領域のリソース
  164.      */
  165.     function setImage(&$rscimg)
  166.     {
  167.         $this->rscimg =& $rscimg;
  168.     }
  169.  
  170.     /**
  171.      * 描画領域のリソースを取得
  172.      *
  173.      * @access public
  174.      * @param resource $rscimg 描画領域のリソース
  175.      */
  176.     function &getImage()
  177.     {
  178.         return $this->rscimg;
  179.     }
  180.  
  181.     /**
  182.      * 色の指定
  183.      *
  184.      * @access public
  185.      * @param integer $color
  186.      */
  187.     function setColor($color)
  188.     {
  189.         if (is_int($color)){
  190.             $this->color = $color;
  191.         } else if (is_string($color)){
  192.             $colors = explode(','$color);
  193.             $this->color = ImageColorAllocate($this->rscimg,$colors[0],$colors[1],$colors[2]);
  194.         }
  195.     }
  196.  
  197.     /**
  198.      * フォントサイズのセット
  199.      *
  200.      * @access public
  201.      * @param integer $size フォントサイズ
  202.      */
  203.     function setFontSize($size)
  204.     {
  205.         $this->fontsize = $size;
  206.     }
  207.  
  208.     /**
  209.      * フォントファイルのセット
  210.      *
  211.      * @access public
  212.      * @param integer $fontfile フォントファイル
  213.      */
  214.     function setFontFile($fontfile)
  215.     {
  216.         $this->fontfile = $fontfile;
  217.     }
  218.  
  219.     /**
  220.      * フォントモードのセット
  221.      *
  222.      * @access public
  223.      * @param integer $font_mode フォントモードの
  224.      */
  225.     function setFontMode($font_mode)
  226.     {
  227.         $this->font_mode = $font_mode;
  228.     }
  229.  
  230.     /**
  231.      * フォントファイルのセット
  232.      *
  233.      * @access public
  234.      * @param integer $fontfile フォントファイル
  235.      */
  236.     function setColumns($columns)
  237.     {
  238.         $this->num_column = count($columns);
  239.         $this->theta = (int) (360/$this->num_column);
  240.         $this->columns = $columns;
  241.     }
  242.  
  243.     /**
  244.      * 編集用座標のセット
  245.      *
  246.      * @access public
  247.      * @param float $x x座標
  248.      * @param float $x x座標
  249.      */
  250.     function setPoint($x,$y)
  251.     {
  252.         $this->point['x'] = $x;
  253.         $this->point['y'] = $y;
  254.     }
  255.  
  256.     /**
  257.      * 座標の回転
  258.      *
  259.      * @access public
  260.      * @param float $angle アングル
  261.      * @return integer SINフラグ
  262.      *
  263.      *  |x| |cosθ -sinθ 0|
  264.      *  |y| |sinθ  cosθ 0|
  265.      *  |1| | 0      0    1|
  266.      */
  267.     function rotatePoint($angle)
  268.     {
  269.         $x = $this->point['x'];
  270.         $y = $this->point['y'];
  271.  
  272.         $sin = sin(deg2rad($angle));
  273.         $cos = cos(deg2rad($angle));
  274.  
  275.         $this->point['x'] = $x * $cos - $y * $sin;
  276.         $this->point['y'] = $x * $sin + $y * $cos;
  277.  
  278.         $t_val = array(-1,0);
  279.         $f_val = array(0,1);
  280.         $flags = array();
  281.         $flags['x'] = ($this->point['x'] >= 0)0:1;
  282.         $flags['y'] = ($this->point['y'] >= 0)$f_val[$this->font_mode]:$t_val[$this->font_mode];
  283.  
  284.         return ($flags);
  285.     }
  286.  
  287.     /**
  288.      * 座標の移動
  289.      *
  290.      * @access public
  291.      * @param float $x X軸の移動ピクセル
  292.      * @param float $y Y軸の移動ピクセル
  293.      *
  294.      *  |x| |1 0 Tx|
  295.      *  |y| |0 1 Ty|
  296.      *  |1| |0 0 1 |
  297.      */
  298.     function movePoint($x,$y)
  299.     {
  300.         $this->point['x'] += $x;
  301.         $this->point['y'] += $y;
  302.     }
  303.  
  304.     /**
  305.      * 外枠の作成
  306.      *
  307.      * @access public
  308.      */
  309.     function Polygon()
  310.     {
  311.         $polygon = array();        
  312.         $angle = 0;
  313.  
  314.         foreach ($this->columns as $row){
  315.             $this->setPoint(0,-CHART_SIZE);
  316.             $flags = $this->rotatePoint($angle);
  317.             $this->movePoint($this->origin['x'],$this->origin['y']);
  318.  
  319.             $polygon[] = (int)$this->point['x'];
  320.             $polygon[] = (int)$this->point['y'];
  321.             
  322.             $strlen = strlen($row['name']);
  323.             $posx = $this->point['x'] + $strlen * -CHAR_SIZE * $flags['x'];
  324.             $posy = $this->point['y'] + $this->font_size * $flags['y'];
  325.             $title  = mb_convert_encoding($row['name']'UTF-8'ENCODE_TYPE);
  326.             $fnc_text[FONT_BUILT_IN] = 'ImageString($this->rscimg,$this->font_id,$posx,$posy,$title,$this->color);';
  327.             $fnc_text[FONT_TRUE_TYPE]'ImageTTFText($this->rscimg,$this->font_size,0,$posx,$posy,$this->color,$this->fontfile,$title);';
  328.             eval($fnc_text[$this->font_mode]);
  329.  
  330.             $angle += $this->theta;
  331.         }
  332.         imagepolygon($this->rscimg$polygon$this->num_column$this->color);
  333.     }
  334.  
  335.     /**
  336.      * 放射線の作成
  337.      *
  338.      * @access public
  339.      */
  340.     function Radiation()
  341.     {
  342.         $angle = 0;
  343.  
  344.         foreach ($this->columns as $row){
  345.             $this->setPoint(0,-CHART_SIZE);
  346.             $this->rotatePoint($angle);
  347.             $this->movePoint($this->origin['x'],$this->origin['y']);
  348.  
  349.             $posx = (int)$this->point['x'];
  350.             $posy = (int)$this->point['y'];
  351.             imageline ($this->rscimg,$this->origin['x'],$this->origin['y'],$posx,$posy,$this->color);
  352.  
  353.             $angle += $this->theta;
  354.         }
  355.     }
  356.  
  357.     /**
  358.      * 放射線の作成
  359.      *
  360.      * @access public
  361.      */
  362.     function gridNumber()
  363.     {
  364.         $this->setPoint(-10,+10);
  365.         $this->movePoint($this->origin['x'],$this->origin['y']);
  366.         $posx = (int)$this->point['x']-10;
  367.         $posy = (int)$this->point['y'];
  368.         $fnc_text[FONT_BUILT_IN] = 'ImageChar($this->rscimg,$this->font_id,$posx,$posy,"0%",$this->color);';
  369.         $fnc_text[FONT_TRUE_TYPE]'ImageTTFText($this->rscimg,$this->font_size,0,$posx,$posy,$this->color,$this->fontfile,"0%");';
  370.         eval($fnc_text[$this->font_mode]);
  371.  
  372.         $this->setPoint(-16,-CHART_SIZE/2+10);
  373.         $this->movePoint($this->origin['x'],$this->origin['y']);
  374.         $posx = (int)$this->point['x']-10;
  375.         $posy = (int)$this->point['y'];
  376.         $fnc_text[FONT_BUILT_IN] = 'ImageString($this->rscimg,$this->font_id,$posx,$posy,"50%",$this->color);';
  377.         $fnc_text[FONT_TRUE_TYPE]'ImageTTFText($this->rscimg,$this->font_size,0,$posx,$posy,$this->color,$this->fontfile,"50%");';
  378.         eval($fnc_text[$this->font_mode]);
  379.  
  380.         $this->setPoint(-20,-(CHART_SIZE)+10);
  381.         $this->movePoint($this->origin['x'],$this->origin['y']);
  382.         $posx = (int)$this->point['x']-10;
  383.         $posy = (int)$this->point['y'];
  384.         $fnc_text[FONT_BUILT_IN] = 'ImageString($this->rscimg,$this->font_id,$posx,$posy,"100%",$this->color);';
  385.         $fnc_text[FONT_TRUE_TYPE]'ImageTTFText($this->rscimg,$this->font_size,0,$posx,$posy,$this->color,$this->fontfile,"100%");';
  386.         eval($fnc_text[$this->font_mode]);
  387.     }
  388.  
  389.     /**
  390.      * レーダーの作成
  391.      *
  392.      * @access public
  393.      * @param string $fill 塗りつぶし色
  394.      * @param string $line 線色
  395.      */
  396.     function Radar($line$fill)
  397.     {
  398.         $polygon = array();
  399.         $angle   = 0;
  400.  
  401.         foreach ($this->columns as $row){
  402.             $this->setPoint(0,-($row['value']));
  403.             $this->rotatePoint($angle);
  404.             $this->movePoint($this->origin['x'],$this->origin['y']);
  405.  
  406.             $values[]              = $row['value'];
  407.             $angles[$row['value']] = $angle;
  408.  
  409.             $polygon[] = (int)$this->point['x'];
  410.             $polygon[] = (int)$this->point['y'];
  411.  
  412.             $posx = (int)$this->point['x'];
  413.             $posy = (int)$this->point['y'];
  414.  
  415.             $angle += $this->theta;
  416.         }
  417.         /* 塗りつぶした多角形を描画する */
  418.         $this->setColor($fill);
  419.         imageFilledPolygon ($this->rscimg$polygon$this->num_column$this->color);
  420.  
  421.         /* 多角形を描画する */
  422.         $this->setColor($line);
  423.         imagePolygon ($this->rscimg$polygon$this->num_column$this->color);
  424.     }
  425.  
  426.     /**
  427.      * レーダーチャートの作成
  428.      *
  429.      * @access public
  430.      */
  431.     function radarChart()
  432.     {
  433.         /* 背景の色設定 */
  434.         $this->setColor('255,255,255');
  435.         imagefill($this->rscimg00$this->color);
  436.     
  437.         /* グラフの外枠と項目名 */
  438.         $this->setColor('100,100,100');
  439.         $this->Polygon();
  440.  
  441.         /* レーダー部分の設定 */
  442.         $this->Radar('200,0,0''255,100,100');
  443.  
  444.         /* 放射線部分の設定 */
  445.         $this->setColor('200,200,200');
  446.         $this->Radiation();
  447.  
  448.         /* 目盛りの数字部分の設定 */
  449.         $this->setColor('100,100,0');
  450.         $this->gridNumber();
  451.     }
  452. }
  453.  
  454.   print 'ここ<br>';
  455.   ini_set('display_errors',0);
  456.   header('Content-type:image/Png');
  457.  
  458.    /* valueの最大値は100までです。 */
  459.     $columns = array(
  460.         array('name'=>'test',    'value'=>70),
  461.         array('name'=>'test',    'value'=>85),
  462.         array('name'=>'test',    'value'=>100),
  463.         array('name'=>'test',     'value'=>100),
  464.         array('name'=>'test',    'value'=>100)
  465.     );
  466.  
  467.     $im = ImageCreate(350,350)
  468.     $bg = imagecolorallocate($im255255255);
  469.  
  470.     $objrdr = new RKT_radar(350,350);
  471.     $objrdr->setImage($im);
  472.  
  473.     $objrdr->setColumns($columns);
  474.  
  475.     /* TrueTypeフォントを使用する */
  476.     $objrdr->setFontMode(FONT_TRUE_TYPE);
  477.     $objrdr->setFontFile('seap.ttf');
  478.  
  479.     $objrdr->radarChart();
  480.  
  481.     ImagePng($im)
  482.     ImageDestroy($im);
  483.     
  484. ?>

この質問への意見の募集は締め切られ、ポイントは既に配分されました。
意見を投稿することはできますが、ポイントを受け取ることはできません。



ツリー一覧

┗A01signalImagePng($im); で画像データを出力してるのに、その
 ┗A01-1hayato0210ご回答ありがとうございます。 そうなのですか?
  ┗A01-1-1shimix文字列と画像を一度に返すおつもりで?基本的にhttpレ
   ┗A01-1-1-1hayato0210すみません。できました。 ありがとうございます><

回答一覧

並び替え:

A01
answerersignal [2月25日 01:15]

ImagePng($im);
で画像データを出力してるのに、その手前で関係ない出力があれば
それが画像として壊れるのは当然でしょう

逆になぜ動くはずという考えに至ったのか疑問です

この意見に回答する

ツリーへ TOPへ

A01-1
replyerhayato0210 [2月25日 01:45]

ご回答ありがとうございます。
そうなのですか?

では画像を表示する前に文字列を表示することはできないのでしょうか?
例えば

print '○○の図<br>';
画像

みたいな感じな事は出来ないのでしょうか?

この意見に回答する

ツリーへ TOPへ

A01-1-1
replyershimix [2月25日 08:55] (最終編集:2月25日 17:25)

文字列と画像を一度に返すおつもりで?基本的にhttpレスポンスで返すContent-typeは1種類だけです(ブラウザも2種類のコンテンツを返されると迷惑じゃないかと・・)。htmlソースと、その中で(img要素で)指定した画像に分けるしかないです。

似たような質問は過去にたくさんあります。

  http://www.phppro.jp/qa/2482
  http://www.phppro.jp/qa/2486
  http://www.phppro.jp/qa/2533


単純にHTMLからanchorで別ウィンドウで開くケースでも、画像ファイルを指定すれば「画像のみ」しか表示出来ませんよね(表示位置もほとんどのブラウザで左上固定)。何らかの別の情報も含めたければ、その画像ファイルを(img要素として)含むHTMLファイルを指定するしかありません。ブラウザがhtmlソースに書かれているimg要素のsrc属性のURLにアクセスして画像ファイルを取得します。

この意見に回答する

ツリーへ TOPへ

A01-1-1-1
replyerhayato0210 [2月25日 16:20]

すみません。できました。
ありがとうございます><

この意見に回答する

ツリーへ TOPへ

<<質問一覧へ



Pick Up Q&A

Q
PHPのHTML埋め込み記述について
 このエントリーをはてなブックマークに追加 
A
$_POST["data"] == "男" ? $val = "checked" : $val = "" ; の意味は以下と同じです。 if($_POST["data"] == "男"){ $val = "checked; } e...

>>続きを読む

kende様のご指摘通り、三項演算子を使用する際には、コードの複雑度などを考慮する必要がありますね。書きやすさと共に可読性も追求したいところですね。

▲解説者:岡本(アシアル株式会社 教育コーディネーター兼 システムエンジニア)