疊加圖 echarts-canvas
偶遇一個比較奇怪的需求,是一個疊加圖(superpostion chart),設計圖如下
有5個不同的設備不同時間在線,總計體現出每個時間段的在線熱度,本來想用echarts但是沒找到特別合適的,所以自己做了一個,希望能給需要的人幫助。
最終效果如下
首先需要一個canvas
<canvas id="canvasoffline" class="imgdevice"></canvas>
然后是繪圖方法:
function superPosition (ele, opts) {
let opt = opts||{
data: dataOrg,
left: 100,
right: 50,
grid: 50,
barwidth: 16,
font:'12px monaco',
color: 'rgba(255,99,132,0.2)'
}
console.log(dataOrg)
const length = opt.data.time.length - 1;
const WID = ele.width;
const HEI = ele.height;
const numlength = opt.data.devicelength;
const ctx = ele.getContext('2d');
const grid = opt.grid;
const start = opt.left;
const end = opt.right;
const interval = (WID- start - end ) / length;
for(var num = 0 ; num < numlength; num ++){
ctx.save();
ctx.font = opt.font;
ctx.fillText("NO."+(num+1),60, opt.barwidth+num*grid - 10);
// for(let i = 0; i <= length; i ++){
// ctx.fillText(data.time[i] ,i * interval + start - 14 , 33+num*grid);
// }
ctx.fillRect(start, 0+num*grid, WID-start-end, 1);
ctx.fillRect(start, opt.barwidth+num*grid, WID-start-end, 1)
ctx.fillStyle = opt.color
let ms = 'no'+(num+1);
dataOrg[ms].forEach((e,i) => {
ctx.fillRect(start+(e - 1)*interval,0+num*grid,interval,opt.barwidth);
ctx.fillRect(start+(e - 1)*interval,0+numlength*grid,interval,opt.barwidth)
})
ctx.restore()
}
ctx.font = opt.font;
ctx.fillText("總計",60, opt.barwidth+grid*num - 10);
ctx.fillRect(start, 0+num*grid, WID-start-end, 1);
ctx.fillRect(start, opt.barwidth+num*grid, WID-start-end, 1)
for(let i = 0; i <= length; i ++){
ctx.fillText(opt.data.time[i] ,i * interval + start - 14 , opt.grid + num*grid);
}
}
上面是實現圖的代碼,使用方法如下
var dataOrg = {
time: ['7:00','8:00',"9:00","10:00","11:00","12:00","13:00"],//y軸
no1: [1,2,6], //各個設備的數據,1,2,6代表第一二六個時間段在線
no2: [1,5],
no3: [1,6],
no4: [1],
no5: [1,3,6],
devicelength: 5 //設備總數
}
const ele = document.querySelector('#canvasoffline'); //獲取元素
ele.height = 80 * (dataOrg.devicelength+1) + 20 ; //圖片高度
ele.width = ele.height * 4; //圖片寬度
const opts = {
data: dataOrg, //數據來源
left: 150, //圖左側空白
right: 150, //圖右側空白
grid: 80, //垂直間距
barwidth: 40, // 柱子寬度
font:'20px monaco', //字體
color: 'rgba(255,99,132,0.2)' //顏色,疊加狀態若要好看需要透明度低
}
superPosition(ele, opts) //執行
最后你還需要添加樣式讓這個元素不會很大
.imgdevice {
width: 100%;
height: 300px;
padding-top: 50px;
border-top: 1px solid rgba(244,243,243,1);
}
下面這是三個設備的時候
下面這個是一個設備的時候
我采用的方法是保持縱橫比,拉大圖片來解決,自適應性還比較差,希望大家有更好的建議或者改善方法可以告訴我。