【自己的整理】【jQuery插件】 使用canvas创建折线图
来源:互联网 发布:淘宝皇冠和天猫哪个好? 编辑:程序博客网 时间:2024/05/19 08:37
使用canvas创建折线图
一个网友的很常规的需求,要根据数据在一个canvas画布元素上画一个折线图,最开始做了一个很土的版本,现在自己想想还是弄个插件吧于是就有了这篇文章。
创建jquery插件标准模板
既然是一个插件就要按照基本法来,所以先要创建一个标准的jquery插件模板:
<!DOCTYPE html><html> <head> <title>用canvas根据数据创建折线图</title> <script src="http://code.jquery.com/jquery-latest.js"></script> <script> (function($){ var methods = { init:function(options){ var chart = $.extend({ 'ChartTitle': '三人成绩折线图',//表头 'defaultLineColor':'rgba(0,0,0,0.4)',//折线图的坐标以及辅助线颜色 'defaultTextColor':'rgba(0,0,0,0.7)',//字体颜色 'canvasWidth':800,//画布宽度 'canvasHeight':600,//画布高度 'chartWidth':600,//图标宽度 'chartHeight':400,//图表高度 'x_metric':[1,2,3,4,5,6],//月份 下面X轴的计量数 'data':[{ "name":"小红", "details":[78,89,86,88,79,88],//数据 "color":"rgba(255,127,127,0.7)"//连线以及点的颜色 },{ "name":"小明", "details":[86,77,69,76,60,98], "color":"rgba(127,255,127,0.7)" },//数据二维数组 { "name":"小兰", "details":[80,77,66,62,99,65], "color":"rgba(127,127,255,0.7)" }], 'startLine':0,//左边开始的时候的数据 'endLine':120,//左边最高点的数据 'line_number':4,//中间画分成几格子 'x_name':'月份',//纵坐标的数量单位 'y_name':'分数'//横坐标的数量单位 },options); //下面用于检测是否在已经存在的画布上画图,还是重新生成一个。 var canvasElement,ctx; if($(this) && $(this).prop("tagName") == "CANVAS"){ var jQueryCanvasObject = $(this); console.log(jQueryCanvasObject); canvasElement = jQueryCanvasObject.get(0); console.log(canvasElement); ctx = canvasElement.getContext('2d'); canvasElement.width = chart.canvasWidth; canvasElement.height = chart.canvasHeight; }else if($(this) && typeof($(this).context) != 'undefined'){ var canvasindex = 0; for(var canvasindex;$('#drawChartCanvas'+canvasindex+'').length > 0;canvasindex ++ ){ } $(this).append("<canvas width="+chart.canvasWidth+" height="+chart.canvasHeight+" id='drawChartCanvas"+canvasindex+"'></canvas>"); canvasElement = $("#drawChartCanvas"+canvasindex).get(0); ctx = canvasElement.getContext('2d'); } else{ var canvasindex = 0; for(var canvasindex;$('#drawChartCanvasInBody'+canvasindex+'').length > 0;canvasindex ++ ){ console.log(canvasindex); } $('body').append("<canvas width="+chart.canvasWidth+" height="+chart.canvasHeight+" id='drawChartCanvasInBody"+canvasindex+"'></canvas>"); canvasElement = $("#drawChartCanvasInBody"+canvasindex).get(0); ctx = canvasElement.getContext('2d'); } }, destory:function(){},//destory方法 待补充 animate:function(){}//其他方法 }; $.fn.drawChart = function (method){ if(methods[method]){ return methods[method].apply(this,Array.prototype.slice.call(arguments,1)); }else if(typeof method === 'object' || !method){ return methods.init.apply(this,arguments); }else{ $.error('方法'+method+'在画折线图插件中不存在'); } } })(jQuery); </script> <script> $(document).ready(function(){$().drawChart()}); </script> </head> <body> </body></html>
到目前为止只是创建了一个默认的折线图数据对象chart,其中包含了诸多信息,比如表头,表的线条颜色等,可以根据自己的喜好改变其中某部分的设置。
我们要开始画一个折线图的时候,最开始画的应该是横竖两条x轴y轴辅助线,加上代表数量的辅助线,以及单位名称、度量等。我们在插件中创建一个新的方法把它叫做drawAxis(),这是一个画辅助线的方法,并不需要用到数据
function drawAxis(ctx,chart){ ctx.font = "30px microsoft yahei"; ctx.fillStyle = chart.defaultTextColor; ctx.fillText(chart.ChartTitle,chart.canvasWidth/2-100,40); ctx.lineWidth = 4; ctx.strokeStyle = chart.defaultLineColor; ctx.lineCap = "round"; var bottomLeft = {'x':(chart.canvasWidth - chart.chartWidth)/2, 'y':(chart.canvasHeight - chart.chartHeight)/2+chart.chartHeight };//左下角点坐标 var topRight = {'x':chart.canvasWidth - ((chart.canvasWidth - chart.chartWidth)/2), 'y':(chart.canvasHeight-chart.chartHeight)/2};//右上角点坐标 ctx.moveTo((chart.canvasWidth-chart.chartWidth)/2,(chart.canvasHeight-chart.chartHeight)/2+chart.chartHeight);//坐标轴原点 ctx.lineTo((chart.canvasWidth-chart.chartWidth)/2,(chart.canvasHeight-chart.chartHeight)/2);//坐标轴y轴上部点 var y_metric = chart.chartHeight/chart.line_number; var between = (chart.endLine - chart.startLine)/(chart.line_number); for(var i = 0; i < chart.line_number; i++){ ctx.moveTo(bottomLeft.x,bottomLeft.y-i*y_metric); ctx.lineTo(bottomLeft.x+chart.chartWidth,bottomLeft.y-i*y_metric); ctx.font = '20px microsoft yahei'; ctx.fillText(Math.floor(between * i + chart.startLine),bottomLeft.x-40,bottomLeft.y-i*y_metric); }; for(var i = 0;i < chart.x_metric.length; i++){ ctx.moveTo( i*(chart.chartWidth/chart.x_metric.length)+(chart.canvasWidth-chart.chartWidth)/2+(chart.chartWidth/chart.x_metric.length)/2, chart.chartHeight + (chart.canvasHeight-chart.chartHeight)/2 ); ctx.lineTo( i*(chart.chartWidth/chart.x_metric.length)+(chart.canvasWidth-chart.chartWidth)/2+(chart.chartWidth/chart.x_metric.length)/2, chart.chartHeight + (chart.canvasHeight-chart.chartHeight)/2 + 5 ); ctx.font = "20px microsoft yahei"; ctx.fillText(chart.x_metric[i], i*(chart.chartWidth/chart.x_metric.length)+(chart.canvasWidth-chart.chartWidth)/2+(chart.chartWidth/chart.x_metric.length)/2 - 6, chart.chartHeight + (chart.canvasHeight-chart.chartHeight)/2 + 25 ); } ctx.stroke(); ctx.font = "22px microsoft yahei"; ctx.fillText(chart.x_name,topRight.x + 3,bottomLeft.y); ctx.fillText(chart.y_name,bottomLeft.x - 3,topRight.y - 10); for(var i = 0;i < chart.data.length; i++){ ctx.strokeStyle = chart.data[i].color; ctx.beginPath(); ctx.moveTo(chart.canvasWidth-(chart.canvasWidth-chart.chartWidth)/2, (chart.canvasHeight-chart.chartHeight)/2 +i*25); ctx.lineTo(chart.canvasWidth-(chart.canvasWidth-chart.chartWidth)/2 + 18, (chart.canvasHeight-chart.chartHeight)/2 +i*25); ctx.stroke(); ctx.fillText(chart.data[i].name, chart.canvasWidth-(chart.canvasWidth-chart.chartWidth)/2 + 20, (chart.canvasHeight-chart.chartHeight)/2 +i*25 +6 ); } }
然后我们需要在插件的初始化方法中加入这个方法
init:function(options){ //...省略代码 drawAxis(ctx,chart);}
这样完成之后我们就可以看到还没有折线的一个图标,只有辅助线、表头、图例、以及单位等。
在我们在自己的本子上画折线图的时候,首先是要画各个点,然后再把这些点用线连起来,那么我们就可以按照这个思路来操作。
最开始我们先计算一下点的位置:
function initPointPosition(chart){ var points = []; for(var g = 0;g < chart.data.length;g++){ var pointsGroup = []; for(var i = 0;i < chart.data[g].details.length; i++ ){ //获取数据 var tempNumber = chart.data[g].details[i]; //算出百分比高度位置 var yPercentHeight = ((tempNumber - chart.startLine)/(chart.endLine-chart.startLine))*chart.chartHeight; //确定位置 var pointPosition = { 'detail':chart.data[g].details[i], 'x':chart.chartWidth/(chart.x_metric.length*2)+i*(chart.chartWidth/chart.x_metric.length)+(chart.canvasWidth-chart.chartWidth)/2, 'y':chart.chartHeight+(chart.canvasHeight-chart.chartHeight)/2-yPercentHeight , 'color':chart.data[g].color }; pointsGroup.push(pointPosition); } points.push(pointsGroup); } return points;}
这个方法可以根据数据来返回一个二维对象数组,数组内的一级元素表示了有多少组点,而二级对象中包含了点的位置,颜色,以及数据等信息。当然这还只是数据层面的,我们还需要把这些点画出来,所以需要加入一个可以把这个二维数组的点画出来的方法:
function drawPoints(ctx,points){ for(var i = 0; i < points.length; i ++){ for(var j = 0; j < points[i].length; j++){ ctx.fillStyle = points[i][j].color; ctx.beginPath(); ctx.arc(points[i][j].x,points[i][j].y,4,0,Math.PI*2,true); ctx.closePath(); ctx.fill(); } }};
我们需要在init(初始化)方法的最后调用这个方法:
init:function(options){ //省略的代码 drawAxis(ctx,chart); var points = initPointPosition(chart); drawPoints(ctx,points);}
此时我们再刷新一下浏览器,可以看到点已经呈现在折线图上面了:
这个时候就要把点都连起来,因为之前点的位置已经存在了,所以连点并不难,我们在插件中加入一个将二维数组的点连起来的方法:
function drawLine(ctx,points){ ctx.lineWidth = 3.5; for(var i = 0; i < points.length; i++){ ctx.beginPath(); for(var j = 0; j < points[i].length-1; j++){ ctx.strokeStyle = points[i][j].color; ctx.moveTo(points[i][j].x,points[i][j].y); ctx.lineTo(points[i][j+1].x,points[i][j+1].y); } ctx.stroke(); }};
然后同样在init方法的最后加入:
init:function(options){ drawAxis(ctx,chart); var points = initPointPosition(chart); drawPoints(ctx,points); drawLine(ctx,points);}
此时我们再刷新一下浏览器,可以看到点之间的连线也连好了。
这个时候可以看到连线已经完成,但是在折线图中看不到具体的数值,这个大小的比较还是有些看不出来,所以我们还要在点的旁边画上数据,同样新建一个方法用来绘制具体数值:
function drawData(ctx,points,chart){ ctx.fillStyle = chart.defaultTextColor; ctx.font = "18px microsoft yahei"; for(var i = 0;i < points.length; i++){ for(var j = 0;j< points[i].length;j++){ ctx.fillText(points[i][j].detail,points[i][j].x,points[i][j].y); } }}
同理要在init方法最后加入绘制具体数值的方法:
init:function(options){ //省略的内容 drawAxis(ctx,chart); var points = initPointPosition(chart); drawPoints(ctx,points); drawData(ctx,points,chart);}
最后再次刷新一下浏览器,可以看到一个较为完整的折线图:
看起来有些紧凑,想要把它变得不那么紧凑的话,可以改变一些设置:
<script> $().drawChart({"startLine":50,"endLine":100});</script>
- 【自己的整理】【jQuery插件】 使用canvas创建折线图
- 使用 jQuery 创建自己的插件
- jQuery基于Canvas的微信运动折线图动态曲线图插件 - wcMotionChart
- 使用Canvas和Paint自己绘制一个折线图
- 使用jquery图表插件jqplot之折线图
- jQuery创建自己的插件(自定义插件)的方法
- jQuery的validate插件使用整理
- 使用 jQuery(中级),第 2 部分: 创建自己的插件
- 使用 jQuery(中级),第 2 部分: 创建自己的插件
- 使用 jQuery(中级),第 2 部分: 创建自己的插件
- 利用canvas实现折线图的绘制
- 用canvas绘制的折线图 +解析
- Canvas 实现表格内的折线图
- 教你如何创建自己的 jQuery 插件
- Jquery--如何创建自己的插件,详细注释版本
- canvas 折线图
- canvas实现折线图
- 创建自己的插件
- java几种线程调度
- 矩阵论与矩阵分析——学习资料(更新..........)
- Xamarin.Android 引导页 启动页
- Ceph 学习——CRUSH算法及源码分析(一)
- 229. Majority Element II
- 【自己的整理】【jQuery插件】 使用canvas创建折线图
- JS判断字符串是否是金钱
- Weblogic + apache 实现负载均衡
- 11月28日云栖精选夜读:阿里巴巴正式开源其自研容器技术Pouch
- EJTAG调试总计
- Android Studio项目上传到GitHub
- 开源系统ThinkSNS+ APP端V1.2.8更新播报
- 56. Merge Intervals
- jdbc.properties查询中文乱码,&不能出现在jdbc.properties文件中