昨年度の「胃 内視鏡」「大腸 内視鏡」「腹部 超音波」の各検査件数を送って頂きました。

CSVファイル「count.csv」にデータを追加しました。
(下記ソースファイルcount.csvの21行目)

このCSVファイルは、折れ線グラフを描画するPHPプログラムと、データリストを描画するPHPプログラムの両方で参照されます。

折れ線グラフの描画は、「kensa_count.php」で行っています。

データ数(行数)をカウントし取得する関数があるのかも知れませんが、現状はプログラム内の変数に代入しているので、そこも修正。
(下記ソースファイルkensa_count.phpの34行目)

折れ線グラフはCANVASで描画していますが、非対応の旧ブラウザでも表示できるように、描画されたグラフをキャプチャして、PNG画像を代替画像として設定しています。

データリストの描画は、「kensa_count_data.php」で行っています。

こちらも、データ数(行数)をプログラム内の変数に代入している部分を修正。
(下記ソースファイルkensa_count_data.phpの15行目)

現在のデータ数は21ですが、プログラムでは、0からカウントするので20を代入しています。

実際のホームページ(WordPress)では、インランフレーム内でPHPプログラムをコール。データ数が増える度に、インラインフレームの高さ(height)の値を増やす必要あり。

データリストの折りたたみ処理は、WordPressのプラグインを利用。
「Arconix Shortcodes」だったかな。

・・・最近、忘れっぽくなってきたので、覚え書きです。・・・



CSVファイルの最終行にデータを追加(21行目)。
左から、「年度」、「胃内視鏡検査件数」、「大腸内視鏡検査件数」、「腹部超音波検査件数」。

1996,600,194,633
1997,690,217,607
1998,774,227,727
1999,722,238,642
2000,829,239,771
2001,887,212,810
2002,838,256,830
2003,863,263,811
2004,927,255,929
2005,1058,238,1057
2006,1172,229,1139
2007,1229,265,1169
2008,1302,261,1225
2009,1398,231,1325
2010,1510,230,1407
2011,1533,218,1436
2012,1599,226,1485
2013,1669,250,1562
2014,1839,298,1648
2015,1855,267,1772
2016,1661,301,1812



