1. 程式人生 > >簡單jQplot建立引擎(支援線圖/餅圖/柱狀圖)

簡單jQplot建立引擎(支援線圖/餅圖/柱狀圖)

實習公司專案需要從資料來源讀取一張表,然後通過指定一個字串的形式就能生成表格,於是我苦逼的吭哧吭哧鼓搗了挺久,弄了個初級版本demo出來。

用的是JQplot,直接貼程式碼:

index.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>

		<script type="text/javascript" src="js/jquery-1.8.3.js"></script>
		<link rel="stylesheet" type="text/css" href="js/jqplot/jquery.jqplot.min.css"/>
		<script type="text/javascript" src="js/jqplot/jquery.jqplot.min.js"></script>
		<script type="text/javascript" src="js/jqplot/plugins/jqplot.pieRenderer.min.js"></script>
		<script type="text/javascript" src="js/jqplot/plugins/jqplot.logAxisRenderer.min.js"></script>
		<script type="text/javascript" src="js/jqplot/plugins/jqplot.canvasTextRenderer.min.js"></script>
		<script type="text/javascript" src="js/jqplot/plugins/jqplot.categoryAxisRenderer.min.js"></script>
		<script type="text/javascript" src="js/jqplot/plugins/jqplot.canvasAxisTickRenderer.min.js"></script>
		<script type="text/javascript" src="js/jqplot/plugins/jqplot.pointLabels.min.js"></script>
		<script type="text/javascript" src="js/jqplot/plugins/jqplot.dateAxisRenderer.min.js"></script>
		<script type="text/javascript" src="js/jqplot/plugins/jqplot.highlighter.min.js"></script>
		<script type="text/javascript" src="js/jqplot/plugins/jqplot.enhancedLegendRenderer.min.js"></script>
		<script type="text/javascript" src="js/jqplot/plugins/jqplot.barRenderer.min.js"></script>
		<script type="text/javascript" src="index.js"></script>

	</head>
	<script type="application/x-javascript">
		var DataText = {};
		var listData = new Array();
		var pot;
		jQuery(function($) {
			var aa =  {"total":"15","rows":[{"price":31,"name":"li","datee":"2013-05-01","eat":"ps"},{"price":9,"name":"li","datee":"2013-05-02","eat":"st"},{"price":31,"name":"li","datee":"2013-05-03","eat":"ps"},{"price":31,"name":"li","datee":"2013-05-04","eat":"ps"},{"price":9,"name":"li","datee":"2013-05-05","eat":"st"},{"price":16,"name":"wang","datee":"2013-05-01","eat":"hb"},{"price":9,"name":"wang","datee":"2013-05-02","eat":"st"},{"price":31,"name":"wang","datee":"2013-05-03","eat":"ps"},{"price":16,"name":"wang","datee":"2013-05-04","eat":"hb"},{"price":9,"name":"wang","datee":"2013-05-05","eat":"st"},{"price":9,"name":"zhang","datee":"2013-05-01","eat":"st"},{"price":9,"name":"zhang","datee":"2013-05-02","eat":"st"},{"price":9,"name":"zhang","datee":"2013-05-03","eat":"st"},{"price":16,"name":"zhang","datee":"2013-05-04","eat":"hb"},{"price":16,"name":"zhang","datee":"2013-05-05","eat":"hb"}]};
			for (var i in aa.rows) {
				listData.push([aa.rows[i].name, aa.rows[i].datee, aa.rows[i].eat, aa.rows[i].price]);
			}
			/*listData
			 //    0         1         2    3
			 //[["li", "2013-05-01", "ps", 31],
			 //["li", "2013-05-02", "st", 9],
			 //["li", "2013-05-03", "ps", 31],
			 //["li", "2013-05-04", "ps", 31],
			 //["li", "2013-05-05", "st", 9],
			 //["wang", "2013-05-01", "hb", 16],
			 //["wang", "2013-05-02", "st", 9],
			 //["wang", "2013-05-03", "ps", 31],
			 //["wang", "2013-05-04", "hb", 16],
			 //["wang", "2013-05-05", "st", 9],
			 //["zhang", "2013-05-01", "st", 9],
			 //["zhang", "2013-05-02", "st", 9],
			 //["zhang", "2013-05-03", "st", 9],
			 //["zhang", "2013-05-04", "hb", 16],
			 //["zhang", "2013-05-05", "hb", 16]]*/

  			listData.push(["zhang", "2013-05-04", "hb", 119.5]);
			
//			listData.length=3;
//			console.log(listData);
			
			DataText = {
				contenter : "chart1",
				title : "dinner",
//				type : "line",
  				type:"bar",
//				type:"pie",
				line : {
					/*
					 * line
					 * 從上述listData變成返回Object data
					 * {
					 * 	legend:["li","wang","zhang"],
					 * 	rows:[
					 * 		(li的)[],
					 * 		(wang的)[],
					 * 		(zhang的)[]
					 * 	]
					 * }
					 */
  					groupByIndex : [0],
					xAxisIndex : 1,
					yAxisIndex : 3,
  					yAxisOpration: "max"
				},
				bar : {
					/*
					 * bar
					 * 從上述listData變成返回Object data
					 * {
					 * 	legend:["li","wang","zhang"],
					 * 	rows:[
					 * 		(li的)[],
					 * 		(wang的)[],
					 * 		(zhang的)[]
					 * 	]
					 * }
					 */
  					groupByIndex : [0,2],
  					xAxisIndex : 1,
					yAxisIndex : 3,
					yAxisOpration : "max"
				},
				/*
				 * pie/bar
				 * 從上述listData變成返回Object data
				 * {
				 * 	rows:[
				 * 		(li的)[],
				 * 		(wang的)[],
				 * 		(zhang的)[]
				 * 	]
				 * }
				 */
				pie : {
  					groupByIndex : [0],
					yAxisIndex : 3,
  					yAxisOpration : "sum"
				}
			}

			drawChart(DataText, listData);

			jQuery.each(DataText, function(index, itemValue) {
				if (!((index === "contenter") || (index === "title") || (index === "type"))) {
					jQuery("#changeChartType").append("<option>" + index + "</option>");
				}
			});

		});
		function changeChartType() {
	DataText.type = document.getElementById("changeChartType").value;
	pot.destroy();
	drawChart(DataText, listData);
}
	</script>
	<body>
		<div id="chart1" style="height:300px; width:500px;"></div>
		<select onchange="changeChartType()" id = "changeChartType"></select>
	</body>
