最近在做银行的项目,项目比较老旧,是基于angular和jquery的,所以很多东西都不支持。而且还是在内网开发的,就很不方便。然后有个需求是需要给当日的数据用折线图展示出来
大概就是上面这样的效果。用echarts也可以实现,但是内网并没有echarts。所以就考虑使用canvas自己画一个。
下面是一个简单的demo
html部分:
<canvas id="myCanvas"></canvas>
js部分:
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
// 数据
const data = [1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1];
// 定义画布宽高
const canvasWidth = 800;
const canvasHeight = 400;
canvas.width = canvasWidth;
canvas.height = canvasHeight;
// 定义折线图边距和坐标轴颜色
const padding = 50;
const axisColor = "#333";
// 定义折线颜色和阴影颜色
const lineColor = "#f00";
const shadowColor = "rgba(0, 0, 0, 0.2)";
// 计算折线图区域宽高
const graphWidth = canvasWidth - padding * 2;
const graphHeight = canvasHeight - padding * 2;
// 计算每个数据点的横向间距和纵向间距
const xSpacing = graphWidth / (data.length - 1);
const ySpacing = graphHeight / (Math.max(...data) - Math.min(...data));
// 创建渐变阴影
const gradient = ctx.createLinearGradient(padding, padding, padding, canvasHeight - padding);
gradient.addColorStop(0, "rgba(0, 0, 0, 0)");
gradient.addColorStop(0.5, shadowColor);
gradient.addColorStop(1, "rgba(0, 0, 0, 0)");
// 画坐标轴
ctx.strokeStyle = axisColor;
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(padding, padding);
ctx.lineTo(padding, canvasHeight - padding);
ctx.lineTo(canvasWidth - padding, canvasHeight - padding);
ctx.stroke();
// 画数据点
ctx.lineWidth = 4;
ctx.beginPath();
ctx.moveTo(padding, canvasHeight - padding - data[0] * ySpacing);
for (let i = 1; i < data.length; i++) {
const x = i * xSpacing + padding;
const y = canvasHeight - padding - data[i] * ySpacing;
ctx.lineTo(x, y);
}
// 填充渐变阴影
ctx.lineTo(canvasWidth - padding, canvasHeight - padding);
ctx.lineTo(padding, canvasHeight - padding);
ctx.closePath();
ctx.fillStyle = gradient;
ctx.fill();
// 画折线
ctx.strokeStyle = lineColor;
ctx.stroke();
效果图大概入如上图所示;
当然,如果要实现我所想要的效果,就可以把画坐标的模块给去掉
注意:
因为canvas如果要填充颜色的话,是需要一个封闭空间的,所以,如果要实现需求里的效果,就需要先用白色线画一个封闭空间,然后再给封闭空间填充颜色。然后就需要再重新绘制一次折线,就可以达到需求里的效果了。
如果对你有用的话,那就点赞收藏一下吧~