废话不多说,使用extjs+amcharts创建3d柱状图和数据表实例,如下:
1.首先定义一个数据模型
1 Ext.define("cacheHijack", { 2 extend : 'Ext.data.Model', 3 fields : [ { 4 name : 'id', 5 type : 'double' 6 }, { 7 name : 'site', 8 type : 'string' 9 }, { 10 name : 'domain', 11 type : 'string' 12 }, { 13 name : 'date', 14 type : 'string' 15 }, { 16 name : 'ip', 17 type : 'string' 18 }, { 19 name : 'areaIsp', 20 type : 'string' 21 }, { 22 name : 'hot_num', 23 type : 'double' 24 }, { 25 name : 'hijack_rate', 26 type : 'float' 27 } ] 28 });
2.创建一个store,extjs中的数据来源,这里作为ext和amcharts用到的共同的数据源。
1 var itemsPerPage = 20; //用于显示每一页的记录 2 var store = Ext.create("Ext.data.Store", { 3 model : 'cacheHijack', 4 remoteSort : false, 5 pageSize : itemsPerPage, 6 autoLoad: true, 7 proxy : { 8 type : 'ajax', 9 url : '/netmonitor/resource/cacheHijackedManager', //这个地方是远程请求的地址,返回的是json类型的数据 10 method : 'POST', 11 timeout : 600000, 12 reader : { 13 type : 'json', 14 root : 'items', 15 totalProperty : 'total' 16 } 17 } 18 });
3.ext远程数据加载后的操作,这边操作主要是将store里的数据进行转化,转化成json对象数组的形式用于amcharts的3d图的数据源。
解释:因为下面amcharts的3d柱状图需要store里的domain,hijack_rate以后额外定义的color数据,所以这个地方我便获取出来,
组合成 jsontext = [{domain:xxx1,hijack_rate:xxx1,color:#oD8ECF},{domain:xxx2,hijack_rate:xxx2,color:#oD8ECF}, {domain:xxx3,hijack_rate:xxx3,color:#oD8ECF},......],然后通过Ext.decode将其转化成标准的json对象
数组,通过create3dChart这个方法传递给amcharts创建的3d 柱状图。接着往下看。。。
1 store.on('load', function(records, options, success){ 2 var jsontext = "["; 3 for (var i = 0; i < store.getCount(); i++) { 4 var record = store.getAt(i); 5 var domain = record.get('domain'); 6 var hijack_rate = record.get('hijack_rate'); 7 jsontext += "{"; 8 jsontext += "domain:""+ domain + "",hijack_rate:"+ hijack_rate +",color:"#0D8ECF"},"; 9 } 10 jsontext = jsontext.substring(0, jsontext.length-1)+"]"; 11 var jsonO = Ext.decode(jsontext); 12 create3dChart(jsonO); 13 });
4.以上都属于先准备好数据,下面就是创建显示的面板了,首先,我先创建一个ext数据表格面板,
1 var gridPanel = Ext.create('Ext.grid.Panel', { 2 id : 'cacheHijack-dataPanel', 3 border : false, 4 flex: 7, 5 store : store, 6 // 表格中间展示数据 7 columns : [ { 8 text : '序号', 9 dataIndex : 'id', 10 width : 60 11 }, { 12 text : '网站', 13 dataIndex : 'site', 14 width : 130 15 }, { 16 text : '域名', 17 dataIndex : 'domain', 18 width : 180 19 }, { 20 text : '日期', 21 dataIndex : 'date', 22 width : 140 23 }, { 24 text : '服务器IP', 25 dataIndex : 'ip', 26 width : 190 27 }, { 28 text : '资源归属地', 29 dataIndex : 'areaIsp', 30 width : 200 31 }, { 32 text : '热度数量', 33 dataIndex : 'hot_num', 34 width : 150 35 }, { 36 text : '劫持率', 37 dataIndex : 'hijack_rate', 38 width : 150, 39 renderer:DomUrl 40 }], 41 listeners: { 42 itemclick: function (me, record, item, index, e, eOpts) { 43 //双击事件的操作 44 var domain = record.data['domain']; 45 var site = record.data['site']; 46 var date = record.data['date']; 47 createUniqWin(domain,site,date); 48 } 49 } 50 });
实现的效果是这个样子
然后是一个创建3d柱状图的方法
1 function create3dChart(options) { 2 var chart = new AmCharts.AmSerialChart(); 3 chart.autoMarginOffset = 0; 4 chart.dataProvider = options; 5 chart.categoryField = "domain"; 6 chart.startDuration = 1; 7 // chart.fontSize = 3; 8 chart.angle = 30; 9 chart.depth3D = 15; 10 11 // AXES 12 // category 13 var categoryAxis = chart.categoryAxis; 14 categoryAxis.labelRotation = 15; // this line makes category values to be rotated 15 categoryAxis.gridAlpha = 0; 16 categoryAxis.fillAlpha = 1; 17 categoryAxis.fillColor = "#FAFAFA"; 18 categoryAxis.gridPosition = "start"; 19 20 // value 21 var valueAxis = new AmCharts.ValueAxis(); 22 valueAxis.dashLength = 5; 23 valueAxis.title = "劫持率"; 24 valueAxis.minimum = 0; 25 valueAxis.maximum = 100; 26 valueAxis.axisAlpha = 0; 27 valueAxis.unit = "%"; 28 chart.addValueAxis(valueAxis); 29 30 // GRAPH 31 var graph = new AmCharts.AmGraph(); 32 graph.valueField = "hijack_rate"; 33 graph.colorField = "color"; 34 graph.balloonText = "[[category]]: [[value]]" + "%"; 35 graph.type = "column"; 36 graph.lineAlpha = 0; 37 graph.fillAlphas = 1; 38 graph.bulletSize = 10; 39 chart.addGraph(graph); 40 41 // WRITE 42 chart.write("chart3dDiv"); //这个地方的"chart3dDiv"是一个div的id,这个div在总面板上,下面即将看到 43 }
5.下面这个是组合两者的总面板,请看代码:
1 var resultsPanel = Ext.create('Ext.panel.Panel', { 2 title: '白名单劫持率', 3 frame: true, 4 getPanelWidth(), 5 height: getPanelHeight(), 6 layout: { 7 type: 'vbox', 8 align: 'stretch' 9 }, 10 items: [{ 11 xtype: 'container', 12 layout: { 13 type: 'hbox', 14 align: 'stretch' 15 }, 16 flex: 3, 17 html: '<div id="chart3dDiv" style="' + getPanelWidth() + ' px;height:235px;"></div>' //这个地方就是用于放置3d图的div 18 },{ 19 xtype: 'container', 20 layout: {type: 'hbox', align: 'stretch'}, 21 flex: 3, 22 items: [gridPanel,{ 23 xtype: 'form', 24 layout: { 25 type: 'vbox', 26 align:'stretch' 27 } 28 }] 29 }], 30 dockedItems : [ { 31 xtype : 'pagingtoolbar', 32 pageSize : itemsPerPage, 33 store : store, 34 dock : 'bottom', 35 displayInfo : true, 36 displayMsg : '显示{0}-{1}条,共计{2}条', 37 emptyMsg : '没有数据', 38 beforePageText : '当前页', 39 afterPageText : '共{0}页' 40 } ], 41 renderTo: 'main' + typeId 42 });
6.最终实现的效果是下满这个样子:
7.还有就是后台获取数据部分的代码
1 public void cacheHijackedManager(HttpServletRequest req, HttpServletResponse resp) throws Exception 2 { 3 resp.setContentType("text/json; charset=utf-8"); 4 String start = req.getParameter("start"); //起始条 5 String limit = req.getParameter("limit"); 6 7 int total = getTotalAmount(); 8 9 Connection conn = null; 10 PreparedStatement pst = null; 11 ResultSet rs = null; 12 String sql = "SELECT * FROM w_cache_hijack_day limit " + start + "," + limit; 13 try { 14 conn = new DBManager().DataManagerConn(Conf.customerID,Conf.NETRESOURCE); 15 pst = conn.prepareStatement(sql); 16 rs = pst.executeQuery(); 17 JSONArray ret = new JSONArray(); 18 while (rs.next()) { 19 JSONObject cacheHijack = new JSONObject(); 20 cacheHijack.put("id", rs.getDouble(1)); 21 cacheHijack.put("site", rs.getString(3)); 22 cacheHijack.put("domain", rs.getString(4)); 23 cacheHijack.put("date", rs.getDate(2).toString()); 24 cacheHijack.put("ip", rs.getString(5)); 25 cacheHijack.put("areaIsp", rs.getString(6)); 26 cacheHijack.put("hot_num", rs.getDouble(7)); 27 cacheHijack.put("hijack_rate", rs.getFloat(8) + "%"); 28 29 ret.add(cacheHijack); 30 } 31 resp.getWriter().print("{"success":"true","items":" + ret + ","total":"" + total + ""}"); 32 } catch (Exception e) { 33 e.printStackTrace(); 34 } finally{ 35 try { 36 if(rs!=null) rs.close(); 37 if(pst!=null) pst.close(); 38 if(conn!=null) conn.close(); 39 } catch (SQLException e) { 40 e.printStackTrace(); 41 } 42 } 43 }
1 /** 2 * 统计总数,用于分页 3 * @param domain 4 * @param date 5 * @return 6 */ 7 public int getTotalAmount() { 8 int totalPages = 0;// 默认值为0 9 String sql = "SELECT count(*) FROM w_cache_hijack_day"; 10 11 Connection conn = null; 12 PreparedStatement pstm = null; 13 ResultSet rs = null; 14 try { 15 conn = new DBManager().DataManagerConn(Conf.customerID,Conf.NETRESOURCE); 16 pstm = conn.prepareStatement(sql); 17 rs = pstm.executeQuery(); 18 if (rs.next()) { 19 totalPages = rs.getInt(1); 20 } 21 } catch (Exception e) { 22 e.printStackTrace(); 23 } finally { 24 try { 25 if(rs!=null) rs.close(); 26 if(pstm!=null) pstm.close(); 27 if(conn!=null) conn.close(); 28 } catch (SQLException e) { 29 e.printStackTrace(); 30 } 31 } 32 return totalPages; 33 }
记录可能略粗略,以备遗忘。