上一篇文章 新手學HighCharts(一)—-基本使用 中介紹了highCharts的基本使用,今天給大家介紹對比柱狀圖的使用,貼張圖先:
highcharts數據顯示形式
在highcharts中有一個屬性series
,這個屬性主要是配置圖表要展示的數據。
var series = [ { name: 'Tokyo', data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6] }, { name: 'New York', data: [-0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5] }, { name: 'Berlin', data: [-0.9, 0.6, 3.5, 8.4, 13.5, 17.0, 18.6, 17.9, 14.3, 9.0, 3.9, 1.0] }, { name: 'London', data: [3.9, 4.2, 5.7, 8.5, 11.9, 15.2, 17.0, 16.6, 14.2, 10.3, 6.6, 4.8] } ];
每一個系列是個數組,每一項在圖片中都會生成圖表中一個圖標分類的數據,如上面的柱狀圖,每一個系列都是一個不同顏色的柱狀。
那麼如何動態加載這些數據呢?剛纔在上面說了,series
中每一個系列都是一個數組,每一個系列的加載形式是這樣的,舉個栗子:
[Array[2],Array[2],Array[2],Array[2]]
這個就是一個簡單的柱狀圖:
再往裏面細分一下是這樣的
[[“平均值”,70],[“最高分”,99],[“最低分”,35],[“及格率”,80]]
後臺
B層實現層
展示下B層實現類裏面具體的實現方法:
/** * 根據班級ID和課程ID查詢圖表數據(集合) * @param check_class 班級ID數組 * @param courseId 課程ID * @param exam_DataBase 數據庫名稱 * @return */ public List<List<Map<Serializable, Serializable>>> queryChartByCouAndClaList(String check_class, String courseId,String passMark, String dataBaseName) { StudentScoreBean studentScoreBean; List<StudentScore> studentScore=null; String[] class_check; ScoreAnalyzeByClassView classScore=new ScoreAnalyzeByClassView(); List<List<Map<Serializable,Serializable>>> listReturnMap=new ArrayList<List<Map<Serializable,Serializable>>>(); try { //遠程調用鏈接 studentScoreBean=(StudentScoreBean)this.lookupRemoteBean(studentScoreURL); class_check = check_class.split(","); //循環遍歷數組,獲取classId for(int i=0;i<class_check.length;i++) { //調用查詢方法 String classId=class_check[i].toString(); studentScore=studentScoreBean.queryScoreByCourseAndClass(courseId, classId, dataBaseName); //數據分析統計 int max=Integer.parseInt(studentScore.get(0).getTotalScore()); int min=Integer.parseInt(studentScore.get(0).getTotalScore()); int sum=0; int pass=0; //最低分、最高分 //循環遍歷獲取最高分和最低分 for(int j=0;j<studentScore.size();j++) { int value=Integer.parseInt(studentScore.get(j).getTotalScore()); //最大值和最小值 if(min>value) { min=value; //最大值 } if(max<value) { max=value; //最小值 } //總和 int num=value; sum+=num; //及格人數 if(value>=Integer.parseInt(passMark)) { pass+=1; } } //求平均值 double avg=sum/studentScore.size(); //及格率 double passMK=pass*100/studentScore.size(); classScore.setClassAvgScore(String.valueOf(avg)); classScore.setClassHighScore(String.valueOf(max)); classScore.setClassLowScore(String.valueOf(min)); classScore.setClassPassRate(String.valueOf(passMK)); Map<Serializable,Serializable> map1=new HashMap<Serializable,Serializable>(); map1.put("name", "平均分"); map1.put("count", Double.parseDouble(classScore.getClassAvgScore())); Map<Serializable,Serializable> map2=new HashMap<Serializable,Serializable>(); map2.put("name", "最高分"); map2.put("count", Double.parseDouble(classScore.getClassHighScore())); Map<Serializable,Serializable> map3=new HashMap<Serializable,Serializable>(); map3.put("name", "最低分"); map3.put("count", Double.parseDouble(classScore.getClassLowScore())); Map<Serializable,Serializable> map4=new HashMap<Serializable,Serializable>(); map4.put("name", "及格率"); map4.put("count", Double.parseDouble(classScore.getClassPassRate())); List<Map<Serializable,Serializable>> listMap=new ArrayList<Map<Serializable,Serializable>>(); listMap.add(map1); listMap.add(map2); listMap.add(map3); listMap.add(map4); listReturnMap.add(listMap); //在list集合外在嵌套一層list } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return listReturnMap; }
因爲界面顯示時用到的不只是一條數據,所以返回值在list外面有嵌套了一層list,每一個List<Map<Serializable,Serializable>>
在經過json轉換之後,都是一個系列,在嵌套一層list,就是多個系列。
Controller層
Controller層沒什麼好說的,只是起到一個接受界面數據,傳給B層;接受B層處理的數據,返給界面;主要的業務邏輯處理都在B層。
/** * 根據班級ID和課程ID查詢圖表數據(集合) * @param request * @param response */ @RequestMapping("/queryChartByCouAndClaList") public void queryChartByCouAndClaList(HttpServletRequest request,HttpServletResponse response) { //獲取前臺界面數據 String check_class=request.getParameter("Check_val"); String courseId=request.getParameter("CourseId"); String passMark=request.getParameter("PassMark"); //查詢數據 List<List<Map<Serializable, Serializable>>> listChart=scoreAnalyzeFacadeClassBean.queryChartByCouAndClaList(check_class,courseId,passMark,Exam_DataBase); //json轉換 jacksonJsonUntil.beanToJson(response, listChart); }
前臺
JSP
圖表顯示,jsp中只需要給highcharts定義一個容器存放就行。
<div id="columnChart" style="width:900px; height: 500px; margin-top:20px;"></div>
JavaScript
在實現動態加載的過程中,重要的地方一個是B層的業務邏輯實現,另一個就是javascript中的一個轉換。 當後臺數據經過json轉換之後,傳達js裏面的數據形式是這樣的:
[Array[4],Array[4]]
這樣的話還不能夠顯示,爲什麼,因爲每個Array下,存的是一個個的對象,給highcharts的數據顯示不一樣,每一個Array下的具體形式是這樣的:
[Object[2],Object[2],Object[2],Object[2]]
每一個Object下再分纔是具體的數據
[“平均值”,70]
所以還需要把接受到的數據進行轉換,轉換成適合highcharts顯示的格式:
var title="班級成績對比分析"; var renderToDiv="columnChart"; //要加載到的div GetOptions(renderToDiv,title); //獲取highcharts的基本樣式 options.series=new Array(); var i,j; for(i=0;i<check_val.length;i++) //循環賦值 { options.series[i]=new Object(); //實例化對象 options.series[i].name=class_name[i]; //獲取班級名稱 var array=[]; //定義數組 for(j=0;j<data[i].length;j++) //循環獲取柱狀圖數據 { var result=new Array(data[i][j].name,data[i][j].count); array.push(result); } options.series[i].data=array; }
如果你細看的話,就會發現一個問題,其中的GetOptions
是哪來的,不要着急,下面給你介紹,Highcharts庫使用的是json格式來配置的數據,首先定義highcharts的基本樣式
var chart; var options; function GetOptions(renderToDiv,title) { options={ chart: { type: 'column', renderTo: renderToDiv, //添加到那個div下 }, credits: { enabled: false, }, title: { text: title }, xAxis: { categories: [ ], labels: { rotation: 0, align: 'right', style: { fontSize: '13px', fontFamily: 'Verdana, sans-serif' } } }, yAxis: { min: 0, title: { text: '總值' } }, legend: { enabled: true //圖例開關 }, tooltip: { //pointFormat: '總值', }, series: [{ dataLabels: { enabled: true, rotation: -90, color: '#FFFFFF', align: 'right', x: 4, y: 10, style: { fontSize: '13px', fontFamily: 'Verdana, sans-serif', textShadow: '0 0 3px black' } } }] } }
這些都是一些可以複用的屬性,然後再把數據動態的加載到options中,把整個樣式放到準備好的盛放容器中就可以了。
chart=new Highcharts.Chart(options); //實例化一個新的Highcharts圖表
這樣,圖表就成功的動態加載出來了!