色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

您的位置:首頁技術文章
文章詳情頁

JS使用canvas技術模仿echarts柱狀圖

瀏覽:121日期:2024-03-30 08:32:00

canvas 畫布是html5中新增的標簽,可以通過js操作 canvas 繪圖 API在網頁中繪制圖像。

百度開發了一個開源的可視化圖表庫ECharts,功能非常強大,可以實現折線圖、柱狀圖、散點圖、餅圖、K線圖、地圖等多種圖表。很多項目都有使用過ECharts開發過圖表功能。

本實例教程使用原生js教你開發一個仿ECharts的柱狀圖。學習本教程之前,讀者需要具備html和css技能,同時需要有簡單的JavaScript基礎。

按照ECharts的開發方法,圖表都是生成在一個HTML元素中。所以本實例中也先準備一個id名為canvasWrap的div元素,如下所示:

<div id='canvasWrap'></div>

然后在canvasWrap元素中創建canvas元素,再在canvas元素上繪制柱狀圖。開發之前,按照慣例,還是先分析柱狀圖的具體操作,再根據具體操作把實現功能的方法分成多個步驟,接下來一個步驟一個步驟去完成它。

1. 編寫柱狀圖數據2. 獲取canvasWrap元素及寬高3. 創建繪圖環境3.1 創建canvas畫布3.2 設置canvas畫布的寬度和高度3.3 將canvas畫布放入到canvasWrap元素中3.4 創建繪圖上下文環境4. 設定坐標區域5. 繪制x軸5.1 繪制軸線5.2 繪制刻度線5.3 繪制刻度名稱6. 繪制y軸6.1 繪制軸線6.2 繪制刻度線6.3 繪制刻度值6.4 繪制x軸網格線7. 繪制柱圖7.1 計算柱圖寬度7.2 計算柱圖高度7.3 計算柱圖X起點7.4 計算柱圖Y起點7.5 繪制柱圖

具體代碼如下:

