项目里用到了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:
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方法的第三个参数。 |