canvas绘制曲线图
/**
-
moveTo() 是Canvas 2D API 将一个新的子路径的起始点移动到(x,y)坐标的方法
-
CanvasRenderingContext2D.lineTo()是
-
Canvas 2D API 使用直线连接子路径的终点到(x,y)做标的方法(并不会真正地绘制)。
-
使用beginPath() 绘制路径的起始点, 使用moveTo()移动画笔,
-
使用stroke()方法真正的画线
-
定义和用法:
-
fillText()方法在画布上绘制填色的文本。文本的默认颜色是黑色。
-
提示:请使用 font 属性来定义字体和字号,并使用fillStyle属性以另一种颜色/渐变来渲染文本。
-
JavaScript 语法:
-
context.fillText(text,x,y,maxWidth);
-
参数值
-
参数 描述
-
text 规定在画布上输出的文本。
-
x 开始绘制文本的x坐标位置(相对于画布)。
-
y 开始绘制文本的y坐标位置(相对于画布)。
-
maxWidth 可选。允许的最大文本宽度,以像素计。
-
fillStyle属性来设置用于填充绘图的颜色、渐变或模式
-
strokeStyle 设置描边样式 接收所有颜色类型
-
values为一个数组,从中获取values数组中的最大值
-
var max = Math.max.apply(Math,values);
-
从中获取values数组中的最小值
-
var min = Math.min.apply(Math,values);
-
PI就是圆周率π,PI是弧度制的π,也就是180°
所以,Math.PI = 3.14 = 180° -
const定义的变量不可以修改,而且必须初始化。
-
var定义的变量可以修改,如果不初始化会输出undefined,不会报错。
-
let是块级作用域,函数内部使用let定义后,对函数外部无影响。
-
@param json
-
@returns
*/
function lenCanvasCT(json){var canvas_lens_ct = document.getElementById(‘canvas_lens_ct’);
// 获取上下文;'2d’建立一个CanvasRenderingContext2D对象代表一个二维渲染上下文。
var context = canvas_lens_ct.getContext(“2d”);//2、获取画布的宽度和高度
const WIDTH = canvas_lens_ct.width;
const HEIGHT = canvas_lens_ct.height;//3、定义坐标轴相对于画布的内边距
var padding = 20; //初始化内边距
var paddingLeft = 50; //至少大于绘制文字的宽度
var paddingBottom = 70; //至少大于绘制文字的高度
//4、定义绘制坐标轴的关键点的坐标值;以下这个方式是对象字面量表法,与JsonObject相类似;axis轴线的意思
var axisY = { //y轴的起点坐标值
x: paddingLeft,
y: padding
};
var origin = { //原点坐标值(x轴与y轴交叉点)
x: paddingLeft,
y: HEIGHT - paddingBottom
}
var axisX = { //x轴的起点坐标值
x: WIDTH - padding,
y: HEIGHT - paddingBottom
}//绘制坐标轴;axisY:y轴的起点坐标值;orgin:原点坐标值(x轴与y轴交叉点);axisX:x轴的起点坐标值
context.beginPath();
context.moveTo(axisY.x, axisY.y); //y轴的起点坐标值开始;Canvas 2D API 将一个新的子路径的起始点移动到(x,y)坐标的方法
context.lineTo(origin.x, origin.y); //到原点坐标值(x轴与y轴交叉点),竖线
context.lineTo(axisX.x, axisX.y); //到x轴的起点坐标值,横线
context.stroke(); //真正的绘制画线//绘制坐标轴的箭头;y轴箭头
context.beginPath();
context.moveTo(axisY.x - 5, axisY.y + 10);
context.lineTo(axisY.x, axisY.y); //y轴的起点坐标值
context.lineTo(axisY.x + 5, axisY.y + 10);
context.stroke();
//x轴箭头
context.beginPath();
context.moveTo(axisX.x - 10, axisX.y - 5);
context.lineTo(axisX.x, axisX.y); //x轴的起点坐标
context.lineTo(axisX.x - 10, axisX.y + 5);
context.stroke();//病例量表平均T分,顶部线
context.beginPath();
context.moveTo(WIDTH/3-70, axisY.y);
context.lineTo(WIDTH/3-50, axisY.y);
context.strokeStyle = ‘#55aa00’; //绿色
context.stroke();
//绘制实心圆点
context.fillStyle = ‘#55aa00’;
context.beginPath();
context.arc(WIDTH/3-60,axisY.y,4,0,2*Math.PI); //创建弧/曲线(用于创建圆形或部分圆);半径为4的实心圆
context.fill();//心理症状T分;顶部线
context.beginPath();
context.moveTo(WIDTH/2-50, axisY.y);
context.lineTo(WIDTH/2-30, axisY.y);
context.strokeStyle = ‘#aa0000’; //红色
context.stroke();
//绘制实心圆点
context.fillStyle = ‘#aa0000’;
context.beginPath();
context.arc(WIDTH/2-40,axisY.y,4,0,2*Math.PI); //创建弧/曲线(用于创建圆形或部分圆);半径为4的实心圆
context.fill();//装好装坏因子T分;顶部线
context.beginPath();
context.moveTo(WIDTH-WIDTH/3-30, axisY.y);
context.lineTo(WIDTH-WIDTH/3-10, axisY.y);
context.strokeStyle = ‘#0055aa’; //蓝色
context.stroke();
//绘制实心圆点
context.fillStyle = ‘#0055aa’;
context.beginPath();
context.arc(WIDTH-WIDTH/3-20,axisY.y,4,0,2*Math.PI); //创建弧/曲线(用于创建圆形或部分圆);半径为4的实心圆
context.fill();//绘制文字;#55aa00绿色;红色#aa0000;#0055aa蓝色;黑色#030303;
context.fillStyle = ‘#030303’;
context.strokeStyle = ‘#030303’;
context.font = ‘13px 宋体’;
//(参数:要写的字,x坐标,y坐标);context.fillText(‘要写的文字’, 100, 100);
context.fillText(‘T分’, axisY.x-5, axisY.y-10);
context.fillText(‘测查日期’, axisX.x-35, HEIGHT - paddingBottom + axisY.y);
//病例量表平均T分;绿色
context.fillStyle = ‘#55aa00’;
context.strokeStyle = ‘#55aa00’;
context.font = ‘13px 宋体’;
context.fillText(‘病例量表平均T分’, WIDTH/3-50, axisY.y);
//心理症状T分;红色
context.fillStyle = ‘#aa0000’;
context.strokeStyle = ‘#aa0000’;
context.font = ‘13px 宋体’;
context.fillText(‘心理症状T分’, WIDTH/2-30, axisY.y);
//装好装坏因子T分;蓝色
context.fillStyle = ‘#0055aa’;
context.strokeStyle = ‘#0055aa’;
context.font = ‘13px 宋体’;
context.fillText(‘装好装坏因子T分’, WIDTH-WIDTH/3-10, axisY.y);
//恢复原来颜色;黑色
context.fillStyle = ‘#030303’;
context.strokeStyle = ‘#030303’;//得到数组对象;resultIds即rids数组的长度是多少就加载多少个;即jasMd == json.length-2
var jasMd = json[json.length-1].jasMd;
var iave = []; //病例量表平均T分 集合数组
var mentT = []; //心理症状(总)T分 集合数组
var gdbd = []; //装好-装坏因子T分 集合数组
var xsurd = []; //测查日期 集合数组
//json得到的第1个json[0]对象[object Object]是常数,最后一个json[json.length-1]对象[object Object]对象是MD.DAT文件中所需要的内容数据
for (var i = 1; i < json.length-1; i++) {
//console.log(‘json’+i+’:’+json[i]); //得到对应对象
var japct = json[i].japct;
var pct1 = japct[0].pctrp; //报告1
var pct2 = japct[1].pctrp; //报告2
var pct4 = japct[3].pctrp; //报告4
mentT.push(pct4[0].jopct); //心理症状(总)T分
gdbd.push(pct2[91].jopct); //装好装坏因子T分
xsurd.push(pct1[15].jopct); //测查日期
var jaMd = jasMd[i-1].jaMd;
iave.push(jaMd[3].joMd); //病例量表平均T分
}
console.log(‘病例量表平均T分iave:’+iave+’–心理症状(总)T分mentT:’+mentT+’–装好-装坏因子T分gdbd:’+gdbd); //可得到具体数组数据//存储x轴的值
var pointsX = [];
//7、绘制坐标轴的刻度(x轴的测查日期和y轴的总分);x轴的测查日期
var surveyDay = {
x: paddingLeft,
y: HEIGHT - paddingBottom + 5
}//x轴测查日期
for (var i = 0; i < xsurd.length; i++) {
context.font = ‘16px’;
context.textBaseline = ‘top’;
if(xsurd.length < 9){
//测查日期数小于9时
context.fillText(xsurd[i] + ‘日’, surveyDay.x, surveyDay.y);
}else{
//测查日期数大于9时,字体竖直排列
context.fillTextVertical(xsurd[i] + ‘日’, surveyDay.x, surveyDay.y);
}
pointsX.push(surveyDay.x);
surveyDay.x += (axisX.x - origin.x) / xsurd.length;
}//var scoY = (origin.y - axisY.y) / (max / hg + 1); //hg10:y轴划分值;100/10+1;hgap10:最高值间隔
var scoY = (origin.y-axisY.y)/11; //即单元格高
var score = {
x: axisY.x - 5,
y: axisY.y + scoY,
fen: 100
}
context.textAlign = ‘right’;
//y轴间隔分数
for (var i = 0; i <= 10; i++) {
context.font = ‘16px 宋体’;
context.fillText(score.fen + ‘分’,score.x, score.y);
score.y += scoY;
score.fen -= 10;
}
//x轴刻度
for (var i = 1; i <= 20; i++) {
context.beginPath();
context.moveTo(axisY.x, axisY.y+(i+1)scoY/2);
context.lineTo(axisY.x-5, axisY.y+(i+1)scoY/2);
context.stroke(); //真正的绘制画线
}
//y轴刻度
for (var i = 0; i < xsurd.length; i++) {
console.log(‘surveyDay.x:’+surveyDay.x);
context.moveTo(pointsX[i], axisX.y);
context.lineTo(pointsX[i], axisX.y+5);
context.stroke(); //真正的绘制画线
}
/- var iave = []; //病例量表平均T分 集合数组
var mentT = []; //心理症状(总)T分 集合数组
var gdbd = []; //装好-装坏因子T分 集合数组
*/
//绘制折线;var iave = []; //病例量表平均T分 集合数组
context.beginPath();
for (let i = 0; i < iave.length; i++) {
//x轴的坐标
let pointX = pointsX[i];
//y轴的坐标
let pointY = origin.y - (origin.y - (axisY.y + scoY)) * iave[i] / 100;
context.fillStyle = ‘#55aa00’;
if(i === 0){
// context.textBaseline = ‘’;
context.textAlign = ‘right’
context.moveTo(pointX, pointY);
context.fillText(iave[i]+‘分’, pointX+35, pointY);
}else{
context.textBaseline = ‘bottom’;
context.textAlign = ‘center’;
context.lineTo(pointX, pointY);
context.setLineDash([10,10]); //设置虚线
context.fillText(iave[i]+‘分’, pointX, pointY);
}
context.font = ‘16px’;
}
context.strokeStyle = ‘#55aa00’; //#55aa00绿色
context.stroke();
//绘制小圆点
for (let i = 0; i < iave.length; i++) {
//x轴的坐标
let pointX = pointsX[i];
//y轴的坐标
let pointY = origin.y - (origin.y - (axisY.y +scoY)) * iave[i] / 100;
context.fillStyle = ‘#55aa00’; //#55aa00绿色;红色#aa0000
context.beginPath();
context.arc(pointX,pointY,4,0,2*Math.PI); //创建弧/曲线(用于创建圆形或部分圆);半径为4的实心圆
context.fill();
}//折线var mentT = []; //心理症状(总)T分 集合数组
context.beginPath();
for (let i = 0; i < mentT.length; i++) {
//x轴的坐标
let pointX = pointsX[i];
//y轴的坐标
let pointY = origin.y - (origin.y - (axisY.y + scoY)) * mentT[i] / 100;
context.fillStyle = ‘#aa0000’;
if(i === 0){
// context.textBaseline = ‘’;
context.textAlign = ‘right’
context.moveTo(pointX, pointY);
context.fillText(mentT[i]+‘分’, pointX+35, pointY);
}else{
context.textBaseline = ‘bottom’;
context.textAlign = ‘center’;
context.lineTo(pointX, pointY);
//context.setLineDash([10,10]); //设置虚线
context.fillText(mentT[i]+‘分’, pointX, pointY);
}
context.font = ‘16px’;
}
context.strokeStyle = ‘#aa0000’; //#55aa00绿色
context.stroke();//绘制小圆点
for (let i = 0; i < mentT.length; i++) {
//x轴的坐标
let pointX = pointsX[i];
//y轴的坐标
let pointY = origin.y - (origin.y - (axisY.y +scoY)) * mentT[i] / 100;
context.fillStyle = ‘#aa0000’; //#55aa00绿色;红色#aa0000
context.beginPath();
context.arc(pointX,pointY,4,0,2*Math.PI); //创建弧/曲线(用于创建圆形或部分圆);半径为4的实心圆
context.fill();
}//折线:var gdbd = []; //装好-装坏因子T分 集合数组
context.beginPath();
for (let i = 0; i < gdbd.length; i++) {
//x轴的坐标
let pointX = pointsX[i];
//y轴的坐标
let pointY = origin.y - (origin.y - (axisY.y + scoY)) * gdbd[i] / 100;
context.fillStyle = ‘#0055aa’;
if(i === 0){
// context.textBaseline = ‘’;
context.textAlign = ‘right’
context.moveTo(pointX, pointY);
context.fillText(gdbd[i]+‘分’, pointX+35, pointY);
}else{
context.textBaseline = ‘bottom’;
context.textAlign = ‘center’;
context.lineTo(pointX, pointY);
context.setLineDash([1,0]); //恢复实线
context.fillText(gdbd[i]+‘分’, pointX, pointY);
}
context.font = ‘16px’;
}
context.strokeStyle = ‘#0055aa’; //#0055aa蓝色;#55aa00绿色
context.stroke();//绘制小圆点
for (let i = 0; i < gdbd.length; i++) {
//x轴的坐标
let pointX = pointsX[i];
//y轴的坐标
let pointY = origin.y - (origin.y - (axisY.y +scoY)) * gdbd[i] / 100;
context.fillStyle = ‘#0055aa’; //#0055aa蓝色;#55aa00绿色;红色#aa0000
context.beginPath();
context.arc(pointX,pointY,4,0,2*Math.PI); //创建弧/曲线(用于创建圆形或部分圆);半径为4的实心圆
context.fill();
}//打印显示,canvas本身不显示,用img替换
canvas_lens_ct.style.display = ‘none’;
var img_len_ct = document.getElementById(‘img_len_ct’);
img_len_ct.src = canvas_lens_ct.toDataURL();
img_len_ct.style.display = ‘block’;
} - var iave = []; //病例量表平均T分 集合数组
/**
-
@author zhangxinxu(.com)
-
@licence MIT
-
@description http://www.zhangxinxu.com/wordpress/?p=7362
-
canvas日期竖直排列;js混合计算逐字排列
-
values为一个数组,从中获取values数组中的最大值
- var max = Math.max.apply(Math,values);
- 从中获取values数组中的最小值
- var min = Math.min.apply(Math,values);
*/
CanvasRenderingContext2D.prototype.fillTextVertical = function (text, x, y) {
var context = this;
var canvas = context.canvas;
var arrText = text.split(’’);
var arrWidth = arrText.map(function (letter){
return context.measureText(letter).width;
});var align = context.textAlign;
var baseline = context.textBaseline;if(align == ‘left’){
x = x + Math.max.apply(null, arrWidth) / 2;
}else if(align == ‘right’){
x = x - Math.max.apply(null, arrWidth) / 2;
}
if(baseline == ‘bottom’ || baseline == ‘alphabetic’ || baseline == ‘ideographic’){
y = y -arrWidth[0] / 2;
}else if (baseline == ‘top’ || baseline == ‘hanging’){
y = y + arrWidth[0] / 2;
}context.textAlign = ‘center’;
context.textBaseline = ‘middle’;//开始逐字绘制
arrText.forEach(function (letter, index){
//确定下一个字符的纵坐标位置
var letterWidth = arrWidth[index];// 旋转90度 context.translate(x, y); context.rotate(90 * Math.PI /180); context.translate(-x, -y); context.fillText(letter, x, y); // 旋转坐标系还原成初始态 context.setTransform(1, 0, 0, 1, 0, 0); // 确定下一个字符的纵坐标位置 var letterWidth = arrWidth[index]; y = y + letterWidth;
});
// 水平垂直对齐方式还原
context.textAlign = align;
context.textBaseline = baseline;
}
上一篇: 幽默逗乐俏皮话。
下一篇: PS制作文字与产品倒影