用highchart的時候發現它是用svg來畫圖的,那麼用canvas來做怎麼樣的。
以前做AS圖表插件的時候,繪制圖畫主要用容器的Graphics對象來繪制,而canvas的context和Graphics一樣,都可以用來繪制圖形。
然後就試著用canvas做了這樣一個東西。

具體實現如下,個人表達能力有問題,各位看官還是看源碼吧,如下:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/Html; charset=utf-8" />
<title>LineChart</title>
</head>
<body>
<div id="lineChart" style="width: 900px;height: 600px;border: #c9302c"></div>
<script src="jquery-1.8.2.min.js"></script>
<script src="ChartTest1.JS"></script>
<script type="text/Javascript">
$("#lineChart").lineChart("init");
</script>
</body>
</Html>
ChartTest1.JS源碼如下:
/**
* Created by jackyWHJ on 14-2-26.
*/
(function($) {
var canvas,context;
var stepXArr=[],stepYArr=[],xStepWidth=0;
var xAxisHeight = 0 ,yAxisWidth = 0;
var heightVal = 0;//高度值對應數據比例
/**
* 畫X軸
* */
var drawXAxis = function (xAxisData) {
context.beginPath();
//畫X軸橫線
context.moveTo(yAxisWidth - 6, canvas.height - xAxisHeight);
context.lineTo(canvas.width-yAxisWidth,canvas.height - xAxisHeight);
//畫刻度、加標簽
var len = xAxisData.length;
xStepWidth = (canvas.width-2*yAxisWidth)/len;
for(var i = 0;i < len;i++){
//畫刻度,默認刻度高度為6個像素
context.moveTo(yAxisWidth + (i+1)*xStepWidth, canvas.height - xAxisHeight);
context.lineTo(yAxisWidth + (i+1)*xStepWidth,canvas.height - xAxisHeight + 6);
//畫標簽,默認字體為14個像素
context.font = "normal normal bold 14px 微軟雅黑";
//字體居中在刻度中間
context.fillText(xAxisData[i],
yAxisWidth + (i+0.5)*xStepWidth - xAxisData[i].length*14/2,
canvas.height - xAxisHeight + 24);
//緩存刻度位置,用於畫網格
stepXArr.push(yAxisWidth + (i+1)*xStepWidth);
}
context.stroke();
}
/**
* 畫Y軸
* */
var drawYAxis = function(yMax,step) {
context.beginPath();
//畫X軸橫線
context.moveTo(yAxisWidth, xAxisHeight);
context.lineTo(yAxisWidth,canvas.height - xAxisHeight + 6);
//畫刻度、加標簽
var tickWidth = (canvas.height - 2*xAxisHeight )/step;
heightVal = (canvas.height - 2*xAxisHeight )/yMax;
for(var i = 0;i <= step;i++){
//畫刻度,默認刻度高度為6個像素
context.moveTo(yAxisWidth, canvas.height - xAxisHeight - tickWidth * i);
context.lineTo(yAxisWidth - 6,canvas.height - xAxisHeight - tickWidth * i);
//畫標簽,默認字體為14個像素
context.font = "normal normal 14px 微軟雅黑";
//字體居中在刻度中間
context.fillText(yMax/step * i,
yAxisWidth - 50,
canvas.height - xAxisHeight - tickWidth * i + 7);
//緩存刻度位置,用於畫網格
stepYArr.push(canvas.height - xAxisHeight - tickWidth * i);
}
context.stroke();
}
/**
* 畫網格
* */
var drawGrid = function() {
context.save();
context.strokeStyle = "#6e6e6e";
context.fillStyle = "#ffffff";
context.lineWidth = 0.5;
//畫橫線
var j = 0,stepX = (canvas.width - 2*yAxisWidth)/10,stepY = (canvas.height - 2*xAxisHeight)/10;
//10個像素位為單位,6個像素畫線,4個像素空出來,成為虛線
for (var i = 0,len = stepYArr.length; i < len; i ++) {
context.beginPath();
for(j = 0;j < stepX;j++){
context.moveTo(yAxisWidth + j*10, stepYArr[i]);
context.lineTo(yAxisWidth + j*10 + 6, stepYArr[i]);
}
context.stroke();
}
//畫豎線
for (var i = 0,len = stepXArr.length; i < len; i ++) {
context.beginPath();
for(j = 0;j < stepY;j++){
context.moveTo(stepXArr[i],xAxisHeight + j*10 );
context.lineTo(stepXArr[i],xAxisHeight + j*10+6);
}
context.stroke();
}
context.restore();
}
/**
* 畫線條
* */
var drawLine = function(lineData){
//循環數據源畫線條
context.beginPath();
context.fillStyle = "#000000";
context.lineWidth = 2;
context.moveTo(stepXArr[0] - xStepWidth/2 ,canvas.height - xAxisHeight - lineData[0]*heightVal);
for (var i = 1,len = lineData.length; i < len; i ++) {
context.lineTo(stepXArr[i] - xStepWidth/2 ,canvas.height - xAxisHeight - lineData[i]*heightVal);
}
context.stroke();
//畫圓點
for (var i = 0,len = lineData.length; i < len; i ++) {
context.beginPath();
context.fillStyle = "rgba(" + (Math.random()*255).toFixed(0) + ", " +
(Math.random()*255).toFixed(0) + ", " +
(Math.random()*255).toFixed(0) + ", 1.0)";
context.arc(stepXArr[i] - xStepWidth/2 ,canvas.height - xAxisHeight - lineData[i]*heightVal,
7, 0, Math.PI*2, true);
context.fill();
}
}
/**
* 畫柱子
* */
var drawBar = function(barData,colorArr){
var barWidth = xStepWidth/2;//定義柱子寬度
//循環數據源畫矩形
for (var i = 0,len = barData.length; i < len; i ++) {
context.beginPath();
context.fillStyle = colorArr[i];
context.fillRect(stepXArr[i] - xStepWidth/2 - barWidth/2,canvas.height - xAxisHeight - barData[i]*heightVal,
barWidth,barData[i]*heightVal);
context.fill();
}
}
var methods = {
init: function(options) {
// 在每個元素上執行方法
return this.each(function() {
var $this = $(this);
// 嘗試去獲取settings,如果不存在,則返回“undefined”
var settings = $this.data("lineChart");
// 如果獲取settings失敗,則根據options和default創建它
if (typeof settings === "undefined") {
var defaults = {
width:850,
height:450,
xAxis:["蘋果","香蕉","梨","番茄","龍眼"],
lineData:[350,200,300,245,150],
barData:[350,134,120,51,90],
colorArr:["#ae303e","#913730","#D49797","0x538FD3","#A34e5d"],
onSomeEvent: function() {
}
};
settings = $.extend({}, defaults, options);
// 保存我們新創建的settings
$this.data("lineChart", settings);
} else {
//如果我們獲取了settings,則將它和options進行合並(這不是必須的,你可以選擇不這樣做)
settings = $.extend({}, settings, options);
// 如果你想每次都保存options,可以添加下面代碼:
// $this.data("lineChart", settings);
}
canvas = document.createElement("canvas");
canvas.width = settings.width;
canvas.height = settings.height;
canvas.style.CSSText = "margin:0 auto;";
$this.append(canvas);
context = canvas.getContext("2d");
xAxisHeight = settings.height/8 ,yAxisWidth = settings.width/8;
drawXAxis(settings.xAxis);
drawYAxis(400,10);
drawGrid();
drawBar(settings.barData,settings.colorArr);
drawLine(settings.lineData);
});
},
destroy: function(options) {
// 在每個元素中執行代碼
return $(this).each(function() {
var $this = $(this);
// 執行代碼
// 刪除元素對應的數據
$this.removeData("lineChart");
});
},
val: function(options) {
// 這裡的代碼通過.eq(0)來獲取選擇器中的第一個元素的,我們或獲取它的HTML內容作為我們的返回值
var someValue = this.eq(0).Html();
// 返回值
return someValue;
}
};
$.fn.lineChart = function() {
var method = arguments[0];
if (methods[method]) {
method = methods[method];
arguments = Array.prototype.slice.call(arguments, 1);
} else if (typeof method === "object" !method) {
method = methods.init;
} else {
$.error("Method" + method + "does not exist on jQuery.pluginName");
return this;
}
return method.apply(this, arguments);
};
})(jQuery);