</html>

index.js
function getdata(DataText, listData) {
	if (DataText.type === "line") {
		var Text = DataText.line;
		if (DataText.type === "bar") {
			Text = DataText.bar;
		}
		if (Text === undefined) {
			alert("Create Line Chart Error");
		} else {
			var Class = [];
			var RealClass = [];
			if (Text.groupByIndex === undefined) {
				Class = Text.xAxisIndex;
				RealClass = [];
				RealClass.push(Text.xAxisIndex);
			} else {
				Class = Text.groupByIndex;
				RealClass = Text.groupByIndex.concat();
				RealClass.push(Text.xAxisIndex);
			}
			var ClassData = [];
			var RealClassData = [];
			var ClassAndRealClassRelation = [];
			var data = [];

			jQuery.each(listData, function(index, itemValue) {
				var aClassItem = "";
				jQuery.each(Class, function(i, v) {
					aClassItem = aClassItem + itemValue[v] + ",";
				});
				aClassItem = aClassItem.substr(0, aClassItem.length - 1);
				var ClassDataIndex;
				//標記是哪個的,比如li的下標0,wang的下標1
				if (jQuery.inArray(aClassItem, ClassData) == -1) {
					ClassDataIndex = ClassData.push(aClassItem);
					ClassDataIndex = ClassDataIndex - 1;
					data[ClassDataIndex] = [];
				} else {
					ClassDataIndex = jQuery.inArray(aClassItem, ClassData);
				}
				if (Text.yAxisOpration != undefined) {
					var RealClassDataIndex;
					//---------------------按點分開始-----------------------
					var aRealClassItem = "";
					jQuery.each(RealClass, function(i, v) {
						aRealClassItem = aRealClassItem + itemValue[v] + ",";
					});
					aRealClassItem = aRealClassItem.substr(0, aRealClassItem.length - 1);
					if (jQuery.inArray(aRealClassItem, RealClassData) == -1) {
						RealClassDataIndex = RealClassData.push(aRealClassItem);
						RealClassDataIndex = RealClassDataIndex - 1;
						var ClassAndRealClassRelationIndex = data[ClassDataIndex].push([itemValue[Text.xAxisIndex], itemValue[Text.yAxisIndex]]);
						ClassAndRealClassRelationIndex = ClassAndRealClassRelationIndex - 1;
						ClassAndRealClassRelation.push([aRealClassItem, ClassAndRealClassRelationIndex, 1, ClassDataIndex]);
					} else {
						var tempIndex = jQuery.inArray(aRealClassItem, RealClassData);
						ClassAndRealClassRelation[tempIndex][2] = ClassAndRealClassRelation[tempIndex][2] + 1;
						var targetNode = data[ClassDataIndex][ClassAndRealClassRelation[tempIndex][1]];
						if (Text.yAxisOpration === "max") {
							if (targetNode[1] < itemValue[Text.yAxisIndex]) {
								targetNode[1] = itemValue[Text.yAxisIndex];
							}
						} else if (Text.yAxisOpration === "min") {
							if (targetNode[1] > itemValue[Text.yAxisIndex]) {
								targetNode[1] = itemValue[Text.yAxisIndex];
							}
						} else if ((Text.yAxisOpration === "sum") || (Text.yAxisOpration === "avg")) {
							targetNode[1] = targetNode[1] + itemValue[Text.yAxisIndex];
						} else {
							alert("Error!!!");
						}
					}
				} else {
					data[ClassDataIndex].push([itemValue[Text.xAxisIndex], itemValue[Text.yAxisIndex]]);
				}
			});
			if ((Text.yAxisOpration != undefined) && (Text.yAxisOpration === "avg")) {
				jQuery.each(ClassAndRealClassRelation, function(key, val) {
					var targetNode = data[val[3]][val[1]];
					targetNode[1] = targetNode[1] / val[2];
				});
			}
			if (Text.groupByIndex === undefined) {
				ClassData = ["default"];
			}
			var ob = {
				legend : ClassData,
				rows : data
			}
			return ob;
		}
	}
	if (DataText.type === "bar") {
		var Text = DataText.bar;
		if (Text === undefined) {
			alert("Create Bar Chart Error");
		} else {
			var Class = [];
			var RealClass = [];
			if (Text.groupByIndex === undefined) {
				Class = Text.xAxisIndex;
				RealClass = [];
				RealClass.push(Text.xAxisIndex);
			} else {
				Class = Text.groupByIndex;
				RealClass = Text.groupByIndex.concat();
				RealClass.push(Text.xAxisIndex);
			}
			var ClassData = [];
			var RealClassData = [];
			var ClassAndRealClassRelation = [];
			var data = [];

			jQuery.each(listData, function(index, itemValue) {
				var aClassItem = "";
				jQuery.each(Class, function(i, v) {
					aClassItem = aClassItem + itemValue[v] + ",";
				});
				aClassItem = aClassItem.substr(0, aClassItem.length - 1);
				var ClassDataIndex;
				//標記是哪個的,比如li的下標0,wang的下標1
				if (jQuery.inArray(aClassItem, ClassData) == -1) {
					ClassDataIndex = ClassData.push(aClassItem);
					ClassDataIndex = ClassDataIndex - 1;
					data[ClassDataIndex] = [];
				} else {
					ClassDataIndex = jQuery.inArray(aClassItem, ClassData);
				}
				if (Text.yAxisOpration != undefined) {
					var RealClassDataIndex;
					//---------------------按點分開始-----------------------
					var aRealClassItem = "";
					jQuery.each(RealClass, function(i, v) {
						aRealClassItem = aRealClassItem + itemValue[v] + ",";
					});
					aRealClassItem = aRealClassItem.substr(0, aRealClassItem.length - 1);
					if (jQuery.inArray(aRealClassItem, RealClassData) == -1) {
						RealClassDataIndex = RealClassData.push(aRealClassItem);
						RealClassDataIndex = RealClassDataIndex - 1;
						var ClassAndRealClassRelationIndex = data[ClassDataIndex].push([itemValue[Text.xAxisIndex], itemValue[Text.yAxisIndex]]);
						ClassAndRealClassRelationIndex = ClassAndRealClassRelationIndex - 1;
						ClassAndRealClassRelation.push([aRealClassItem, ClassAndRealClassRelationIndex, 1, ClassDataIndex]);
					} else {
						var tempIndex = jQuery.inArray(aRealClassItem, RealClassData);
						ClassAndRealClassRelation[tempIndex][2] = ClassAndRealClassRelation[tempIndex][2] + 1;
						var targetNode = data[ClassDataIndex][ClassAndRealClassRelation[tempIndex][1]];
						if (Text.yAxisOpration === "max") {
							if (targetNode[1] < itemValue[Text.yAxisIndex]) {
								targetNode[1] = itemValue[Text.yAxisIndex];
							}
						} else if (Text.yAxisOpration === "min") {
							if (targetNode[1] > itemValue[Text.yAxisIndex]) {
								targetNode[1] = itemValue[Text.yAxisIndex];
							}
						} else if ((Text.yAxisOpration === "sum") || (Text.yAxisOpration === "avg")) {
							targetNode[1] = targetNode[1] + itemValue[Text.yAxisIndex];
						} else {
							alert("Error!!!");
						}
					}
				} else {
					data[ClassDataIndex].push([itemValue[Text.xAxisIndex], itemValue[Text.yAxisIndex]]);
				}
			});
			if ((Text.yAxisOpration != undefined) && (Text.yAxisOpration === "avg")) {
				jQuery.each(ClassAndRealClassRelation, function(key, val) {
					var targetNode = data[val[3]][val[1]];
					targetNode[1] = targetNode[1] / val[2];
				});
			}
			if (Text.groupByIndex === undefined) {
				ClassData = ["default"];
			}
			var ob = {
				legend : ClassData,
				rows : data
			}
			return ob;
		}
	}
	if (DataText.type === "pie") {
		var Text = DataText.pie;
		if ((Text === undefined) || (Text.groupByIndex === undefined)) {
			alert("Create " + DataText.type + " Chart Error");
		} else {
			Class = Text.groupByIndex;
			var ClassData = [];

			var data = [];
			var count = [];
			
			jQuery.each(listData, function(index, itemValue) {
				//---------------------按線分開始-----------------------
				var aClassItem = "";
				jQuery.each(Class, function(i, v) {
					aClassItem = aClassItem + itemValue[v] + ",";
				});
				aClassItem = aClassItem.substr(0, aClassItem.length - 1);
				var ClassDataIndex;
				//標記是哪個的,比如li的下標0,wang的下標1
				if (jQuery.inArray(aClassItem, ClassData) == -1) {
					ClassDataIndex = ClassData.push(aClassItem);
					ClassDataIndex = ClassDataIndex - 1;
					data[ClassDataIndex] = [];
					count[ClassDataIndex] = 1;
				} else {
					ClassDataIndex = jQuery.inArray(aClassItem, ClassData);
					count[ClassDataIndex] = count[ClassDataIndex] + 1;
				}
				if (Text.yAxisOpration != undefined) {
					if (data[ClassDataIndex].length === 0) {
						data[ClassDataIndex] = [ClassData[ClassDataIndex], itemValue[Text.yAxisIndex]];
					} else {
						var targetNode = data[ClassDataIndex];
						//--------------------caozuo---------------------------
						if (Text.yAxisOpration === "max") {
							if (targetNode[1] < itemValue[Text.yAxisIndex]) {
								targetNode[1] = itemValue[Text.yAxisIndex];
							}
						} else if (Text.yAxisOpration === "min") {
							if (targetNode[1] > itemValue[Text.yAxisIndex]) {
								targetNode[1] = itemValue[Text.yAxisIndex];
							}
						} else if ((Text.yAxisOpration === "sum") || (Text.yAxisOpration === "avg")) {
							targetNode[1] = targetNode[1] + itemValue[Text.yAxisIndex];
						} else {
							alert("Error!!!");
						}
						//--------------------caozuo---------------------------
					}
				} else {
					data[ClassDataIndex].push([itemValue[Text.yAxisIndex]]);
				}
			});
			if ((Text.yAxisOpration != undefined) && (Text.yAxisOpration === "avg")) {
				jQuery.each(data, function(key, val) {
					var targetNode = data[key];
					targetNode[1] = targetNode[1] / count[key];
				});
			}
			var ob = {
				rows : data
			}
			return ob;
		}
	}
}

