/*
	グラフを描画するＡＰＩ
*/


if (!window.KN) {
	var KN = {};
}

KN.Graph = {};

KN.Graph.Class = function()
{
	var color_ = [
		  {graph:"#FF6666", num:"#990000"}, {graph:"#66FF66", num:"#009900"}
		, {graph:"#6666FF", num:"#000099"}, {graph:"#FFFF66", num:"#999900"}
		, {graph:"#FF66FF", num:"#990099"}, {graph:"#66FFFF", num:"#009999"}
		, {graph:"#666666", num:"#000000"}
	];

	var num_rad_ratio_ = 0.6;	// 円グラフ数値表示の半径に対する位置。
	var max_number_ = 0;
	var adjust_ = { percent:0, width:0, grade:0 };
	var values_ = [];
	var vl_ = 0;				// Value Length
	var total_ = 0;
	var offset_ = [];
	var show_ = { name:true, num:true, percent:true };

	// (x,y)が含まれる円グラフの項目のインデックスを返す。
	var getArea = function(x, y)
	{
		var rad = (1 - Math.atan2(x, y) / Math.PI) * total_ * 0.5;

		for (var i = 0; i < vl_; ++i) {
			if (values_[i].ruikei > rad) {
				return i;
			}
		}
		return 0;
	};

	// 角度th, yの時のx を返す。
	var getX = function(y, th)
	{
		var t = th > Math.PI * 0.5 && th < Math.PI * 1.5;

		if (y <  0 && t || y >= 0 && !t) {
			return null;
		}

		var tan = Math.tan(th + 1.5 * Math.PI);
		return tan ? y / tan : 0;
	};

	// データのソート
	this.SortAsc  = function() { values_ = values_.sortBy( function(node, index) { return  node.num; } ); };
	this.SortDesc = function() { values_ = values_.sortBy( function(node, index) { return -node.num; } ); };

	// 項目名,数量,%の表示/非表示切り替え
	this.SetShowName    = function(flg) { show_.name	= flg; };
	this.SetShowNumber  = function(flg) { show_.num		= flg; };
	this.SetShowPercent = function(flg) { show_.percent	= flg; };

	// 色をセットする。
	this.SetColor = function() { color_ = arguments; };

	// 円グラフ、帯グラフで、項目名等の表示が重ならないように調整する。
	this.AdjustPosition = function(percent, width, grade) { adjust_ = { percent:percent, width:width, grade:grade }; };

	// 値をセットする。{name:項目名,num:数値},..
	this.SetValues = function()
	{
		values_ = $A(arguments);
		total_ = 0;

		// 合計,最大値を計算。色の割り当て。
		max_number_ = 0;
		var cl = color_.length;
		vl_ = values_.length;

		values_.each(
			function(node, index)
			{
				total_ += node.num;
				if (max_number_ < node.num) {
					max_number_ = node.num;
				}
				node.color = color_[index % cl];
				offset_[index] = { x:0, y:0 };
			}
			);

		values_[0].ruikei = values_[0].num;

		for (var i = 1; i < vl_; ++i) {
			values_[i].ruikei = values_[i-1].ruikei + values_[i].num;
		}
	};

	// 凡例
	this.DrawTable = function(id)
	{
		var table = "";

		values_.each(
			function(node, index)
			{
				table +=	"<tr>"
					+		"<td style='border-style:none;padding:0px 0.5em 0px 0px;'><div style='width:0.8em;height:0.8em;background-color:" + node.color.graph + ";'></div></td>"
					+		"<td style='font-size:small;padding:0px;border-style:none;color:" + node.color.num + ";'>" + node.name + "</td>"
					+		"</tr>";
			}
			);
		$(id).innerHTML = "<table style='border-style:none;border-collapse:collapse;margin:0px;padding:0px;'>" + table + "</table>";
	};

	// 棒グラフ
	this.DrawBar = function(id, width, height)
	{
		var table = "";
		var percent = 0;

		values_.each(
			function(node, index)
			{
				table +=	"<tr>";
				if (show_.name) {
					table +=	"<td style='border-style:none;margin:0px;padding:0px 0.5em 0px 0px;'><span style='font-size:x-small;color:" + node.color.num + ";'>" + node.name + "</span></td>";
				}
				table	+=	"<td style='border-style:none;margin:0px;padding:0px;'>"
						+	"<span style='font-size:x-small;margin-left:3px;position:absolute;color:" + node.color.num + ";'>";
				if (show_.num) {
					table +=	node.num;
				}
				if (show_.percent) {
					// 小数点第2桁目を四捨五入
					percent = Math.floor(node.num * 1000 / total_ + 0.5) / 10;
					table +=	"(" + percent + "%)";
				}
				table +=	"</span>";
				table +=	"<div style='overflow:hidden;width:" + Math.floor(width * node.num / max_number_) + "px;height:" + height + "px;background-color:" + node.color.graph + ";'></div></td>"
					+		"</tr>";
			}
			);
		$(id).innerHTML = "<table style='border-style:none;border-collapse:collapse;margin:0px;padding:0px;'>" + table + "</table>";
	};

	// 帯グラフ
	this.DrawColumn = function(id, width, height)
	{
		var gr = "";
		var val = "";
		var b_percent = 0;

		values_.each(
			function(node, index)
			{
				// 小数点第2桁目を四捨五入
				var percent = Math.floor(node.num * 1000 / total_ + 0.5) / 10;
				var left	= Math.floor(b_percent);

				// グラフ値(名前,数値,パーセント)描画の文字列作成
				val +=	"<span style='font-size:x-small;position:absolute;"
					+	"top:" + (2 + (percent <= adjust_.percent ? adjust_.width * (index % (adjust_.grade+1)) : 0)) + "px;"
					+	"left:" + (left + 2) + "px;color:" + node.color.num + ";'>";

				if (show_.name) {
					val += node.name;
				}
				if (show_.name && show_.num) {
					val += "<br/>";
				}
				if (show_.num) {
					val += node.num;
				}
				if (show_.percent) {
					val += "(" + percent + "%)";
				}

				val +=	"</span>";

				// グラフ本体
				var w = node.num * width / total_;
				gr += "<div style='overflow:hidden;position:absolute;left:" + left + "px;top:0px;width:" + Math.floor(w) + "px;height:" + height + "px;background-color:" + node.color.graph + ";'></div>";
				b_percent += w;
			}
			);
		$(id).style.verticalAlign = "top";
		$(id).innerHTML = "<div style='position:relative;margin:0px;padding:0px;'>" + gr + val + "</div>";
	};

	// 円グラフの項目をずらして表示する際のずれ幅を指定する。。
	this.SetOffset = function(index, x, y) { offset_[index] = {x:x, y:y}; };

	// 円グラフ
	this.DrawCircle = function(id, radius, mag)
	{
		var border;
		var tmp;
		var counter;
		var x, x2, y, y2;
		var i;
		var gr = "";
		var border_rad = [];

		if (typeof mag == "undefined") {
			mag = 1;
		}

   		// 各項目の境界線の角度
		values_.each( function(node, index) {
			border_rad[index] = 2 * Math.PI * node.ruikei / total_;
		});

		for (y = -radius; y <= radius; ++y) {

			counter = 0;
			border = [];

			values_.each( function(node, index) {
				var x = getX(y, border_rad[index]);

				// 円の外側の座標は排除
				if (x !== null && x * x + y * y < radius * radius) {
					border[counter++] = Math.floor(x);
				}
			});

			// 弧
			tmp = Math.floor( Math.sqrt(radius * radius - y * y) );
			border.push(tmp);
			border.push(-tmp);

			// ソート
			border.sort( function (a, b) { return a - b; } );

			// border[n]→border[n+1]
			var bl = border.length - 1;

			for (i = 0; i < bl; ++i) {
				x  = border[i];
				x2 = border[i + 1];

				tmp = getArea(x2 - 1, y);

				x += offset_[tmp].x;
				x2 += offset_[tmp].x;
				y2 = y + offset_[tmp].y;

				gr += "<div style='position:absolute;overflow:hidden;left:"  + (x + radius) * mag + "px;top:" + (y2 + radius) * mag + "px;"
					+	"width:" + (x2 - x) * mag + "px;height:" + mag + "px;background-color:" + values_[tmp].color.graph + ";'></div>";
			}
		}


		// 文字描画
		var val = "";

		values_.each(
			function(node, index)
			{
				// 小数点第2桁目を四捨五入
				var percent = Math.floor(node.num * 1000 / total_ + 0.5) / 10;

				// 文字半径
				var num_radius = radius * num_rad_ratio_
					+ (percent <= adjust_.percent ? adjust_.width * (adjust_.grade - index % (adjust_.grade + 1)) : 0);

				// グラフ値(名前,数値,パーセント)描画の文字列作成
				var rad = ((node.ruikei * 2 - node.num) / total_ - 0.5) * Math.PI;
				var x = offset_[index].x + Math.floor(radius - 4 + num_radius * Math.cos(rad) - node.name.length * 5);
				var y = offset_[index].y + Math.floor(radius - 6 + num_radius * Math.sin(rad));

				val += "<span style='position:absolute;left:0px;top:0px;text-align:center;font-size:x-small;top:" + y + "px;left:" + x + "px;color:" + node.color.num + ";'>";

				if (show_.name) {
					val += node.name;
				}
				if (show_.num) {
					if (show_.name) {
						val += "<br/>";
					}
					val += node.num;
				}
				if (show_.percent) {
					val += "(" + percent + "%)";
				}
				val += "</span>";
			}
			);

		$(id).style.verticalAlign = "top";
		$(id).innerHTML = "<div style='position:relative;margin:0px;padding:0px;'>" + gr + val + "</div>";
	};
};

KN.Graph.Create = function() { return new KN.Graph.Class(); };