//1 編寫柱狀圖數據option = { //x軸數據 xAxis: { data: [’Mon’, ’Tue’, ’Wed’, ’Thu’, ’Fri’, ’Sat’, ’Sun’] }, //柱圖數據 series: [{ //多寫幾組數據,用于查看不同數據時的圖表效果 // data: [0.01, 0.2, 0.05, 0.07, 0.04, 0.13, 0.9], // data: [1, 1, 5, 7, 4, 1, 9], // data: [1213, 30, 150, 80, 70, 910, 630], data: [120, 199, 150, 180, 70, 110, 130], //圖形樣式:柱圖 type: ’bar’ }]};//創建圖表函數,wrap:圖表父元素id;data:圖表數據function fnCharts(wrap,data){ //2.獲取canvasWrap元素 var eWrap = document.getElementById(wrap); //2.獲取canvasWrap元素寬度和高度,用于設置canvas畫布大小 var nWrapW = eWrap.offsetWidth; var nWrapH = eWrap.offsetHeight; //3.1 創建canvas畫布 var eCanvas = document.createElement(’canvas’); //3.2 設置canvas畫布的寬度和高度 eCanvas.width = nWrapW; eCanvas.height = nWrapH; //3.3 將canvas畫布放入到canvasWrap元素中 eWrap.appendChild(eCanvas); //3.4 創建繪圖上下文環境(才能夠在Canvas畫布上繪制) var oCtx = eCanvas.getContext(’2d’); //4.設定坐標區域左上角和右下角 //起點設置為50.5,而不是整數,是為了讓線條變清晰 var nZoneStartX = 50.5; var nZoneStartY = 50.5; var nZoneEndX = nWrapW - nZoneStartX; var nZoneEndY = nWrapH - nZoneStartY; //5.1 使用線條函數繪制x軸軸線 fnCreatLine(nZoneStartX,nZoneEndY,nZoneEndX,nZoneEndY); //計算x軸長度 var nLonX = nZoneEndX - nZoneStartX; //獲取x軸數據數組長度 var nDataLon = option.xAxis.data.length; //根據x軸數據數組長度循環,在循環中繪制刻度線和刻度數值名稱 for(let i=0;i<nDataLon;i++){ //計算出x軸刻度線起點在x軸上的值 let nScaleX = nZoneStartX+Math.floor(nLonX*(i/nDataLon)); //刻度線起點都在x軸上 let nScaleY = nZoneEndY; //5.2 繪制刻度線,長度為10 fnCreatLine(nScaleX,nScaleY,nScaleX,nScaleY+10); //從數據中獲取刻度名稱字符串 let sName = option.xAxis.data[i]; //計算出刻度名稱起點 let nNameX = nZoneStartX+Math.floor(nLonX*(i/nDataLon))+Math.floor(nLonX*(1/nDataLon))/2; let nNameY = nZoneEndY+15; //5.3 繪制刻度名稱 fnCreatText(sName,nNameX,nNameY,’#aaa’,’center’); } //6.1 使用線條函數繪制y軸軸線 fnCreatLine(nZoneStartX,nZoneEndY,nZoneStartX,nZoneStartY); //繪制y軸刻度線前,需要有刻度最大值、最小值、刻度線段數和刻度線之間的間隔這些數據。 //刻度最大值先從數組中取最大值,等下再計算應該顯示的最大值 var nMaxScal = Math.max.apply(null,option.series[0].data); //刻度最小值在本實例中取0 var nMinScal = 0; //刻度線段數在本實例中設置為4 var nSplit = 4; //計算刻度間隔值 var nStep = (nMaxScal-nMinScal)/nSplit; //這時候會發現刻度間隔值好像有點奇怪,因為一般圖表的刻度間隔值都是5的倍數, //比如:[0,0.5,1.0,1.5,2]或[0,50,100,150,200]。 //所以還需要進一步計算,看nStep是否是5的倍數,如果不是,則遞增nIncrease,使其達到最接近的5的倍數。 //計算第一步,根據nStep算出倍數值應該是0.5或5或50或... //在本實例中通過把nStep數值先轉換為字符串再進行處理(也可以使用對數和指數去計算)。 var sTemp = ’’ + nStep; //把nStep轉換為字符串 //聲明一個需要遞增的數,默認為1 var nIncrease = 1; //聲明一個變量用于解決小數相乘產生的精度bug var nTempMultiple = 1; //nIncrease取10的n次冪,通過以下判斷計算 if(sTemp.indexOf(’.’)==-1){ //如果nStep不包含小數點,nIncrease取10的sTemp.length-2次冪。 //比如nStep為19的話,nIncrease = 10的0次冪,遞增數為1 //nStep為9的話,nIncrease = 10的-1次冪,遞增數為0.1 //nStep為199的話,nIncrease = 10的1次冪,遞增數為10 nIncrease = Math.pow(10,sTemp.length-2); }else{ //如果nStep包含小數點,nIncrease取10的sTemp整數位-2次冪。 nIncrease = Math.pow(10,sTemp.indexOf(’.’)-2); //這個變量用于解決小數相乘可能產生的精度bug,比如nIncrease是小數的情況 nTempMultiple = Math.pow(10,sTemp.indexOf(’.’)); } //倍數取整,便于遞增,如165改成160,16.5改成16,1.65改成1.6,可通過下列公式實現 nStep = Math.ceil(nStep/nIncrease)*(nIncrease*nTempMultiple)/nTempMultiple; //使用循環遞增nIncrease修正刻度值 while(nStep%(nIncrease*5)!=0){ nStep += nIncrease*1; } //通過間隔值乘以線段數,修改刻度最大值 nMaxScal = nStep * nSplit; //計算y軸長度,這里多減3是因為y軸頂端要留點距離 var nLonY = nZoneEndY - nZoneStartY - 3; //繪制y軸刻度 for(let i=0;i<=nSplit;i++){ //刻度線起點都在y軸上 let nScaleX = nZoneStartX; //計算出y軸刻度線起點在y軸上的值 let nScaleY = nZoneEndY-Math.floor(nLonY*(i/nSplit)); //6.2 繪制刻度線 fnCreatLine(nScaleX,nScaleY,nScaleX-10,nScaleY); //6.3 繪制刻度值 fnCreatText(’’+i*nStep,nScaleX-20,nScaleY,’#333’); if(i!=0){ //6.4 非0位置,繪制x軸網格線 fnCreatLine(nScaleX,nScaleY,nScaleX+nLonX,nScaleY,’#ccc’); } } //7.1 計算柱圖寬度 let nBarWidth = Math.ceil(Math.floor(nLonX*(1/nDataLon))*.8); //遍歷x軸數據 for(let i=0;i<nDataLon;i++){ //7.2 計算柱圖高度 let nBarHeight = nLonY/nMaxScal*option.series[0].data[i]; //7.3 計算柱圖X起點 let nBarStartX = nZoneStartX+Math.floor(nLonX*(i/nDataLon)) +(Math.floor(nLonX*(1/nDataLon))-nBarWidth)/2; //7.4 計算柱圖Y起點 let nBarStartY = nZoneEndY-nBarHeight; //7.5 繪制柱圖 fnCreatRect(nBarStartX,nBarStartY,nBarWidth,nBarHeight); } //繪制線條函數 function fnCreatLine(sX,sY,eX,eY,color=’#000’){ //開始繪制路徑 oCtx.beginPath(); //設置路徑顏色 oCtx.strokeStyle = color; //設置路徑起點和終點,繪制線條 oCtx.moveTo(sX,sY); oCtx.lineTo(eX,eY); //給路徑添加顏色 oCtx.stroke(); } //繪制文字 function fnCreatText(text,x,y,color=’#000’,align=’end’,baseLine=’middle’){ //設置文字顏色 oCtx.fillStyle = color; //設置水平對齊方式 oCtx.textAlign = align; //設置垂直對齊方式 oCtx.textBaseline = baseLine; //繪制文字 oCtx.fillText(text,x,y); } //繪制矩形 function fnCreatRect(x,y,width,height,color=’#a00’){ //設置顏色 oCtx.fillStyle = color; oCtx.fillRect(x,y,width,height); }}//調用圖表函數,并傳入元素id和option數據fnCharts(’canvasWrap’,option);

