偶遇一個比較奇怪的需求,是一個疊加圖(superpostion chart),設計圖以下canvas
有5個不一樣的設備不一樣時間在線,總計體現出每一個時間段的在線熱度,原本想用echarts可是沒找到特別合適的,因此本身作了一個,但願能給須要的人幫助。echarts
最終效果以下post
首先須要一個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); } }
上面是實現圖的代碼,使用方法以下3d
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) //執行
最後你還須要添加樣式讓這個元素不會很大rest
.imgdevice { width: 100%; height: 300px; padding-top: 50px; border-top: 1px solid rgba(244,243,243,1); }
下面這是三個設備的時候code
下面這個是一個設備的時候blog
我採用的方法是保持縱橫比,拉大圖片來解決,自適應性還比較差,但願你們有更好的建議或者改善方法能夠告訴我。圖片