function drawChart(DataText, listData) {
	var data = getdata(DataText, listData);
	if (DataText.type === "line") {
		drowLineChart(DataText, listData);
	} else if (DataText.type === "bar") {
		drowBarChart(DataText, listData);
	} else if (DataText.type === "pie") {
		drowPieChart(DataText, listData);
	} else {
		alert("what?");
	}
}

function drowBarChart(DataText, listData) {
	console.log("bar");
	var data = getdata(DataText, listData);
	pot = jQuery.jqplot(DataText.contenter, data.rows, {
		title : DataText.title,
		seriesDefaults : {
			renderer : jQuery.jqplot.BarRenderer,
  			rendererOptions : {
//				barMargin : 20
				animation: {
                    show: true
                }
  			},
			pointLabels : {
				show : true
			}
		},
		axesDefaults : {
			tickRenderer : jQuery.jqplot.CanvasAxisTickRenderer,
			tickOptions : {
				angle : -45
			}
		},
		axes : {
			xaxis : {
				renderer : jQuery.jqplot.CategoryAxisRenderer
			},
			yaxis : {
				tickOptions : {
					angle : 0
				}
			}
		},
		legend : {// Date series title
			show : true,
			location : 'e',
			placement : 'outside',
			labels : data.legend
		}
	});
}

