NO IMAGE

Canvasで折れ線グラフ IE8対応

  • 2012年6月27日
  • 2013年11月7日
  • Canvas
  • 46view
  • 0件

20120627円グラフを描いた際は、IE8対応に、Google謹製のexcanvas.js を使用しました。

今回は文字を描く関数fillText()を使ったのですが、excanvas.jsが対応しておらず、そこでエラーを吐き動作停止。

Web検索したら、文字も書けるJavaScriptライブラリ「uupaa-excanvas.js」があると言うことで、それを組み込んでみました。

このライブラリは、マイクロソフトのSilverlightあるいはVMLというプラグインだかアドオンを利用して描画するようです。

なんとか、組み込んで描画するようにはなったものの、表示が完了するまで15秒程待たされます。 ・・・これでは、時間がかかり過ぎて、あまり実用的では ないと言う印象です。 ・・・IE9なら即時に表示されることを考えると、私の実装方法に問題があるのでしょう。ネット上の情報から、よく理解せずに、適当に実装しているのでスムーズに動かいないもの当然か・・・orz・・・。

2013/10/13追記:
IE10の開発モードでIE8にすると全く動きません。現在運用HPでは、「uupaa-excanvas.js」は使用しておらず、IE8時はpng画像を表示するようにしています。

・・・IE8対応ばかりやってたら、全然、コンテンツ移管作業の方が進んでいません。

今後は方針を、「まずはIE9で動作すれば吉とし、IE8以前への対応は後回し」 に切り替え、しばらく単純作業に戻ろうと思います。

折れ線グラフの方は、縦軸は左側だけにして、より分りやすくスッキリさせたつもりです。

データを追加する際は、ソース中の変数 imax にデータ総数(現在は16年分なので0~15で15)を、配列変数 kensa_year に西暦を、配列変数 kensa_i に胃内視鏡検査の回数を、配列変数 kensa_d に大腸内視鏡検査の回数を、配列変数 kensa_f に腹部超音波検査の回数を追加します。

試しに、適当なデータを5年分追加してみましたが、他のところはイジル必要なく折れ線グラフが表示できました。検査件数が、現在のエリアからハミ出すくらい増えた場合は全体的に修正対応が必要ですが、しばらくは、簡単にデータ更新ができそうです。^^

みっともないサンプルソースはこちら。・・・試す場合は文字コードをUTF-8として保存して下さい。


