Spring +Spring MVC +JFreeChart+Maven 生成Web圖表
1、環境搭建
使用Maven 引導jar包,搭建環境。項目採用MVC框架,將生成的圖片發送到JSP頁面上。最近項目裏面有用到需要使用圖表工具,準備先入手JFreeChart,上手快,後期如果還有用到,考慮使用其他的圖表工具。
1.1 pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.chenhuan</groupId>
<artifactId>jfreechart</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>jfreechart Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<!-- https://mvnrepository.com/artifact/jfree/jfreechart -->
<dependency>
<groupId>jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.0.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>1.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc-portlet -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc-portlet</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/taglibs/standard -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
</dependencies>
<build>
<finalName>jfreechart</finalName>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<!-- 注意此處的url -->
<url> http://localhost:8080/manager/text</url>
<server>tomcat7</server> <!-- 此處的名字必須和setting.xml中配置的ID一致-->
<username>admin</username>
<password>admin</password>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
<ignorePackaging>true</ignorePackaging>
<path>/jfreechart</path> <!-- 此處的名字是項目發佈的工程名-->
</configuration>
</plugin>
</plugins>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
</project>
1.2 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<!-- 解決中文亂碼問題 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/appServlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup> <!-- 啓動時加載 -->
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name> <!-- url映射 -->
<url-pattern>/</url-pattern> <!-- 攔截器,攔截所有 -->
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.PNG</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.JPEG</url-pattern>
</servlet-mapping>
<!-- 針對JfreeChart的servlet -->
<servlet>
<servlet-name>DisplayChart</servlet-name>
<servlet-class>
org.jfree.chart.servlet.DisplayChart <!--這個固定不變-->
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DisplayChart</servlet-name>
<url-pattern>/DisplayChart</url-pattern>
</servlet-mapping>
</web-app>
1.3 appServlet-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd ">
<mvc:annotation-driven />
<!-- ①:對web包中的所有類進行掃描,以完成Bean創建和自動依賴注入的功能 -->
<context:component-scan base-package="com.cqu.controller" />
<!-- 這兩個類用來啓動基於Spring MVC的註解功能,將控制器與方法映射加入到容器中 -->
<beans:bean
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<beans:bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<!-- 這個類用於Spring MVC視圖解析 -->
<beans:bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/pages/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
</beans:beans>
2、 java代碼及界面
2.1 controller代碼
controller中有三個圖表,分別是柱狀圖,餅狀圖和儀表圖。在jsp頁面中通過點擊不同的鏈接可以在頁面中查看生成的相應的圖片。這部分代碼都是來源與別人的博客,我只是做了整合。
ChartController_split.java
@Controller
public class ChartController_split {
// @RequestMapping("/resultmap")
public String resultmap(){
return "/resultmap";
}
此處可以選擇性的加入下面的三個圖表代碼
}
2.1.1 顯示柱狀圖
@RequestMapping(value = "/getColumnChart")
public ModelAndView getColumnChart(HttpServletRequest request,HttpServletResponse response, ModelMap modelMap) throws Exception{
//1. 獲得數據集合
CategoryDataset dataset = getDataSet();
//2. 創建柱狀圖
JFreeChart chart = ChartFactory.createBarChart3D("學生對教師授課滿意度", // 圖表標題
"課程名", // 目錄軸的顯示標籤
"百分比", // 數值軸的顯示標籤
dataset, // 數據集
PlotOrientation.VERTICAL, // 圖表方向:水平、垂直
false, // 是否顯示圖例(對於簡單的柱狀圖必須是false)
false, // 是否生成工具
false // 是否生成URL鏈接
);
//3. 設置整個柱狀圖的顏色和文字(char對象的設置是針對整個圖形的設置)
chart.setBackgroundPaint(ChartColor.WHITE); // 設置總的背景顏色
//4. 獲得圖形對象,並通過此對象對圖形的顏色文字進行設置
CategoryPlot p = chart.getCategoryPlot();// 獲得圖表對象
p.setBackgroundPaint(ChartColor.lightGray);//圖形背景顏色
p.setRangeGridlinePaint(ChartColor.WHITE);//圖形表格顏色
//5. 設置柱子寬度
BarRenderer renderer = (BarRenderer)p.getRenderer();
renderer.setMaximumBarWidth(0.06);
//解決亂碼問題
getChartByFont(chart);
//6. 將圖形轉換爲圖片,傳到前臺
String fileName = ServletUtilities.saveChartAsPNG(chart, 700, 400, null, request.getSession());
//生成URL,用於請求
String chartURL=request.getContextPath() + "/DisplayChart?filename="+fileName;
modelMap.put("chartURL", chartURL);
//請求URL時,將URL返回到指定的JSP頁面
return new ModelAndView("resultmap",modelMap);
}
//設置文字樣式
private static void getChartByFont(JFreeChart chart) {
//1. 圖形標題文字設置
TextTitle textTitle = chart.getTitle();
textTitle.setFont(new Font("宋體",Font.BOLD,20));
//2. 圖形X軸座標文字的設置
CategoryPlot plot = (CategoryPlot) chart.getPlot();
CategoryAxis axis = plot.getDomainAxis();
axis.setLabelFont(new Font("宋體",Font.BOLD,22)); //設置X軸座標上標題的文字
axis.setTickLabelFont(new Font("宋體",Font.BOLD,15)); //設置X軸座標上的文字
//2. 圖形Y軸座標文字的設置
ValueAxis valueAxis = plot.getRangeAxis();
valueAxis.setLabelFont(new Font("宋體",Font.BOLD,15)); //設置Y軸座標上標題的文字
valueAxis.setTickLabelFont(new Font("sans-serif",Font.BOLD,12));//設置Y軸座標上的文字
}
// 獲取一個演示用的組合數據集對象 ;可以使用模擬的數據集,也可以採用數據庫返回的數據集,通過控制器將模型的數據傳送到視圖層
private static CategoryDataset getDataSet() {
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(40, "", "普通動物學");
dataset.addValue(50, "", "生物學");
dataset.addValue(60, "", "動物解剖學");
dataset.addValue(70, "", "生物理論課");
dataset.addValue(80, "", "動物理論課");
return dataset;
}
2.1.2 顯示餅狀圖
//顯示餅狀圖
@RequestMapping(value="getPieChart")
public ModelAndView getPieChart(HttpServletRequest request,HttpServletResponse response, ModelMap modelMap) throws Exception{
DefaultPieDataset dpd = new DefaultPieDataset();
dpd.setValue("管理人員", 25);
dpd.setValue("市場人員", 25);
dpd.setValue("開發人員", 45);
dpd.setValue("其他", 10);
//創建主題樣式
StandardChartTheme standardChartTheme=new StandardChartTheme("CN");
//設置標題字體
standardChartTheme.setExtraLargeFont(new Font("隸書",Font.BOLD,20));
//設置圖例的字體
standardChartTheme.setRegularFont(new Font("宋書",Font.PLAIN,15));
//設置軸向的字體
standardChartTheme.setLargeFont(new Font("宋書",Font.PLAIN,15));
//應用主題樣式
ChartFactory.setChartTheme(standardChartTheme);
JFreeChart chart = ChartFactory.createPieChart("某公司組織結構圖",dpd, true, false, false);
chart.setBackgroundPaint(Color.white);
String fileName = ServletUtilities.saveChartAsPNG(chart,600,400,request.getSession());
//ServletUtilities是面向web開發的工具類,返回一個字符串文件名,文件名自動生成,生成好的圖片會自動放在服務器(tomcat)的臨時文件下(temp)
String PieURL = request.getContextPath() + "/DisplayChart?filename=" + fileName;
//根據文件名去臨時目錄下尋找該圖片,這裏的/DisplayChart路徑要與配置文件裏用戶自定義的<url-pattern>一致
modelMap.put("PieURL", PieURL);
return new ModelAndView("resultmap",modelMap);
}
2.1.3 顯示儀表盤
//顯示儀表圖
@RequestMapping(value="getMeterChart")
public ModelAndView getMeterChart(HttpServletRequest request,HttpServletResponse response, ModelMap modelMap) throws Exception{
//1,數據集合對象 此處爲DefaultValueDataset
DefaultValueDataset dataset = new DefaultValueDataset();
// 當前指針指向的位置,即:我們需要顯示的數據
dataset.setValue(new Double(60D));
/**
* 獲取圖表區域對象
*
* A. setDataSet(int index, DataSet dataSet);
* 爲錶盤設定使用的數據集,通常一個錶盤上可能存在多個指針,
* 因此需要制定該數據集與哪個指針相互關聯。
* 可以將指針想象成數據集的一種體現方式。
*/
DialPlot dialplot = new DialPlot();
dialplot.setView(0.0D, 0.0D, 1.0D, 1.0D);
dialplot.setDataset(0,dataset);
/**
* 開始設置顯示框架結構
* B. setDailFrame(DailFrame dailFrame);設置錶盤的底層面板圖像,通常錶盤是整個儀表的最底層。
*/
DialFrame dialframe =new StandardDialFrame();
dialplot.setDialFrame(dialframe);
/**
* 結束設置顯示框架結構
* C. setBackground(Color color);設置錶盤的顏色,可以採用Java內置的顏色控制方式來調用該方法。
*/
GradientPaint gradientpaint = new GradientPaint(new Point(), new Color(255, 255, 255), new Point(), new Color(170, 170, 220));
DialBackground dialbackground = new DialBackground(gradientpaint);
dialbackground.setGradientPaintTransformer(new StandardGradientPaintTransformer(GradientPaintTransformType.VERTICAL));
dialplot.setBackground(dialbackground);
// 設置顯示在錶盤中央位置的信息
DialTextAnnotation dialtextannotation = new DialTextAnnotation("溫度");
dialtextannotation.setFont(new Font("Dialog", 1, 14));
dialtextannotation.setRadius(0.69999999999999996D);
dialplot.addLayer(dialtextannotation);
DialValueIndicator dialvalueindicator = new DialValueIndicator(0);
dialplot.addLayer(dialvalueindicator);
// 根據錶盤的直徑大小(0.75),設置總刻度範圍
/**
* E. addScale(int index, DailScale dailScale);
* 用於設定錶盤上的量程,index指明該量程屬於哪一個指針所指向的數據集,
* DailScale指明該量程的樣式,如量程的基本單位等信息。
*
* StandardDialScale(double lowerBound, double upperBound, double startAngle,
* double extent, double majorTickIncrement, int minorTickCount)
* new StandardDialScale(-40D, 60D, -120D, -300D,30D);
*/
//
StandardDialScale standarddialscale =new StandardDialScale();
standarddialscale.setLowerBound(0D);
standarddialscale.setUpperBound(100D);
standarddialscale.setStartAngle(-120D);
standarddialscale.setExtent(-300D);
standarddialscale.setTickRadius(0.88D);
standarddialscale.setTickLabelOffset(0.14999999999999999D);
standarddialscale.setTickLabelFont(new Font("Dialog", 0, 14));
dialplot.addScale(0, standarddialscale);
/**
* F. addLayer(DailRange dailRange);
* 用於設定某一特定量程的特殊表現,通常位於量程之下,如紅色範圍標註,綠色範圍標註等。
* 在調用該方法之前需要設定DailRange的一些信息,包括位置信息,顏色信息等等。
*/
//設置刻度範圍(紅色)
StandardDialRange standarddialrange = new StandardDialRange(0D, 60D, Color.red);
standarddialrange.setInnerRadius(0.52000000000000002D);
standarddialrange.setOuterRadius(0.55000000000000004D);
dialplot.addLayer(standarddialrange);
//設置刻度範圍(橘黃色)
StandardDialRange standarddialrange1 = new StandardDialRange(60D, 80D, Color.orange);
standarddialrange1.setInnerRadius(0.52000000000000002D);
standarddialrange1.setOuterRadius(0.55000000000000004D);
dialplot.addLayer(standarddialrange1);
//設置刻度範圍(綠色)
StandardDialRange standarddialrange2 = new StandardDialRange(80D, 100D, Color.green);
standarddialrange2.setInnerRadius(0.52000000000000002D);
standarddialrange2.setOuterRadius(0.55000000000000004D);
dialplot.addLayer(standarddialrange2);
/**
* 設置指針
* G. addPointer(DailPointer dailPointer);
* 用於設定錶盤使用的指針樣式,JFreeChart中有很多可供選擇指針樣式,
* 用戶可以根據使用需要,採用不同的DailPoint的實現類來調用該方法
*/
Pointer pointer = new Pointer(); //內部內
dialplot.addPointer(pointer); //addLayer(pointer);
/**
* 實例化DialCap
* H. setCap(DailCap dailCap);設定指針上面的蓋帽的樣式。
*/
DialCap dialcap = new DialCap();
dialcap.setRadius(0.10000000000000001D);
dialplot.setCap(dialcap);
//生成chart對象
JFreeChart jfreechart = new JFreeChart(dialplot);
//設置標題
jfreechart.setTitle("設備取水溫度採樣");
ChartFrame frame = new ChartFrame("CityInfoPort公司組織架構圖 ", jfreechart,true);
String fileName =ServletUtilities.saveChartAsPNG(jfreechart,600,400, request.getSession());
String MeterURL = request.getContextPath() + "/DisplayChart?filename=" + fileName;
modelMap.put("MeterURL", MeterURL);
return new ModelAndView("resultmap",modelMap);
}
2.2 一張圖片包含多個餅狀圖
2.2.1 MutilChartController .java
package com.cqu.controller;
import java.awt.Font;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.StandardChartTheme;
import org.jfree.chart.entity.StandardEntityCollection;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.MultiplePiePlot;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.servlet.ServletUtilities;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.util.TableOrder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class MutilChartController {
@RequestMapping(value="/getMutilChart")
public ModelAndView mutilChart(HttpServletRequest request,HttpServletResponse response, ModelMap modelMap) throws Exception {
String checkInType[] = { "出勤", "病假", "事假", "其他" };
String clazzs[] = { "JSD1208班", "JSD1209班", "JSD1210班", "JSD1211班" };
String chartTitle = "各班級出勤情況";
//創建主題樣式
StandardChartTheme standardChartTheme=new StandardChartTheme("CN");
//設置標題字體
standardChartTheme.setExtraLargeFont(new Font("隸書",Font.BOLD,20));
//設置圖例的字體
standardChartTheme.setRegularFont(new Font("宋書",Font.PLAIN,15));
//設置軸向的字體
standardChartTheme.setLargeFont(new Font("宋書",Font.PLAIN,15));
//應用主題樣式
ChartFactory.setChartTheme(standardChartTheme);
// 創建數據集
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
// 構建數據
int checkInData;
for (int i = 0; i < checkInType.length; i++) {
for (int j = 0; j < clazzs.length; j++) {
checkInData = 1 + (int) (Math.random() * 1000);
dataset.addValue(checkInData, checkInType[i], clazzs[j]);
}
}
// 獲取JFreeChart對象
JFreeChart chart = ChartFactory.createMultiplePieChart(
chartTitle, // 圖表標題
dataset, // 數據集
TableOrder.BY_COLUMN, // 指定被提取數據的順序
false, // 是否包含圖例
true, // 是否包含提示工具
false // 是否包含url
);
// 獲取PiePlot對象
MultiplePiePlot multiPlot = (MultiplePiePlot) chart.getPlot();
JFreeChart obj = multiPlot.getPieChart();
PiePlot plot = (PiePlot) obj.getPlot();
//設置標籤格式
plot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0} = {1} ({2})", NumberFormat.getNumberInstance(),
new DecimalFormat("0.00%")));
// 分離圓弧
for (int i = 0; i < clazzs.length; i++) {
//plot.setExplodePercent(i, 0.03D);
plot.setExplodePercent("two", 0.3d);
}
ChartRenderingInfo info = new ChartRenderingInfo(
new StandardEntityCollection());
String fileName = ServletUtilities.saveChartAsPNG(chart,1000,800,request.getSession());
String MutilChart = request.getContextPath() + "/DisplayChart?filename=" + fileName;
modelMap.put("MutilChart", MutilChart);
return new ModelAndView("resultmap",modelMap);
}
}
2.3 最後是JSP頁面
2.3.1 resultmap.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
</head>
<body>
<div style="text-align:center">
jfreechart _圖表<br><br>
點擊顯示柱狀圖<a href="getColumnChart">getColumnChart</a><br>
點擊顯示餅狀圖<a href="getPieChart" >getPieChart</a><br>
點擊顯示儀表圖<a href="getMeterChart" >getMeterChart</a><br>
點擊顯示多狀圖<a href="getMutilChart" >getMutiPieChart</a><br>
<br><br>
<img src="${chartURL}" width=600 height=400 border=0 color=gray >
<img src="${PieURL}" width=600 height=400 border=0 color=gray>
<img src="${MeterURL}" width=600 height=400 border=0 color=gray>
<img src="${MutilChart}" width=1000 height=800 border=0 color=gray>
</div>
</body>
</html>
3 項目文件包
3.1 jfreechart.war
本項目沒有使用數據庫,所以直接將jfreechart.war放在Tomcat 的webapps路徑下就可以運行了,請求路徑爲:http://localhost:8080/jfreechart/resultmap
jfreechart.war 的下載地址爲:Jfreechart.war下載
3.2 jfreechart 完整打包
包含整個文件所需要的文件。不過,要配置maven才能運行起來。下載地址爲:Jfreechart項目