聊聊、Highcharts 动态数据
最近项目中需要用到图表,找了几个开源框架,最后选择 Highcharts,原因是 Highcharts 功能强大,稳定,方便,而且开源,社区比较成熟。
首先下载 Highcharts,导入项目。
在 HTML 页面引入相应的 Js 文件。我这个项目是情绪监控相关,所谓情绪也就是热点的意思。大数据团队通过爬虫,先从数据库词典里拿到比较靠前的几个行业名称,然后通过爬虫在网上抓取这几个行业的热度值。每天固定时间抓取,统计一次。
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>情绪监控页</title>
<script src="../../Highcharts/code/highcharts.js" type="text/javascript"></script>
<script src="../../Highcharts/code/modules/exporting.js" type="text/javascript"></script>
<script src="../../KJAF2/js/base/jquery.js" type="text/javascript"></script>
<script src="../../KJAF2/js/base/jquery.cookie.js" type="text/javascript"></script>
<script src="../../KJAF2/js/base/jquery-ui-1.8.18.custom.min.js" type="text/javascript"></script>
<script src="../../KJAF2/js/base/jquery.ztree.js" type="text/javascript"></script>
<style type="text/css">
#container {
width: 800px;
height: 600px;
margin: 0 auto
}
</style>
</head>
<body>
<div id="container"></div>
<script type="text/javascript">
var chart = null; // 定义全局变量
$(document).ready(function() {
chart = new Highcharts.Chart({
chart : {
renderTo : 'container',
events : {
load : requestData
}
},
title : {
text : '情绪监控'
},
subtitle : {
text : 'www.xxx.com'
},
legend : {
layout : 'vertical',
align : 'right',
verticalAlign : 'middle',
borderWidth : 0
},
xAxis : {
title : {
text : 'thetime'
},
categories : []
},
yAxis : {
tickInterval : 0.5,
max : 20,
min : -20,
title : {
text : 'weight'
}
},
series : [{
name : '汽车零部件'
}, {
name : '专用设备'
}, {
name : '建筑装饰'
}, {
name : '计算机设备'
}, {
name : '传媒'
}, {
name : '仪器仪表'
}, {
name : '电子制造'
}, {
name : '通信设备'
}, {
name : '光学光电子'
}, {
name : '化工新材料'
} ]
});
});
function requestData() {
$.ajax({
url: '../../emotion/xxx/handle.do',
type : 'GET',
dataType : 'json',
contentType : 'application/json',
success: function(point) {
var tempArr0 = [0,0,0,0,0,0,0,0,0,0,0,0];
var tempArr1 = [0,0,0,0,0,0,0,0,0,0,0,0];
var tempArr2 = [0,0,0,0,0,0,0,0,0,0,0,0];
var tempArr3 = [0,0,0,0,0,0,0,0,0,0,0,0];
var tempArr4 = [0,0,0,0,0,0,0,0,0,0,0,0];
var tempArr5 = [0,0,0,0,0,0,0,0,0,0,0,0];
var tempArr6 = [0,0,0,0,0,0,0,0,0,0,0,0];
var tempArr7 = [0,0,0,0,0,0,0,0,0,0,0,0];
var tempArr8 = [0,0,0,0,0,0,0,0,0,0,0,0];
var tempArr9 = [0,0,0,0,0,0,0,0,0,0,0,0];
var times = [];
var timeMap = point[point.length-1].timeMap;
$.each(timeMap,function(m,obj){
times.push(obj);
});
$.each(point,function(m,obj){
if(obj.type == 0){
tempArr0[obj.time]=obj.weight;
}else if(obj.type == 1){
tempArr1[obj.time]=obj.weight;
}else if(obj.type == 2){
tempArr2[obj.time]=obj.weight;
}else if(obj.type == 3){
tempArr3[obj.time]=obj.weight;
}else if(obj.type == 4){
tempArr4[obj.time]=obj.weight;
}else if(obj.type == 5){
tempArr5[obj.time]=obj.weight;
}else if(obj.type == 6){
tempArr6[obj.time]=obj.weight;
}else if(obj.type == 7){
tempArr7[obj.time]=obj.weight;
}else if(obj.type == 8){
tempArr8[obj.time]=obj.weight;
}else if(obj.type == 9){
tempArr9[obj.time]=obj.weight;
}
});
chart.series[0].setData(tempArr0);
chart.series[1].setData(tempArr1);
chart.series[2].setData(tempArr2);
chart.series[3].setData(tempArr3);
chart.series[4].setData(tempArr4);
chart.series[5].setData(tempArr5);
chart.series[6].setData(tempArr6);
chart.series[7].setData(tempArr7);
chart.series[8].setData(tempArr8);
chart.series[9].setData(tempArr9);
times = times.reverse();
chart.xAxis[0].setCategories(times);
// 一秒后继续调用本函数
setTimeout(requestData, 600000);
},
cache: false
});
}
</script>
</body>
</html>
整个页面,600s 刷新一次,动态数据通过 Json 从后台以 get 方式获取。后台则就是一个 Spring Controller。这个页面则要注意几点。xAxis 轴的 categories 动态获取,动态插入值则需要写成 chart.xAxis[0].setCategories(times)。chart.xAxis 是不行的。
package com.szkingdom.lakala.system.handler;
import com.alibaba.fastjson.JSON;
import com.szkingdom.lakala.common.util.SpringContextUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Scope;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* EmotionHandler
* 情绪监控处理类
* xums
* 2017-08-14-下午4:38
*/
@Controller
@Scope("prototype")
@RequestMapping("/emotion")
public class EmotionHandler {
private Logger log = LoggerFactory.getLogger(getClass());
@Autowired
public JdbcTemplate emotionJdbcTemplate;
@RequestMapping(value = "/xxx/handle.do", produces = "application/json;charset=UTF-8")
@ResponseBody
public String handle(HttpServletRequest request, HttpServletResponse response) {
log.info("【情绪监控控制类】...EmotionHandler...handle...");
List<Map<String, Object>> finalList = new ArrayList<Map<String, Object>>();
try {
List<String> timeList = emotionJdbcTemplate.queryForList("select distinct thetime from table order by thetime desc limit 12", String.class);
Map<String, Object> timeMap = new HashMap<String, Object>();
timeMap.put("timeMap", timeList);
Map<String, String> timeSortMap = new HashMap<String, String>();
int n = timeList.size();
StringBuilder builder = new StringBuilder();
for (String time : timeList) {
builder.append("'").append(time).append("'").append(",");
timeSortMap.put(time,String.valueOf(--n));
}
String time = builder.toString();
time = time.substring(0,time.lastIndexOf(","));
List<Map<String, Object>> list = emotionJdbcTemplate.queryForList("select * from table where thetime in ("+time+") group by category,thetime desc");
for (Map<String, Object> map : list) {
String category = (String) map.get("category");
String theTime = (String) map.get("thetime");
if ("汽车零部件".equals(category)) {
map.put("type", "0");
} else if ("专用设备".equals(category)) {
map.put("type", "1");
} else if ("建筑装饰".equals(category)) {
map.put("type", "2");
} else if ("计算机设备".equals(category)) {
map.put("type", "3");
} else if ("传媒".equals(category)) {
map.put("type", "4");
} else if ("仪器仪表".equals(category)) {
map.put("type", "5");
} else if ("电子制造".equals(category)) {
map.put("type", "6");
} else if ("通信设备".equals(category)) {
map.put("type", "7");
} else if ("光学光电子".equals(category)) {
map.put("type", "8");
} else if ("化工新材料".equals(category)) {
map.put("type", "9");
} else {
continue;
}
map.put("time", timeSortMap.get(theTime));
finalList.add(map);
}
finalList.add(timeMap);
} catch (Exception e) {
log.error("【情绪监控控制类】...EmotionHandler...handle...异常..." + e.getMessage());
}
String jsonStr = getSuccResult(finalList);
System.out.println(jsonStr);
return jsonStr;
}
protected String getSuccResult(Object o) {
String ss = JSON.toJSONString(o);
return ss;
}
}
后台则需要注意,produces = "application/json;charset=UTF-8" ,这里很重要。关于 Mysql 数据源的配置,这里就不写了。比较简单。我这里直接用的 org.springframework.jdbc.core.JdbcTemplate,数据源用 c3p0。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<!-- Connection Info -->
<property name="driverClass" value="${masterEmotion.jdbc.driver}"></property>
<property name="jdbcUrl" value="${masterEmotion.jdbc.url}"></property>
<property name="user" value="${masterEmotion.jdbc.username}"></property>
<property name="password" value="${masterEmotion.jdbc.password}"></property>
<property name="maxPoolSize" value="20"></property>
<property name="minPoolSize" value="3"></property>
<property name="maxIdleTime" value="1800" />
<property name="initialPoolSize" value="3"></property>
<property name="autoCommitOnClose" value="false" />
</bean>
<bean id="emotionJdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSources"/>
</bean>
</beans>
最终结果
感谢大家观看!