function drowPieChart(DataText, listData) {
	console.log("pie");
	var data = getdata(DataText, listData);
	pot = jQuery.jqplot(DataText.contenter, [data.rows], {
		title : DataText.title,
		seriesDefaults : {
			renderer : jQuery.jqplot.PieRenderer,
			rendererOptions : {
				animation: {
                    show: true
               },
				fill : false, // Turn off filling of slices
				showDataLabels : true,
				dataLabelNudge : +62,
				dataLabelThreshold : 2,
				sliceMargin : 4, // Add a margin to separate the slices.
				lineWidth : 3 // stroke the slices with a little thicker line.
			}
		},
		legend : {// Date series title
			show : true,
			location : 'se',
			placement : 'inside',
			fontSize : '12px',
			rowSpacing : '1px'
		},
		highlighter : {
			show : true,
			formatString : '%s',
			useAxesFormatters : false,
			tooltipContentEditor : function(str, seriesIndex, pointIndex, plot) {
				return '<span style="font-size:15px;">' + str + '</span>';
			}
		}
	});
	jQuery('#' + DataText.contenter).bind('jqplotDataHighlight', function(ev, seriesIndex, pointIndex, data) {
		jQuery('#' + DataText.contenter + ' .jqplot-title')[0].textContent = data;
	});

	jQuery('#' + DataText.contenter).bind('jqplotDataUnhighlight', function(ev, seriesIndex, pointIndex, data) {
		jQuery('#' + DataText.contenter +
		' .jqplot-title')[0].textContent = DataText.title;
	});
}