這篇實例教程可能需要點耐心去讀源碼,如果碰到不明白的地方,可以在不明白的源碼位置輸出值,也許能豁然開朗。

以上就是JS使用canvas技術模仿echarts柱狀圖的詳細內容,更多關于JS使用canvas柱狀圖的資料請關注好吧啦網其它相關文章!

標簽: JavaScript
相關文章:
主站蜘蛛池模板: 久久久国产99久久国产久 | 国产色a在线观看 | 一级毛片aaaaaa视频免费看 | 国产麻豆一级在线观看 | 国产成人精品曰本亚洲77美色 | 成年免费大片黄在线观看一 | 亚洲男人的天堂久久无 | 99国产成人高清在线视频 | 欧美成人免费观看bbb | 欧美操人| 国产日韩精品一区在线观看播放 | 欧美日韩一区二区综合在线视频 | 高清在线一区二区三区亚洲综合 | 成年人在线免费观看网站 | 亚洲日本一区二区三区高清在线 | 国内主播福利视频在线观看 | aaa级毛片| 免费视频精品一区二区三区 | 永久黄网站色视频免费网站 | 波多野结衣中文在线播放 | 成人在线午夜 | 在线视频亚洲欧美 | 久久亚洲天堂 | 性夜黄a爽爽免费视频国产 性夜影院爽黄a爽免费看网站 | 成人网在线视频 | 欧美有码在线观看 | 伊大人香蕉久久网欧美 | 色拍拍噜噜噜aⅴ在线观看 色青青草原桃花久久综合 色婷婷91 | 91精品成人福利在线播放 | 最新中文字幕乱码在线 | 国产永久在线观看 | 黄在线看| 亚洲一区在线免费观看 | 黄色三级在线 | 国产成人无精品久久久久国语 | 亚洲成网站 | 亚洲免费区| 国产一区二区三区美女在线观看 | 日本一区二区三区精品视频 | 亚洲一区免费在线 | 日韩欧美精品综合一区二区三区 |