項目裡用到了kendo UI DataViz的折線圖、餅狀圖等去顯示一些統計資訊,這些圖的顯示用到了SVG。
現在最新的Chrome、Safari、Moz都支援了SVG標籤,甚至是iPhone裡的Safari都支援了SVG。
但是Android要到3.0版本及以上才支援SVG,如果不是3.0及更高版本,使用者必須升級瀏覽器核心才能顯示。
這裡有個解決方案,可以將SVG轉換為canvas再顯示。用到了由google提供的canvg-1.2庫。
具體解決方案執行個體:
首先探測瀏覽器是否支援SVG,這裡借鑒了modernizr的判斷方法。如果支援,這個函數返回true,反之false:
function testSVG(){ var ns = {'svg': 'http://www.w3.org/2000/svg'}; return !!document.createElementNS && !!document.createElementNS(ns.svg, 'svg').createSVGRect;}
做出判斷之後,就能動態載入映像,如果支援SVG,直接用SVG標籤就OK,反之就需要將SVG的標籤轉換為canvas再顯示。
SVG轉化成canvas就要用到canvg,可以到http://code.google.com/p/canvg/去下載,也能串連到google的伺服器上:
<script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/rgbcolor.js"></script> <script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/canvg.js"></script>
使用方法有兩種(google網站上寫著的):
<script type="text/javascript">window.load = function() { //load '../path/to/your.svg' in the canvas with id = 'canvas' canvg('canvas', '../path/to/your.svg') //load a svg snippet in the canvas with id = 'drawingArea' canvg(document.getElementById('drawingArea'), '<svg>...</svg>') //ignore mouse events and animation canvg('canvas', 'file.svg', { ignoreMouse: true, ignoreAnimation: true }) }</script>
這裡我用到了第二種方法,也就是將svg標籤的html字串轉化成canvas。
首先要得到kendo UI Dataviz繪製的SVG圖形的整個SVG標籤的html。再將這個SVG標籤的html放入canvg函數即可。
具體參照下面的demo,先用kendoChart繪製SVG圖形,再判斷瀏覽器是否支援SVG,如果不支援,得到SVG標籤的整個html,再用canvg轉換。(chart的資料是用kendo UI chart的demo的資料)
html:
<div id="chart"></div>
js(依賴jquery):
//create chart $("#chart").kendoChart({ theme: $(document).data("kendoSkin") || "default", title: { text: "Break-up of Spain Electricity Production for 2008" }, legend: { position: "bottom", labels: { template: "#= text # (#= value #%)" } }, seriesDefaults: { labels: { visible: true, format: "{0}%" } }, series: [{ type: "pie", data: [ { category: "Hydro", value: 22 }, { category: "Solar", value: 2 }, { category: "Nuclear", value: 49 }, { category: "Wind", value: 27 } ] }], tooltip: { visible: true, format: "{0}%" } }); //判斷是否支援SVG /* if(!testSVG()){ var svgTagHtml = $("#chart").data("kendoChart").svg(); var canvasHtml = '<canvas id="kendoChart_canvas"></canvas>'; $("#chart").empty().html(canvasHtml); canvg(document.getElementById('kendoChart_canvas'), svgTagHtml); } */ //change svg Tag to canvas Tag //get svg Tag html //.data方法傳入的是chart類型.如果是kendoRadialGauge,那麼.data傳入的是'kendoRadialGauge'; var svgTagHtml = $("#chart").data("kendoChart").svg(); var canvasHtml = '<canvas id="kendoChart_canvas"></canvas>'; $("#chart").empty().html(canvasHtml); canvg(document.getElementById('kendoChart_canvas'), svgTagHtml); });
如果將最後四行代碼注釋,得到SVG圖形。如果不注釋最後四行代碼得到canvas。(這裡都要執行kendoChart去繪製SVG,是為了得到圖形的SVG標籤html,到現在我還沒找到更好的解決方案)。
注釋轉化代碼的(SVG標籤):
不注釋轉碼的(canvas標籤):
兩種標籤得到的效果相同:
缺陷:不管探測到瀏覽器是否支援SVG,都要執行kendoChart去繪製SVG,是為了得到圖形的SVG標籤html,到現在我還沒找到更好的解決方案。
使用canvas後iScroll一起使用還有點問題,要去研究下canvas標籤和canvg方法的第三個參數。