前言:可視化圖表頁面需要提供保存圖片的功能,圖表使用了g2,但是g2的原生樣式並不能滿足需求的高度定制化,於是使用了g2的自定義樣式,用DOM重寫了圖表樣式,但是再使用g2的生成圖片方法,DOM部分無法生成圖片,這時就需要使用html2canvas將DOM生成圖片。
一、引入g2和html2canvas(本文以餅圖為例,g2的用法自行查看文檔)
import html2canvas from 'html2canvas'; import G2 from '@antv/g2';
先上圖:
g2繪制方法:
draw() { const data = [ { location: '三亞', value: 44.9 }, { location: '千島湖', value: 19.7 }, { location: '柬埔寨', value: 17.3 }, { location: '呼倫貝爾呼倫貝爾呼倫貝爾呼倫貝爾', value: 14.4 }, { location: '蘇梅島', value: 2.5 }, { location: '塞班島', value: 2.5 } ]; const chart = new G2.Chart({ container: 'c1', width:800, height: 200, padding: 'auto' }); chart.source(data); chart.legend({ useHtml: true, position:'right', containerTpl: '<div class="g2-legend">' + '<div class="g2-legend-list" style="list-style-type:none;margin:0;padding:0;"></div>' + '</div>', itemTpl: (value, color, checked, index) => { checked = checked ? 'checked' : 'unChecked'; return `<div class="g2-legend-list-item item-${index} ${checked}" data-value=${value} data-color=${color} style="cursor: pointer;font-size: 14px;width:100px;overflow:hidden;text-overflow: ellipsis;white-space: nowrap;"> <span width=150 style="border: none;padding:0;"><i class="g2-legend-marker" style="width:10px;height:10px;display:inline-block;margin-right:10px;background-color:${color};"></i></span> ${value} </div>`; }, }); chart.coord('theta', { radius: 0.8 }); chart.intervalStack().position('value').color('location', [ '#1890ff', '#37c661', '#fbce1e', '#2b3b79', '#8a4be2', '#1dc5c5' ]) .style({ stroke: 'white', lineWidth: 1 }) .label('value', val => { if (val < 3) { return null; } return { offset: -30, textStyle: { fill: 'white', fontSize: 14, shadowBlur: 2, shadowColor: 'rgba(0, 0, 0, .45)' }, formatter: text => { return text + '%'; } }; }); chart.render(); }
legend部分useHtml配置為true,頁面使用DOM的方式渲染右邊的圖例,因為是DOM,所以我們可以通過樣式設置文字超出顯示省略號,紅色的框是為了更清楚標出截圖范圍。
二、截圖方法
capture() { const rect = document.querySelector('#c1').getBoundingClientRect(); let scrollTop = document.documentElement.scrollTop || document.body.scrollTop// 獲取滾動軸滾動的長度 console.log(document.querySelector('#c1').getBoundingClientRect()); //eslint-disable-line html2canvas(document.querySelector('#c1'),{ width:rect.width, height:rect.height, scrollY: -scrollTop, // 頁面存在滾動時,需要設置此屬性,解決繪圖偏移問題 }).then(function(canvas) { console.log(canvas.toDataURL()); // eslint-disable-line document.body.appendChild(canvas); }); },
rect:可以獲取到Dom寬高位置等屬性;
#c1:為截圖的容器,圖表寫在容器里面;
html2canvas方法第一個參數傳容器Dom,第二個參數傳配置參數;
then回調可以獲取到截圖生成的canvas,然后再使用canvas生成圖片的方法,便得到了我們要的圖片。
(為了效果明顯,我將生成的canvas添加到頁面上)
其中scrollY參數很重要,不寫的效果如下:
當頁面有滾動行為時,會發現生成的canvas相對於原圖發生了偏移,餅圖底部被切了一塊,頂部多了一塊空白。
scrollY對應了頁面滾動高度,設置好之后的效果:
最后:html2canvas將dom的效果以canvs的形式畫出來,確實很強大,在我們愉快玩耍的時候,也需要注意它的一些不兼容問題,比如圖中的省略號的效果無法顯示的問題,還有部分css3的特殊屬性也需要注意。