echarts 底层是基于canvas实现。
之前没怎么学习过canvas,工作项目中用到的也比较少
闲来无事,决定自己用canvas实现一个类似echarts中的柱状图
下面直接上代码
const option = {
color:'red',
width: '500px',
height: '300px',
xAxis: {
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
data: [120, 200, 150, 80, 70, 110, 130],
},
series: [{
showBackground: true,
backgroundStyle: {
color: '#cccccc'
}
}]
}
Histogram(option)
function Histogram(obj) {
// 创建canvas
var canvas = document.createElement('canvas')
const canvasId = 'canvas'+Math.round(Math.random()*100)
canvasWidth = obj.width
canvasHeight = obj.height
canvas.setAttribute('id', canvasId)
canvas.setAttribute('width', canvasWidth)
canvas.setAttribute('height', canvasHeight)
// canvas.style.borderBottom = '1px solid red'
// canvas.style.borderLeft = '1px solid red'
document.body.appendChild(canvas)
const xAxis_data = obj.xAxis.data
const yAxis_data = obj.yAxis.data
const backgroundStyle = obj.series[0].backgroundStyle.color
const color = obj.color
console.log(backgroundStyle)
var c = document.getElementById(canvasId)
var ctx = c.getContext("2d")
// 绘制y轴
const yAxis_max = Math.max(...yAxis_data)
// console.log(yAxis_max)
for(var i = 0; i < 5; i++){
ctx.font = '12px'
ctx.fillText(yAxis_max-(yAxis_max/4)*i, 0, ((yAxis_max/5)*i)*(parseInt(canvasHeight)/yAxis_max)+15)
}
// 绘制x轴文本
const xAxis_max = parseInt(canvasWidth)
var xAxis_LENGTH = xAxis_data.length
for(var i = 0; i < xAxis_data.length; i++){
ctx.font = '12px'
ctx.fillText(xAxis_data[i], (xAxis_max/xAxis_LENGTH)*i +30, parseInt(canvasHeight))
}
// 绘制x轴
ctx.moveTo(0, parseInt(canvasHeight)-15);
ctx.lineTo(parseInt(canvasWidth), parseInt(canvasHeight)-15);
ctx.stroke();
// 绘制柱状图
for(var i = 0; i < yAxis_data.length; i++){
const proportion = parseInt(canvasHeight)/yAxis_max
const height = proportion*yAxis_data[i]
const el_width = ((parseInt(canvasHeight)-50)/yAxis_data.length)
console.log(height, el_width)
if(i == 0){
ctx.fillStyle = backgroundStyle;
ctx.fillRect(el_width-10, 0, el_width, parseInt(canvasHeight)-height-15);
ctx.fillStyle = color;
ctx.fillRect(el_width-10, parseInt(canvasHeight)-height-15, el_width, height);
}else{
ctx.fillStyle = backgroundStyle;
ctx.fillRect(el_width+(el_width*i)-15+(el_width*i), 0, el_width, parseInt(canvasHeight)-height-15);
ctx.fillStyle = color;
ctx.fillRect(el_width+(el_width*i)-15+(el_width*i), parseInt(canvasHeight)-height-15, el_width, height);
}
}
}