function drowLineChart(DataText, listData) {
	console.log("line");
	var data = getdata(DataText, listData);
	pot = jQuery.jqplot(DataText.contenter, data.rows, {
		title : DataText.title,
		legend : {// Date series title
			renderer : jQuery.jqplot.EnhancedLegendRenderer,
			showSwatches : true,
			showLabels : true,
			show : true,
			location : 'e',
			placement : 'outside',
			fontSize : '12px',
			rowSpacing : '1px',
			labels : data.legend//['aaa', 'bbb', 'ccc']
		},
		seriesDefaults : {
			rendererOptions : {
//				barMargin : 20
				animation: {
                    show: true
                }
  			},
			pointLabels : {
				show : true
			}
		},
		axesDefaults : {
			tickRenderer : jQuery.jqplot.CanvasAxisTickRenderer,
			//This render support more tick Options like 'angle'
			autoscale : true
		},
		axes : {
			xaxis : {
				renderer : $.jqplot.DateAxisRenderer
			},
			yaxis : {
				min : 0
			}
		},
		highlighter : {
			show : true,
			tooltipContentEditor : function(str, seriesIndex, pointIndex, plot) {
				return '<span style="font-size:15px;">' + data.legend[seriesIndex] + ',' + str + '</span>';
			}
		}
	});
}




然後就可以通過指定DataText中間的變數來定義要出的圖啦。

資源打包http://download.csdn.net/detail/tenixin/7142401