折れ線グラフを描画するPHPプログラム。ソース内で、データ件数を修正(34行目)。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <style type="text/css">
      #kensa_count {
      	width: 760px;
      	height: 590px;
      	background-color: ivory;
			border: 1px #aaa solid;		//* 枠線の装飾 */
      }
      @media screen and (max-width: 599px) {
        #kensa_count {
            width: 560px;
            height: 435px;
        }
      }
      @media screen and (max-width: 476px) {
      #kensa_count {
          width: 330px;
          height: 256px;
        }
      }
    </style>
    <script type="text/javascript">  
    <!--  
      //3桁区切りを付加する関数
      function addFigure(str) { 
        var num = new String(str).replace(/,/g, ""); 
        while(num != (num = num.replace(/^(-?\d+)(\d{3})/, "$1,$2"))); 
        return num; 
      } 

      var imax = 20;

		var kensa_year = [<?php
		   $filepath = "./count.csv";
		   $file = new SplFileObject($filepath); 
		   $file->setFlags(SplFileObject::READ_CSV); 
		   foreach ($file as $line) {
		      if (!empty($line[0])) { //フィールドデータのないレコードは除外
		         if ($line[0] == '1996') {
		            echo "".$line[0]."";  // 最初
		         }else{
		            echo ",".$line[0].""; // 2つ目以降
		         }
		      }
		   }
		?>];

		var kensa_i = [<?php
		   $filepath = "./count.csv";
		   $file = new SplFileObject($filepath); 
		   $file->setFlags(SplFileObject::READ_CSV); 
		   foreach ($file as $line) {
		      if (!empty($line[0])) { //フィールドデータのないレコードは除外
		         if ($line[0] == '1996') {
		            echo "".$line[1]."";  // 最初
		         }else{
		            echo ",".$line[1].""; // 2つ目以降
		         }
		      }
		   }
		?>];

		var kensa_d = [<?php
		   $filepath = "./count.csv";
		   $file = new SplFileObject($filepath); 
		   $file->setFlags(SplFileObject::READ_CSV); 
		   foreach ($file as $line) {
		      if (!empty($line[0])) { //フィールドデータのないレコードは除外
		         if ($line[0] == '1996') {
		            echo "".$line[2]."";  // 最初
		         }else{
		            echo ",".$line[2].""; // 2つ目以降
		         }
		      }
		   }
		?>];

		var kensa_f = [<?php
		   $filepath = "./count.csv";
		   $file = new SplFileObject($filepath); 
		   $file->setFlags(SplFileObject::READ_CSV); 
		   foreach ($file as $line) {
		      if (!empty($line[0])) { //フィールドデータのないレコードは除外
		         if ($line[0] == '1996') {
		            echo "".$line[3]."";  // 最初
		         }else{
		            echo ",".$line[3].""; // 2つ目以降
		         }
		      }
		   }
		?>];

      onload = function(){

        var ctx = document.getElementById("kensa_count").getContext("2d");
        var x_start = 60;
        var y_start = 545;
        var x_width = (760 - x_start * 2) / imax;
        var x_txt_top = 80;
        var x_txt_top2 = 564;
        var y_txt_top = 200;
        var y_txt_top2 = 395;
        var year_xx = 0;
        var year_yy = 0;
        var yt = 20;	// 縦方向のブロック数
        var ytc = yt /2 ;	// 縦方向のカウント
        
        ctx.font = "22px Meiryo";
        ctx.fillText("年度別 検査件数 推移グラフ", 248, 32);

        //背景(四角の背景色)
        for(i = 0 ; i <= ytc ; i++ ) {
        ctx.beginPath();
          ctx.fillStyle = 'beige';
          if(i<ytc){
            ctx.fillRect(x_start,y_start-(100/4)-(100/4*i)-(100/4*i),x_width*(imax+1),100/4);
          }
          ctx.fillStyle = 'honeydew';
          if(i<ytc){
            ctx.fillRect(x_start,y_start-(100/4)-(100/4)-(100/4*i)-(100/4*i),x_width*(imax+1),100/4);
          }
        }
        //背景(水平線)
        for(i = 0 ; i <= yt ; i++ ) {
          ctx.beginPath();
          ctx.strokeStyle = '#aaa';
          ctx.lineWidth = 1;
          ctx.moveTo(x_start+(x_width*0),y_start-100/4*i)
          ctx.lineTo(x_start+(x_width*(imax+1)),y_start-100/4*i);
          ctx.stroke();
        }
        //背景(垂直線)
        for(i = 0 ; i <= imax ; i++) {
          ctx.beginPath();
          ctx.strokeStyle = '#aaa';
          ctx.lineWidth = 1;
          ctx.moveTo(x_start+(x_width*(i+1)),y_start-(100/4*yt))
          ctx.lineTo(x_start+(x_width*(i+1)),y_start);
          ctx.stroke();
        }
        //横軸
          ctx.beginPath();
          ctx.strokeStyle = '#000';
          ctx.lineWidth = 1;
          ctx.moveTo(x_start,y_start)
          ctx.lineTo(x_start+(x_width*(imax+1)),y_start);
          ctx.stroke();
        
        //縦軸
          ctx.beginPath();
          ctx.moveTo(x_start,y_start)
          ctx.lineTo(x_start,y_start-(100/4*yt));
          ctx.stroke();
        
        for(i = 0 ; i <= (imax/2) ; i++) {
        //背景(横軸下部の単位・・・年)
          ctx.font = "14px Meiryo";
          ctx.fillStyle = 'black';
          year_xx = (kensa_year[i*2]-1900);
          year_yy = year_xx;
          if(year_xx>=100){ year_yy = (kensa_year[i*2]-1900-100); }
				 if(year_yy<10){ year_yy = "0" + year_yy; }
			    ctx.fillText("'" + year_yy , x_start+(x_width*i*2) - 12, y_start +24);
        }
        //背景(縦軸左側の単位)
        for(i = 0 ; i <= ytc ; i++) {
          ctx.fillStyle = 'rgb(17,43,116)';
          ctx.textAlign = 'right';
          ctx.fillText(addFigure(200*i), 20+32, y_start-100/2*i+4);
        }
        //説明の背景
          ctx.beginPath();
          ctx.fillStyle = '#ddd';
          ctx.fillRect(x_txt_top -10,y_txt_top -20,170,54);
          ctx.fillRect(x_txt_top2 -10,y_txt_top2 +10,170,30);
        
        //胃内視鏡検査
        for(i = 0 ; i <= imax ; i++) {
          ctx.beginPath();
          ctx.fillStyle = 'rgb(17,43,116)';
          ctx.arc(x_start+(x_width*i),y_start-((kensa_i[i])/4),3,0,Math.PI*2,false);
          ctx.fill();
        }
        for(i = 0 ; i <= (imax-1) ; i++) {
          ctx.beginPath();
          ctx.strokeStyle = 'rgb(17,43,116)';
          ctx.lineWidth = 2;
          ctx.moveTo(x_start+(x_width*i),y_start-((kensa_i[i])/4))
          ctx.lineTo(x_start+(x_width*(i+1)),y_start-((kensa_i[(i+1)])/4));
          ctx.stroke();
        }
        ctx.beginPath(); ctx.arc(x_txt_top,y_txt_top - 4,3,0,Math.PI*2,false); ctx.fill();
        ctx.beginPath(); ctx.arc(x_txt_top + 30,y_txt_top - 4,3,0,Math.PI*2,false); ctx.fill();
        ctx.beginPath(); ctx.moveTo(x_txt_top,y_txt_top - 4); ctx.lineTo(x_txt_top + 30,y_txt_top - 4); ctx.stroke();
        ctx.font = "16px Meiryo";
        ctx.textAlign = 'left';
        ctx.fillText("胃内視鏡検査", x_txt_top + 40,y_txt_top);   

        //大腸内視鏡検査
        for(i = 0 ; i <= imax ; i++) {
          ctx.beginPath();
          ctx.fillStyle = 'orangered';
          ctx.arc(x_start+(x_width*i),y_start-((kensa_d[i])/4),3,0,Math.PI*2,false);
          ctx.fill();
        }
        for(i = 0 ; i <= (imax-1) ; i++) {
          ctx.beginPath();
          ctx.strokeStyle = 'orangered';
          ctx.lineWidth = 2;
          ctx.moveTo(x_start+(x_width*i),y_start-((kensa_d[i])/4))
            ctx.lineTo(x_start+(x_width*(i+1)),y_start-((kensa_d[(i+1)])/4));
          ctx.stroke();
        }
        ctx.beginPath(); ctx.arc(x_txt_top2,y_txt_top2 +30 -4,3,0,Math.PI*2,false); ctx.fill();
        ctx.beginPath(); ctx.arc(x_txt_top2 + 30,y_txt_top2 +30 -4,3,0,Math.PI*2,false); ctx.fill();
        ctx.beginPath(); ctx.moveTo(x_txt_top2,y_txt_top2 +30 -4); ctx.lineTo(x_txt_top2 + 30,y_txt_top2 +30 -4); ctx.stroke();
        ctx.fillText("大腸内視鏡検査", x_txt_top2 + 40,y_txt_top2 +30);   

        //腹部超音波検査
        for(i = 0 ; i <= imax ; i++) {
          ctx.beginPath();
          ctx.fillStyle = 'green';
          ctx.arc(x_start+(x_width*i),y_start-((kensa_f[i])/4),3,0,Math.PI*2,false);
          ctx.fill();
        }
        for(i = 0 ; i <= (imax-1) ; i++) {
          ctx.beginPath();
          ctx.strokeStyle = 'green';
          ctx.lineWidth = 2;
          ctx.moveTo(x_start+(x_width*i),y_start-((kensa_f[i])/4))
            ctx.lineTo(x_start+(x_width*(i+1)),y_start-((kensa_f[(i+1)])/4));
          ctx.stroke();
        }
        ctx.beginPath(); ctx.arc(x_txt_top,y_txt_top +24 -4,3,0,Math.PI*2,false); ctx.fill();
        ctx.beginPath(); ctx.arc(x_txt_top + 30,y_txt_top +24 -4,3,0,Math.PI*2,false); ctx.fill();
        ctx.beginPath(); ctx.moveTo(x_txt_top,y_txt_top +24 -4); ctx.lineTo(x_txt_top + 30,y_txt_top +24 -4); ctx.stroke();
        ctx.fillText("腹部超音波検査", x_txt_top + 40,y_txt_top +24);   

    }
        
    //-->  
    </script>
  </head>
  <body style="margin:0; padding:0;">
		<canvas id="kensa_count" width="760" height="590"><img src="./kensa_count_2016.png" alt="kensa_count_2016.png" hspace="0" border="0" vspace="0" width="760" height="590"></canvas>
  </body>
