今天头有点痛,所以不能详细地写了,先把代码贴上来,等身体状况稍微好一点,再继续完善。
1、(主角)一个使用XML模板生成Anychart XML数据的工具类
/**
*
*/
package com.common.anychart;
import java.io.InputStream;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.NullArgumentException;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.common.reflect.ReflectUtils;
/**
* XML数据处理工具类,服务于AnyChart报表
* @author luolin
*
* @version $id:AnyChartXMLProcessor.java,v 0.1 2015年8月19日 上午10:15:57 luolin Exp $
*/
public class AnyChartXMLProcessor {
private static final Logger LOGGER = Logger
.getLogger(AnyChartXMLProcessor.class);
/** 简单线性曲线图模板路径 */
private static final String SIMPLE_LINE_TEMPLATE_FILE = "xmltemplate/simpleLine.xml";
/** 简单柱状图图模板路径 */
private static final String SIMPLE_HISTOGRAM_TEMPLATE_FILE = "xmltemplate/simpleHistogram.xml";
/**
* 使用simpleLine.xml模板生成简单的线性曲线图XML数据
* @param xName x轴标题,格式如:“X轴标题@feild”,feild表示从数据中取值的字段
* @param yName y轴标题,格式如:“y轴标题@feild”,feild表示从数据中取值的字段
* @param title 图标标题
* @param dataList 要展示的数据
* @return 生成的XML数据
* @throws Exception
*/
public static String simpleLine(String xName, String yName, String title, List> dataList)
throws Exception {
LOGGER.info("【使用categorizedVertical.xml模板生成简单的线性曲线图XML数据】xName : " + xName + " , yName : "
+ yName + " , title : " + title);
// 基本参数校验
if (!baseDataValidate(xName, yName, title, dataList)) {
return "";
}
String[] xData = xName.split("@");
String[] yData = yName.split("@");
// 坐标轴数据校验
axisFormatValidate(xData, yData);
InputStream inputStream = AnyChartXMLProcessor.class.getClassLoader().getResourceAsStream(
SIMPLE_LINE_TEMPLATE_FILE);
return templateProcessor(title, dataList, xData, yData, inputStream);
}
/**
* 根据模板处理数据,生成修改后的XML数据
* @param title 统计图的标题
* @param dataList 统计数据
* @param xData X轴数据
* @param yData Y轴数据
* @param inputStream 读入模板的流
* @return 修改模板后得到的XML数据
* @throws Exception
*/
@SuppressWarnings("unchecked")
private static String templateProcessor(String title, List> dataList, String[] xData,
String[] yData, InputStream inputStream)
throws Exception {
SAXReader sax = new SAXReader();
Document xmlDoc = sax.read(inputStream);
Element root = xmlDoc.getRootElement();//根节点
// 取得text节点
List titleElements = root.selectNodes("//text");
// 得到chart_settings下的第一个text节点,并修改它的值
Element titleElement = titleElements.get(0);
titleElement.setText(title);
// 得到X轴的第一个text坐标,修改它的值
Element xTitleElement = titleElements.get(1);
xTitleElement.setText(xData[0]);
// 得到X轴的第一个text坐标,修改它的值
Element yTitleElement = titleElements.get(2);
String yTitleTemplate = yTitleElement.getTextTrim();
yTitleElement.setText(yTitleTemplate.replace("#YTitle#", yData[0]));
// 替换format里面的x、y的标题
List formatElements = root.selectNodes("//format");
if (CollectionUtils.isNotEmpty(formatElements)) {
for (Element element : formatElements) {
String formatText = element.getTextTrim();
element.setText(formatText.replace("#YTitle#", yData[0]).replace("#XTitle#",
xData[0]));
}
}
Element dataElement = (Element) root.selectSingleNode("//data");
// 如何数据集里存放的是更多数据集(表示需要多条线或者多柱),循环处理
if (dataList.get(0) instanceof List) {
for (Object element : dataList) {
createSeriesElement(title, (List>) element, xData, yData, dataElement);
}
return xmlDoc.asXML();
}
createSeriesElement(title, dataList, xData, yData, dataElement);
return xmlDoc.asXML();
}
/**
* 生成series部分
* @param title 标题
* @param dataList 数据集合
* @param xData X轴数据
* @param yData Y轴数据
* @param dataElement "data"节点
* @throws Exception
*/
private static void createSeriesElement(String title, List> dataList, String[] xData,
String[] yData, Element dataElement) throws Exception {
Element seriesElement = dataElement.addElement("series");
seriesElement.addAttribute("name", title);
for (Object item : dataList) {
Element pointElement = seriesElement.addElement("point");
pointElement.addAttribute("name",
String.valueOf(ReflectUtils.getCellValue(item, xData[1])));
pointElement.addAttribute("y",
String.valueOf(ReflectUtils.getCellValue(item, yData[1])));
}
}
/**
* 坐标轴数据校验
* @param xData X轴信息
* @param yData Y轴信息
*/
private static void axisFormatValidate(String[] xData, String[] yData) {
if (xData.length < 2) {
LOGGER.warn("【xName参数不正确】xData : " + xData);
throw new IllegalArgumentException("xName");
}
if (yData.length < 2) {
LOGGER.warn("【yName参数不正确】yData : " + yData);
throw new IllegalArgumentException("yName");
}
}
/**
* 基本数据校验
* @param xName x轴标题,格式如:“X轴标题@feild”,feild表示从数据中取值的字段
* @param yName y轴标题,格式如:“y轴标题@feild”,feild表示从数据中取值的字段
* @param title 图标标题
* @param dataList 要展示的数据
*/
private static boolean baseDataValidate(String xName, String yName, String title,
List> dataList) {
if (CollectionUtils.isEmpty(dataList)) {
LOGGER.warn("【数据dataList为空】");
return false;
}
if (StringUtils.isBlank(xName)) {
LOGGER.warn("【xName为空】");
throw new NullArgumentException("xName");
}
if (StringUtils.isBlank(yName)) {
LOGGER.warn("【yName为空】");
throw new NullArgumentException("yName");
}
if (StringUtils.isBlank(title)) {
LOGGER.warn("【title为空】");
throw new NullArgumentException("title");
}
return true;
}
/**
* 使用simpleHistogram.xml模板生成简单的柱状图的XML数据
* @param xName x轴标题,格式如:“X轴标题@feild”,feild表示从数据中取值的字段
* @param yName y轴标题,格式如:“y轴标题@feild”,feild表示从数据中取值的字段
* @param title 图标标题
* @param dataList 要展示的数据
* @return 生成的XML数据
* @throws Exception
*/
public static String simpleHistogram(String xName, String yName, String title, List> dataList)
throws Exception {
LOGGER.info("【使用simpleHistogram.xml模板生成简单的柱状图的XML数据】xName : " + xName + " , yName : "
+ yName + " , title : " + title);
// 基本参数校验
if (!baseDataValidate(xName, yName, title, dataList)) {
return "";
}
String[] xData = xName.split("@");
String[] yData = yName.split("@");
// 坐标轴数据校验
axisFormatValidate(xData, yData);
InputStream inputStream = AnyChartXMLProcessor.class.getClassLoader().getResourceAsStream(
SIMPLE_HISTOGRAM_TEMPLATE_FILE);
return templateProcessor(title, dataList, xData, yData, inputStream);
}
/**
* 使用simpleHistogram.xml模板生成简单的多柱柱状图的XML数据
* @param xName x轴标题,格式如:“X轴标题@feild”,feild表示从数据中取值的字段
* @param yName y轴标题,格式如:“y轴标题@feild”,feild表示从数据中取值的字段
* @param title 图标标题
* @param dataList 要展示的数据
* @return 生成的XML数据
* @throws Exception
*/
public static String compareHistogram(String xName, String yName, String title,
List> dataList) throws Exception {
LOGGER.info("【使用simpleHistogram.xml模板生成简单的多柱柱状图的XML数据】xName : " + xName + " , yName : "
+ yName + " , title : " + title);
// 基本参数校验
if (!baseDataValidate(xName, yName, title, dataList)) {
return "";
}
String[] xData = xName.split("@");
String[] yData = yName.split("@");
// 坐标轴数据校验
axisFormatValidate(xData, yData);
InputStream inputStream = AnyChartXMLProcessor.class.getClassLoader().getResourceAsStream(
SIMPLE_HISTOGRAM_TEMPLATE_FILE);
return templateProcessor(title, dataList, xData, yData, inputStream);
}
}
2015-8-27 09:26:11更新:昨天忘记添加其中用到的一个反射工具类的代码,今天补上:
ReflectUtils.java
/**
*
*/
package com.common.reflect;
import java.lang.reflect.Field;
/**
* 反射工具类
* @author luolin
*
* @version $id:ReflectUtils.java,v 0.1 2015年8月19日 下午1:46:54 luolin Exp $
*/
public class ReflectUtils {
/**
* 通过字段名从对象中得到字段的值
* @param object 对象
* @param fieldName 字段名
* @return 字段对应的值
* @throws Exception
*/
public static Object getCellValue(Object object, String fieldName) throws Exception {
Field[] fields = object.getClass().getDeclaredFields();
Object value = null;
for (Field field : fields) {
field.setAccessible(true);
if (field.getName().equals(fieldName)) {
value = field.get(object);
break;
}
}
return value;
}
}
2、模板文件:目前我使用了两个简单的模板文件。朋友们在使用的时候,注意模板相对工程的路径需要根据实际情况修改。
折线图模板(simpleLine.xml):
标题未初始化
#XTitle#
#YTitle#: {%Min} - {%Max}
{%YValue}{numDecimals:0}
#YTitle#: {%YValue}{numDecimals:2}
#XTitle#: {%Name}
柱状图模板(simpleHistogram.xml):
标题未初始化
#XTitle#
#YTitle#: {%Min} - {%Max}
#YTitle#: {%YValue}{numDecimals:2}
#XTitle#: {%Name}
3、如何使用?
我是使用AJAX的方式获取XML数据并交给anychart的。
/**
* 创建图表
* @param chartDivId 显示图表的DIV的ID
* @param xmlData 图表需要的XML数据
*/
function createChart(chartDivId,xmlData){
AnyChart.swfFile = "../js/anychart/AnyChart.swf";
AnyChart.initText = "初始化中,请稍后...";
AnyChart.xmlLoadingText = "数据加载中,请稍后...";
AnyChart.noDataText = "没有数据显示,换个查询条件试试!";
var g_dxzr_chart = new AnyChart();
g_dxzr_chart.width = '100%';
g_dxzr_chart.height = '100%';
g_dxzr_chart.bgColor = "#ffffff";
g_dxzr_chart.setData(xmlData);
g_dxzr_chart.write(chartDivId);
}
/**
* 获取数据
* @param top3FormId 查询参数的form的ID
*/
function executeAnalyzeTop3(top3FormId,chartDivId){
var $form = $('#'+top3FormId);
$.ajax({
url:$form.attr('action'),
data:$form.serialize(),
dataType:'text',
type:'post',
success:function(data){
// 创建图表
createChart(chartDivId,data);
},
error:function(){
alert('系统异常,请联系管理员!');
}
})
}
大家如果有什么问题的话,可以给我留言,我也是最近才接触到anychart的,效果其实觉得还不错。
大家一起学习进步。