我们前面所涉及的离线数据库、离线文件的操作,会话机制的控制,以及客户端跨域数据同步、与服务端的交互,都可以很好的让用户在没有网络或者与服务端断开链接的情况下进行正常的操作。但我们的这个离线系统的客户中包含了很多的特定群体,如财务,会计、数据抽取人员,于是需要对数据报表和数据图表一个很强有力支持,让他们更加直观地表达。
目前来说,图表的开发组件还是很多的。
有基于silverLight的 Visifire,这是我的项目在使用MVC 3.0 开发之前最喜欢用的图表组件,喜欢的原因主要有三点(Visifire):
Open Source :相信这是很多程序员朋友最喜欢看到的。
Single API to both Silverlight & WPF:相信这也是许多客户端应用开发程序员最喜欢看到的。
Quick Start:启动速度很快,绝不输给纯脚本的一些轻量级图表插件,而且基于SilverLight的开发,给人视觉上绚丽的冲击感。
之前也在MVC 3.0下使用过Hight Charts,不得不承认这东西很好用,案例丰富,文档齐全,学习和使用都能很快上手,因为是基于纯脚本的,在项目移植上基本不存在什么问题,不像基于SilverLight的组件,你得保证服务机上面必须安装SilverLight。
在基于HTML5 应用的开发中,因为有了 HTML5 Cavans API,提供了通过 JavaScript 绘制图形的方法,使得数据图表开发更加的便捷,于是涌现出了很多基于HTML5 Cavans的脚本库。可以参考这篇文章的介绍:推荐18个基于 HTML5 Canvas 开发的图表库
其中我最喜欢的就是ZingChart,因为他是首个可以以Flash和HTML5 Canvas两种方案呈现图表的图表库,Flash版本,基本在所有的浏览器都是支持的。
我们关注一下这个ZingChart的HTML5版本,因为公司的其他同事也要用,所以稍微小做了下二级封装,这边的封装主要是提取了方法,分离了对数据的绑定,用传参的方式来调用,这样做的原因是我们页面上的数据主要是用二维数组来保存数据,然后用表格来呈现,这个二维数组传值进来正好对应了横轴,纵轴的数据。js库代码如下:
//Ben HTML5 1.0 //Create By Ben 2012.5.25 //基于zingchart图表插件的二级封装 function BenCharts() { /*饼图*/ /*title:标题*/ /*fields:域*/ /*values:值*/ this.makePieChart = function(title, fields, values) { var content = new Array(); for (var i = 0; i < fields.length; i++) { content[i] = '{"values": [' + values[i] + '],"text": "' + fields[i] + '"}'; } var jsonConfigPie = '{' + '"graphset": [' + '{' + '"type": "pie",' + '"legend": {' + '"visible": true' + '},' + '"title":{' + '"text":"' + title + '",' + '"font-family":"helvetica",' + '"font-size":"12px",' + '"background-color":"none",' + '"font-weight":"bold",' + '"font-color":"#000",' + '"text-align":"center"' + '},' + '"plot": {' + '"tooltip-text": "%t<br/>值: %v<br/>百分比: %npv",' + '"animate":true,' + '"speed":1,' + '"effect":5,' + '"value-box": {' + '"visible": true' + '}' + '},' + '"series": [' + content.join(',') + ']' + '}]' + '}'; return jsonConfigPie; } /*线形图*/ /*title:标题*/ /*xTitle:横轴标题*/ /*yTitle:纵轴标题*/ /*xValue:横轴节点*/ /*fields:纵轴节点*/ /*values:横纵轴二维数组*/ this.makeLineChart = function(title, xTitle, yTitle, fields, values, xValue) { var content = new Array(); for (var i = 0; i < fields.length; i++) { content[i] = '{"values": [' + values[i].join(',') + '],"text": "' + fields[i] + '","line-width": 2,"animate": 1,"effect": 1,"marker": {"size": "3px"}}'; } if (!xValue) { xValue = '"1:' + values[0].length + ':1"'; //横轴:(初始,总量,增量值) } else xValue = '["' + xValue.join('","') + '"]'; //横轴:由开发人员自定义 var jsonConfigLine = '{' + '"graphset": [' + '{' + '"type": "line",' + '"title":{' + '"text":"' + title + '",' + '"font-family":"helvetica",' + '"font-size":"12px",' + '"background-color":"none",' + '"font-weight":"bold",' + '"font-color":"#000",' + '"text-align":"center"' + '},' + '"legend": {' + '"visible": true' + '},' + '"scale-x": {' + '"values": ' + xValue + ',' + '"label": {' + '"text": "' + xTitle + '"' + '},' + '"zooming": 1' + '},' + '"scale-y": {' + '"max-items": 8,' + '"label": {' + '"text": "' + yTitle + '"' + '}' + '},' + '"plot": {' + '"tooltip-text": "%t, 值 %v"' + '},' + '"series": [' + content.join(',') + ']' + '}]' + '}'; return jsonConfigLine; } /*柱状图图*/ /*title:标题*/ /*xTitle:横轴标题*/ /*yTitle:纵轴标题*/ /*xValue:横轴节点*/ /*fields:纵轴节点*/ /*values:横纵轴二维数组*/ this.makeBarChart = function(title, xTitle, yTitle, fields, values, xValue) { var content = new Array(); for (var i = 0; i < fields.length; i++) { content[i] = '{"values": [' + values[i].join(',') + '],"text": "' + fields[i] + '","animate": 1,"effect": 5}'; } if (!xValue) { xValue = '"1:' + values[0].length + ':1"'; //横轴:(初始,总量,增量值) } else xValue = '["' + xValue.join('","') + '"]'; //横轴:由开发人员自定义 var jsonConfigBar = '{' + '"graphset": [' + '{' + '"type": "bar",' + '"title":{' + '"text":"' + title + '",' + '"font-family":"helvetica",' + '"font-size":"12px",' + '"background-color":"none",' + '"font-weight":"bold",' + '"font-color":"#000",' + '"text-align":"center"' + '},' + '"legend": {' + '"visible": true' + '},' + '"scale-x": {' + '"values": ' + xValue + ',' + '"label": {' + '"text": "' + xTitle + '"' + '},' + '"zooming": 1' + '},' + '"scale-y": {' + '"label": {' + '"text": "' + yTitle + '"' + '}' + '},' + '"plot": {' + '"tooltip-text": " %t, 值: %v"' + '},' + '"series": [' + content.join(',') + ']' + '}' + ']' + '}'; return jsonConfigBar; } /*线形扩展区域图*/ /*title:标题*/ /*xTitle:横轴标题*/ /*yTitle:纵轴标题*/ /*xValue:横轴节点*/ /*fields:纵轴节点*/ /*values:横纵轴二维数组*/ this.makeAreaChart = function(title, xTitle, yTitle, fields, values, xValue) { var content = new Array(); for (var i = 0; i < fields.length; i++) { content[i] = '{"values":[' + values[i].join(',') + '],"text":"' + fields[i] + '","line-width":"2px","animate":1,"effect":1,"marker":{"size":"3px"}}'; } if (!xValue) { xValue = '"1:' + values[0].length + ':1"'; //横轴:(初始,总量,增量值) } else xValue = '["' + xValue.join('","') + '"]'; //横轴:由开发人员自定义 var jsonConfigArea = '{' + '"graphset": [' + '{' + '"type":"area",' + '"legend": {' + '"visible": true' + '},' + '"title":{' + '"text":"' + title + '",' + '"font-family":"helvetica",' + '"font-size":"12px",' + '"background-color":"none",' + '"font-weight":"bold",' + '"font-color":"#000",' + '"text-align":"center"' + '},' + '"scale-x":{' + '"values": ' + xValue + ',' + '"label":{' + '"text":"' + xTitle + '"' + '},' + '"zooming":1' + '},' + '"scale-y":{' + '"label":{' + '"text":"' + yTitle + '"' + '},' + '"zooming":1' + '},' + '"plot":{' + '"tooltip-text":"%t, 值: %v"' + '},' + '"series":[' + content.join(',') + ']' + '}]' + '}'; return jsonConfigArea; } } var BC = new BenCharts();
页面调用示例如下:
/*使用饼图*/ var fields = new Array("1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"); var values = new Array("100", "120", "35", "88", "66", "56", "79", "115", "42", "100", "110", "80"); var datas = BC.makePieChart("月数据报表", fields, values); zingchart.render({ 'id': 'g1', 'width': 500, 'height': 300, 'data': datas });
/*使用线形图*/ var title = "月数据线形图"; var xTitle = "2012各月份数据报表"; var yTitle = "上报数据"; var fields = new Array('东区', '西区', '南区', '北区'); var xValue = new Array('1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'); var value1 = [12, 15, 55, 14, 22, 23, 64, 32, 27, 0, 0, 0]; var value2 = [23, 17, 35, 19, 28, 32, 12, 59, 75, 45, 28, 72]; var value3 = [35, 45, 25, 29, 33, 49, 42, 42, 12, 36, 45, 58]; var value4 = [17, 16, 55, 65, 22, 46, 64, 32, 47, 12, 38, 40]; var values = new Array(value1, value2, value3, value4); zingchart.render({ 'id': 'g2', 'width': 600, 'height': 250, 'data': BC.makeLineChart(title, xTitle, yTitle, fields, values, xValue) //'data': makeLineChart(title, xTitle, yTitle, fields, values) //不写入xValue,则会自动生成横轴值 });
/*使用柱状图*/ var title = "月数据柱状图"; var xTitle = "2012各月份"; var yTitle = "上报件"; var fields = new Array('东区', '西区', '南区', '北区'); var xValue = new Array('1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'); var value1 = [12, 15, 55, 14, 22, 23, 64, 32, 47, 2, 2, 2]; var value2 = [23, 17, 35, 19, 28, 32, 12, 59, 75, 45, 28, 72]; var value3 = [35, 45, 25, 29, 33, 49, 42, 42, 12, 36, 45, 58]; var value4 = [17, 16, 55, 65, 22, 46, 64, 32, 47, 12, 38, 40]; var values = new Array(value1, value2, value3, value4); zingchart.render({ 'id': 'g3', 'width': 860, 'height': 300, 'data': BC.makeBarChart(title, xTitle, yTitle, fields, values, xValue) // 'data': makeBarChart(title, xTitle, yTitle, fields, values) //不写入xValue,则会自动生成横轴值 });
其实后来发现挺不合理,因为这个图表的数据本身就是json格式构成的,所以应该直接把相应格式的json字符串传进来比较好,而我们为了在页面上显示数据表格,把之前的json数据转成二维数组,然后又转成json串,装箱拆箱的,无端耗费性能。
还有一个需要注意的,这个ZingChart是不能用于商业用途的,如果你要用于商业用途,那需要付一定的费用。这个挺坑的,我们公司是买了,如果是自己做研究,也可以去下试用版。这个想破解也容易,其实就是一堆脚本,里面有个license.js,接下来,你懂的,嘻嘻...
因为我用的时候是英文版本的,还不支持中文,所以我这边做了本地化,右键菜单现在显示的是中文。
源码下载:HTML5_Charts