</html>



データリストを描画するPHPプログラム。ソース内でデータ件数を修正(15行目)。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <title>沢田内科医院</title>
    <meta charset="UTF-8">
    <script type="text/javascript">  
    <!--  
      //3桁区切りを付加する関数
      function addFigure(str) { 
        var num = new String(str).replace(/,/g, ""); 
        while(num != (num = num.replace(/^(-?\d+)(\d{3})/, "$1,$2"))); 
        return num; 
      } 

      var imax = 20;

		var kensa_year = [<?php
		   $filepath = "./count.csv";
		   $file = new SplFileObject($filepath); 
		   $file->setFlags(SplFileObject::READ_CSV); 
		   foreach ($file as $line) {
		      if (!empty($line[0])) { //フィールドデータのないレコードは除外
		         if ($line[0] == '1996') {
		            echo "".$line[0]."";  // 最初
		         }else{
		            echo ",".$line[0].""; // 2つ目以降
		         }
		      }
		   }
		?>];

		var kensa_i = [<?php
		   $filepath = "./count.csv";
		   $file = new SplFileObject($filepath); 
		   $file->setFlags(SplFileObject::READ_CSV); 
		   foreach ($file as $line) {
		      if (!empty($line[0])) { //フィールドデータのないレコードは除外
		         if ($line[0] == '1996') {
		            echo "".$line[1]."";  // 最初
		         }else{
		            echo ",".$line[1].""; // 2つ目以降
		         }
		      }
		   }
		?>];

		var kensa_d = [<?php
		   $filepath = "./count.csv";
		   $file = new SplFileObject($filepath); 
		   $file->setFlags(SplFileObject::READ_CSV); 
		   foreach ($file as $line) {
		      if (!empty($line[0])) { //フィールドデータのないレコードは除外
		         if ($line[0] == '1996') {
		            echo "".$line[2]."";  // 最初
		         }else{
		            echo ",".$line[2].""; // 2つ目以降
		         }
		      }
		   }
		?>];

		var kensa_f = [<?php
		   $filepath = "./count.csv";
		   $file = new SplFileObject($filepath); 
		   $file->setFlags(SplFileObject::READ_CSV); 
		   foreach ($file as $line) {
		      if (!empty($line[0])) { //フィールドデータのないレコードは除外
		         if ($line[0] == '1996') {
		            echo "".$line[3]."";  // 最初
		         }else{
		            echo ",".$line[3].""; // 2つ目以降
		         }
		      }
		   }
		?>];

	//検査データを表に書き出し
	function kensa_data_list() {
		var content = "<div class=\"nendo\" style=\"float:left; width:29%; height:62px; display:flex; align-items:center; -webkit-justify-content:center; justify-content:center; margin:1px; background-color:silver;\">年 度</div>";
	          content += "<div style=\"float:left; width:22%; height:62px; display:flex; align-items:center; -webkit-justify-content:center; justify-content:center; margin:1px; word-wrap:break-word; background-color:skyblue;\">胃内視鏡検査</div>";
	          content += "<div style=\"float:left; width:23%; height:62px; display:flex; align-items:center; -webkit-justify-content:center; justify-content:center; margin:1px; word-wrap:break-word; background-color:palegreen;\">腹部超音波検査</div>";
	          content += "<div style=\"float:left; width:23%; height:62px; display:flex; align-items:center; -webkit-justify-content:center; justify-content:center; margin:1px; word-wrap:break-word; background-color:lightsalmon;\">大腸内視鏡検査</div>";        
	        for(i = 0 ; i <= imax ; i++) {
	          content += "<div style=\"float:left; width:29%; height:30px; line-height:30px; margin:1px; text-align:center; background-color:silver;\">" + kensa_year[(imax - i)] + "(H" + (kensa_year[(imax - i)]-1988) + ")</div>";
	          content += "<div style=\"float:left; width:22%; height:30px; line-height:30px; margin:1px; text-align:center; background-color:skyblue;\">" + addFigure(kensa_i[(imax - i)]) + "</div>";
	          content += "<div style=\"float:left; width:23%; height:30px; line-height:30px; margin:1px; text-align:center; background-color:palegreen;\">" + addFigure(kensa_f[(imax - i)]) + "</div>";
	          content += "<div style=\"float:left; width:23%; height:30px; line-height:30px; margin:1px; text-align:center; background-color:lightsalmon;\">" + kensa_d[(imax - i)] + "</div>";
	        }
	        content += "<br clear='all'>";
	        
	        document.getElementById('kensa_kensuu').innerHTML = content;
	}

    //-->
    </script>
  </head>
  <body style="margin:0; padding:0;">
            <div id="kensa_kensuu" width="760" style="margin:0px;"><script>kensa_data_list()</script></div>
  </body>
</html>



2017/06/28追記:
その後、「kensa_count.php(34行目)」と「kensa_count_data.php(15行目)」の記述を改修

変更前:      var imax = 20;
変更後:      var imax = <?php echo count( file( "./count.csv" ) ); ?>-1;

検査件数のデータ追加の際、上記2つのファイルを修正する必要はなくなりました。
ただ、初回、表示に少し時間がかかる気もします。


関連ページ:
Canvasで折れ線グラフ IE8対応 ・・・この頃はデータをCSVファイルに抜き出していない。