今天头有点痛,所以不能详细地写了,先把代码贴上来,等身体状况稍微好一点,再继续完善。
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<Element> 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<Element> 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,dataElement); } return xmlDoc.asXML(); } createSeriesElement(title,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,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",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,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,List<?> dataList) throws Exception { LOGGER.info("【使用simpleHistogram.xml模板生成简单的柱状图的XML数据】xName : " + xName + ",yData); InputStream inputStream = AnyChartXMLProcessor.class.getClassLoader().getResourceAsStream( SIMPLE_HISTOGRAM_TEMPLATE_FILE); return templateProcessor(title,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,List<List<?>> dataList) throws Exception { LOGGER.info("【使用simpleHistogram.xml模板生成简单的多柱柱状图的XML数据】xName : " + xName + ",yData); InputStream inputStream = AnyChartXMLProcessor.class.getClassLoader().getResourceAsStream( SIMPLE_HISTOGRAM_TEMPLATE_FILE); return templateProcessor(title,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; } }
折线图模板(simpleLine.xml):
<anychart> <settings> <animation enabled="True"/> </settings> <charts> <chart plot_type="CategorizedVertical"> <chart_settings> <title enabled="true"> <text>标题未初始化</text> </title> <axes> <x_axis tickmarks_placement="Center"> <labels enabled="true" rotation="60" display_mode="rotated" align="Inside"> </labels> <title enabled="true"> <text>#XTitle#</text> </title> </x_axis> <y_axis> <title enabled="true"> <text>#YTitle#: {%Min} - {%Max}</text> </title> </y_axis> </axes> </chart_settings> <data_plot_settings default_series_type="Line"> <line_series point_padding="0.2" group_padding="1"> <label_settings enabled="true"> <background enabled="false"/> <font color="Rgb(45,45,45)" bold="true" size="9"> <effects enabled="true"> <glow enabled="true" color="White" opacity="1" blur_x="1.5" blur_y="1.5" strength="3"/> </effects> </font> <format>{%YValue}{numDecimals:0}</format> </label_settings> <tooltip_settings enabled="true"> <format> #YTitle#: {%YValue}{numDecimals:2} #XTitle#: {%Name} </format> <background> <border type="Solid" color="DarkColor(%Color)"/> </background> <font color="DarkColor(%Color)"/> </tooltip_settings> <marker_settings enabled="true"/> <line_style> <line thickness="3"/> </line_style> </line_series> </data_plot_settings> <data> </data> </chart> </charts> </anychart>
<anychart> <settings> <animation enabled="True"/> </settings> <charts> <chart plot_type="CategorizedVertical"> <chart_settings> <title enabled="true"> <text>标题未初始化</text> </title> <axes> <x_axis tickmarks_placement="Center"> <labels enabled="true" rotation="60" display_mode="rotated" align="Inside"> </labels> <title enabled="true"> <text>#XTitle#</text> </title> </x_axis> <y_axis> <title enabled="true"> <text>#YTitle#: {%Min} - {%Max}</text> </title> </y_axis> </axes> </chart_settings> <data_plot_settings default_series_type="Bar"> <bar_series group_padding="0.2"> <tooltip_settings enabled="true"> <format> #YTitle#: {%YValue}{numDecimals:2} #XTitle#: {%Name} </format> <background> <border type="Solid" color="DarkColor(%Color)"/> </background> <font color="DarkColor(%Color)"/> </tooltip_settings> </bar_series> </data_plot_settings> <data> </data> </chart> </charts> </anychart>
我是使用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('系统异常,请联系管理员!'); } }) }
大家一起学习进步。