<!DOCTYPE html>
<html lang="ja">
<head>
	<title>Canvasで折れ線グラフ</title>
	<meta charset="UTF-8">
	<meta content="text/html; charset=utf-8" http-equiv="content-type">
	<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
	<link href="http://fonts.googleapis.com/css?family=Oswald%27%20rel=%27stylesheet">
	<style type="text/css">
	[role="main"] {
		position: relative;
		min-height: 1440px;
		z-index: 9999;
		padding: 5px 5px;
	}
	[role="main"] .entry {
		float: left;
		margin: 5px 5px;
		padding-top: 10px;
		padding-bottom: 10px;
		padding-left: 10px;
		background-color: #e9e4e1;
		-webkit-border-radius: 8px;
		-moz-border-radius: 8px;
		border-radius: 8px;
	}
	[role="main"] .entry .date {
		float: right;
		padding-right: 8px;
		font-size: 12px;
	}
	[role="main"] .entry-body {
		clear: both;
		width: 600px;
		margin-right: 10px;
		font-size: 14px;
		line-height: 1.6;
		text-align: justify;
		-ms-text-justify: inter-ideograph;
		text-justify: inter-ideograph;
	}
	#kensa_count {
		width: 590px;
		height: 545px;
		margin: 5px;
		background-color: ivory;
		border: 1px #aaa solid; //* 枠線の装飾 */
	}
	@media screen and (max-width: 639px) {
		#kensa_count {
			width: 440px;
			height: 406px;
		}
		#kensa_kensuu {
			margin-left: 5px;
		}
		[role="main"] .entry-body {
			width: auto;
		}
	}
	@media screen and (max-width: 476px) {
		#kensa_count {
			width: 277px;
			height: 256px;
		}
	}
	</style>
	<!--[if lt IE 9]>
	<script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script> <![endif]-->
	<script type="text/xaml" id="xaml"><?xml version="1.0"?>
		<Canvas xmlns="http://schemas.microsoft.com/client/2007"></Canvas></script>
	<script type="text/javascript" src="../_shared/js/uupaa-excanvas.js"></script>
	<script type="text/javascript">
	<!--

	// IEのバージョンを取得(IE以外のブラウザは0)
	var msie = navigator.appVersion.toLowerCase();
	msie = (msie.indexOf('msie')>-1)?parseInt(msie.replace(/.*msie[ ]/,'').match(/^[0-9]+/)):0;

	function addFigure(str) {
		var num = new String(str).replace(/,/g, "");
		while(num != (num = num.replace(/^(-?\d+)(\d{3})/, "$1,$2")));
		return num;
	}

	var ie_ctrl = 0;
	if((msie<9&&msie>0)) { // IE8以下での処理
		ie_ctrl = 15;
	}

	var imax = 15;
	var kensa_year = [1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011];
	var kensa_i = [ 600, 690, 774, 722, 829, 887, 838, 863, 927,1058,1172,1229,1302,1398,1510,1533];
	var kensa_d = [ 194, 217, 227, 238, 239, 212, 256, 263, 255, 238, 229, 265, 261, 231, 230, 218];
	var kensa_f = [ 633, 607, 727, 642, 771, 810, 830, 811, 929,1057,1139,1169,1225,1325,1407,1436];

	onload = function(){

		var ctx = document.getElementById("kensa_count").getContext("2d");

		var x_start = 60;
		var y_start = 495;
		var x_width = (590 - x_start * 2) / imax;
		var x_txt_top = 80;
		var x_txt_top2 = 364;
		var y_txt_top = 200;
		var y_txt_top2 = 368;
		var year_xx = 0;
		var year_yy = 0;

		ctx.font = "22px Meiryo";
		ctx.fillText("年度別 検査件数", 204, 32 -(ie_ctrl*1.6));

		//背景(四角の背景色)
		for(i = 0 ; i <= 9 ; i++ ) {
			ctx.beginPath();
			ctx.fillStyle = 'beige';
			if(i<9){
				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<9){
				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 <= 18 ; 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*18))
			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*18));
		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) - 10, y_start +24 -ie_ctrl);
		}
		//背景(縦軸左側の単位)
		for(i = 0 ; i <= 9 ; i++) {
			ctx.fillStyle = 'rgb(17,43,116)';
			ctx.textAlign = 'right';
			ctx.fillText(addFigure(200*i), 20+32, y_start-100/2*i+4 -ie_ctrl);
		}
		//説明の背景
		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 -ie_ctrl);

		//大腸内視鏡検査
		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 -ie_ctrl);

		//腹部超音波検査
		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 -ie_ctrl);

	}

	//検査データを表に書き出し
	function kensa_data_list() {
		var content = "<Table Border=1 bordercolor='dimgray' bordercolorlight='dimgray' bordercolordark='dimgray' Width='100%' Align='left' CellSpacing=0 CellPadding=10 BgColor='ivory'>";
		content += "<Tr align='center' bordercolor='dimgray' bordercolorlight='dimgray' bordercolordark='dimgray'><Td>年度</Td><Td>胃内視鏡検査</Td><Td>大腸内視鏡検査</Td><Td>腹部超音波検査</Td></Tr>";
		for(i = 0 ; i <= imax ; i++) {
			content += "<Tr bordercolor='dimgray' bordercolorlight='dimgray' bordercolordark='dimgray'>";
			content += "<Td align='center'>" + kensa_year[i] + "(H" + (kensa_year[i]-1988) + ")</Td>";
			content += "<Td align='right'>" + addFigure(kensa_i[i]) + "</Td>";
			content += "<Td align='right'>" + kensa_d[i] + "</Td>";
			content += "<Td align='right'>" + addFigure(kensa_f[i]) + "</Td>";
			content += "</Tr>";
		}
		content += "</TABLE><BR CLEAR='ALL'>";

		document.getElementById('kensa_kensuu').innerHTML = content;
	}
	//-->
	</script>
</head>
<body>
	<div id="content">
		<div role="main">
			<article class="entry">
				<div class="date">2012/06/26 更新</div>
				<div class="entry-body">
					<h1 class="entry-title">検査件数 推移グラフ</h1>
					<canvas id="kensa_count" width="590" height="545"> このコンテンツの表示にはCANVASに対応したブラウザをご利用下さい。 </canvas>
					<div role="clear"></div>
					<!-- -->
					<!-- 関連情報・依頼事項など -->
					<ol>
					<li type="disc">このグラフの表示にはCANVASに対応したブラウザ(IEならバージョン9以上)が必要です。御了承下さい。</li>
					<li type="disc">IE8でこのグラフを表示させるためにはブラウザにプラグイン「silverlight」をインストールして下さい。<a href="http://www.microsoft.com/ja-jp/silverlight/download.aspx" target="_blank">ダウンロードはこちらから。</a></li>
					</ol>
				</div>
			</article>
			<article class="entry">
				<div class="date">2012/06/26 更新</div>
				<div class="entry-body">
					<h1 class="entry-title">検査件数 データ表</h1>
					<div id="kensa_kensuu" style="margin: 11px 0px 0px 3px;"><script>kensa_data_list()</script></div>
					<div role="clear"></div>
					<!-- -->
					<!-- 関連情報・依頼事項など -->
					<ol>
					<li type="disc">「検査件数」記事に関して、記載内容の間違い等にお気付きの方は、御連絡していただけると助かります。</li>
					</ol>
				</div>
			</article>
		<!--/main--></div>
	<!--/content--></div>
</body>
</html>