需求

我们在投诉模块中还有一个功能没有实现:

统计:根据年度将相应年度的每个月的投诉数进行统计,并以图表的形式展示在页面中;在页面中可以选择查看当前年度及其前4年的投诉数。在页面中可以选择不同的年度,然后页面展示该年度的曲线统计图。

我们到目前为止是没有学过任何的统计图的工具的,那么我们要怎么解决这个功能呢???我们有另外的组件来把统计图显示出来:FusionCharts

FusionCharts 是使用javascript 实现统计图表的js组件;其官网地址:http://www.fusioncharts.com。

具体的是怎么操作的可以看官方文档,我们以项目的需求来完成对应的功能就行了。


FusionCharts使用

FusionCharts安装

首先,我们要把对应的JS文档加入到我们的项目中:

  • “fusioncharts.js”
  • “fusioncharts.charts.js”
  • 和相关主题文件复制到项目的js/fusioncharts文件夹。

引入Demo

我们只要根据修改Demo的值就可以实现出我们想要的效果了。


<!DOCTYPE HTML>
<html>
<head>
<%@include file="/common/header.jsp" %>
<title>年度投诉统计图</title>
<script type="text/javascript" src="${basePath}js/fusioncharts.js"></script>
<script type="text/javascript" src="${basePath}js/fusioncharts.charts.js"></script>
<script type="text/javascript" src="${basePath}js/themes/fusioncharts.theme.fint.js"></script>
<script>
FusionCharts.ready(function () {
var revenueChart = new FusionCharts({
"type": "column2d",
"renderAt": "chartContainer",
"width": "500",
"height": "300",
"dataFormat": "json",
"dataSource": {
"chart": {
"caption": "Monthly revenue for last year",
"subCaption": "Harry's SuperMart",
"xAxisName": "Month",
"yAxisName": "Revenues (In USD)",
"theme": "fint"
},
"data": [
{
"label": "Jan",
"value": "420000"
},
{
"label": "Feb",
"value": "810000"
},
{
"label": "Mar",
"value": "720000"
},
{
"label": "Apr",
"value": "550000"
},
{
"label": "May",
"value": "910000"
},
{
"label": "Jun",
"value": "510000"
},
{
"label": "Jul",
"value": "680000"
},
{
"label": "Aug",
"value": "620000"
},
{
"label": "Sep",
"value": "610000"
},
{
"label": "Oct",
"value": "490000"
},
{
"label": "Nov",
"value": "900000"
},
{
"label": "Dec",
"value": "730000"
}
]
}
});
revenueChart.render();
})
</script>
</head> <body>
<br>
<s:select id="year" list="{2015}" onchange="doAnnualStatistic()"></s:select>
<br>
<div id="chartContainer"></div>
</body>
</html>

需求分析

再次回到我们的需求原型图,我们看看是怎么样的:

根据不同的年份,就显示出不同的统计图数据…..这明显就用到了ajax技术。 因此可以确定下来,我们的前端就是用ajax进行交互,渲染出对应的统计图的。

我们的后端就是根据不同的年份,去获取不同的年份每个月的数据,返回给浏览器

前端分析

我们的需求是得让我们显示近5年的统计图…于是下拉框是我们近5年的….

我们虽然是可以把option中的数据写死,但是呢,如果过了一年的话,那么我们的数据是不会同步的。当我在2017年写的时候,到2018年,页面显示还是2017年的数据….所以这明显是不合理的….

要想近5年是动态产生的,就不能够把数据写死….于是我们可以在JSP页面上得到当前年的值,根据当前年就非常容易推出近5年的数据了…

于是我们又可以使用到Calendar这个日历类了…

在JSP页面得到当前年的数据,并装载到list集合中

    Calendar calendar = Calendar.getInstance();

    //得到当前年的值
int year = calendar.get(Calendar.YEAR); //把年份用一个集合装载
List yearList = new ArrayList(); //获取近5年的值
for(int i =0; i<5; i++) {
yearList.add(i, year--);
}
request.setAttribute("yearList", yearList);
request.setAttribute("year", year);

在Struts的select标签中把这个集合迭代出来


<s:select id="year" list="#request.yearList" onchange="doAnnualStatistic()"></s:select>

下面是我们的效果:


接着,我们发现FusionCharts这个组件,想要把数据显示在统计图表中,我们的JSON数据的格式是需要这样的

还有值得注意的地方是,一进入页面中需要加载当前年度的投诉统计数


<script> //页面一加载就执行方法
$(function () {
doAnnualStatistic();
}); //根据年份获取投诉数
function doAnnualStatistic() {
//获取当前年份
var $year = $("#year option:selected").val(); //一进来,如果没有选择任何的年数,就显示当前年份的
if($year=="" || $year==undefined) {
$year = "${year}";
}
//2、统计年度投诉数据并展示图表
$.ajax({
url: "${basePath}complain/complain_getAnnualStatisticData.action",
type: "post",
dataType: "json",
data: {"year",$year},
success: function (backData) {
if(backData!=null && backData!=""){
var revenueChart = new FusionCharts({
"type": "line",
"renderAt": "chartContainer",
"width": "600",
"height": "400",
"dataFormat": "json",
"dataSource": {
"chart": {
"caption": "年度统计投诉数",
"xAxisName": "月 份",
"yAxisName": "投 诉 数",
"theme": "fint"
},
"data":backData.chartData
}
});
revenueChart.render();
}
},
error:function () {
alert("统计投诉数失败!");
}
});
}
</script>

后端分析

我们的后端就是根据年份,获取对应的值,返回一个JSON格式给浏览器,那就行了…

但是呢,我们还有其他的细节需要考虑:今年是2017年7月,但是在查询年度投诉数是要把整个年的信息查询出来,8-12月的投诉数肯定是没有的。那么我们会将还没到的时间设置成“”,如果在2016年的某月是没有投诉数的,我们应该将其替换成0,而不是“”….

在action中,我们得获取到用户传递过来的年份,我们调用service、dao层的方法获取该年度对应每个月的投诉数,转换成JSON格式输出就行了。

我们知道前端需要的JSON格式是一个对象数组,最终目的就是数组:Struts2框架在最后解析的时候,会把集合解析成是数组。对象数组在java编程语言就是List集合中嵌套着Map集合。

在后端中,还有一个难点,就是我们的SQL语句该怎么写????我们要从数据库查询的是该年份每个月的投诉数….

通过该年而查询每个月,我们可以很快地想到要用到分组查询。但是还有一个问题,我们在进行分组查询的时候,如果表中是没有1月或2月等数组的话,分组查询出来的数据是没有这些月份的。而我们的统计图是需要所有月份的数据的。咋看一下,我们是需要把查询出来的数据做循环判断,得看看有没有该月份,如果没有该月份还得把数据填充进去。。还得判断该月份是不是本年度的….这样想一下就觉得麻烦了……


select month(comp_time) as '月份',count(*) '总数'
from complain
where year(comp_time)=?
group by month(comp_time)


再次回到前面分析的,如果本年度的月份还没有到,那么将该月的数据设置为“”,如果是其他年份的的月份查出的数据为null,那么我们应该把这些月份的投诉数设置为0而不是”“…..

但是呢,我们现在有一个办法,可以在查询的时候,不管该月份有没有数据,都得显示出来….这就是左外连接

于是我们自己手动生成一张拥有12个月份的数据表,跟我们的投诉表进行左外连接…


select imonth, count(comp_id)
from t_month left join complain on imonth=month(comp_time)
and year(comp_time)=2017
group by imonth
order by imonth;

上面的sql语句的查询效率是有点低的,我们改造一下,改成是子查询:


select imonth,c2
from t_month left join (select month(comp_time) c1, count(comp_id) c2 from complain where year(comp_time)=? group by month(comp_time)) t
on imonth = c1
order by imonth;

代码实现

dao层根据年份查询出每个月份的投诉数据


/**
*
* @param year 根据年获取数据
* @return 返回的是一个列表数组
*/
@Override
public List<Object[]> getAnnualStatisticByYear(int year) { //拼接SQL语句
StringBuffer buffer = new StringBuffer();
buffer.append(" SELECT imonth,c2 ")
.append(" FROM t_month")
.append(" LEFT JOIN (SELECT month(comp_time) c1, count(comp_id) c2 FROM complain WHERE YEAR(comp_time)=? GROUP BY MONTH(comp_time)) t")
.append(" ON imonth = c1")
.append(" ORDER BY imonth;");
SQLQuery sqlQuery = getSession().createSQLQuery(buffer.toString());
sqlQuery.setParameter(0, year); List<Object[]> list = sqlQuery.list();
return list;
}

service层拿到Dao层的数据,判断是否是本年度的,如果是本年度的,那么还没有到的月份的数据就设置为”“,如果已经过的了月份,如果没有数据就设置为0.

返回一个List集合嵌套着Map集合,就可以给前台解析了。


@Override
public List getAnnualStatisticByYear(int year) { List<Object[]> annualStatisticByYear = complainDao.getAnnualStatisticByYear(year); List<Map> returnList = new ArrayList<>(); //得到本年度和本月份
int curYear = Calendar.getInstance().get(Calendar.YEAR);
//Calerdar月份从0开始,
int curMonth = Calendar.getInstance().get(Calendar.MONTH)+1; //使用Map集合装载着数据
Map<String,Object> map = null;
for (Object[] objects : annualStatisticByYear) {
map = new HashedMap();
//得到月份
Integer month = Integer.valueOf(objects[0] + "");
map.put("label", month + "月");
if (curYear == year) { //是本年度,那么看看月份是否大于本月份
if (month > curMonth) {
//将数据设置为""
map.put("value", "");
} else {
if (objects[1] != null) {
map.put("value", objects[1]);
} else {
map.put("value", "0");
}
}
}else {//不是本年度
if (objects[1] != null) {
map.put("value", objects[1]);
} else {
map.put("value", "0");
}
}
returnList.add(map);
}
return returnList;
}

action层把service层的数据封装到Map集合中,嵌套ajax解析Map集合,得到的就是对象数组了。


//返回JSON格式的数据,这里我们就直接用Struts2框架来返回对应的数据就行了。
public String getAnnualStatisticData() { //获取用户传递过来的年份
String str_year = ServletActionContext.getRequest().getParameter("year");
if (str_year != null) {
int year = Integer.valueOf(str_year);
//根据年份去获取每个月的投诉数
map.put("msg", "success");
map.put("chartData", complainServiceImpl.getAnnualStatisticByYear(year));
}
return "getAnnualStatisticData";
}

前台把年份提交给Action,解析出后台返回的数据,渲染成折线图….


function doAnnualStatistic() {
//获取当前年份
var $year = $("#year option:selected").val(); //一进来,如果没有选择任何的年数,就显示当前年份的
if($year=="" || $year==undefined) {
$year = "${year}";
}
//2、统计年度投诉数据并展示图表
$.ajax({
url: "${basePath}complain/complain_getAnnualStatisticData.action",
type: "post",
dataType: "json",
data: {"year":$year},
success: function (backData) {
if(backData!=null && backData!=""){
var revenueChart = new FusionCharts({
"type": "line",
"renderAt": "chartContainer",
"width": "600",
"height": "400",
"dataFormat": "json",
"dataSource": {
"chart": {
"caption": "年度统计投诉数",
"xAxisName": "月 份",
"yAxisName": "投 诉 数",
"theme": "fint"
},
"data":backData.chartData
}
});
revenueChart.render();
}
},
error:function () {
alert("统计投诉数失败!");
}
});
}

纳税服务系统【统计图Fusionchart】的更多相关文章

  1. 纳税服务系统【信息发布管理、Ueditor、异步信息交互】

    需求分析 我们现在来到了纳税服务系统的信息发布管理模块,首先我们跟着原型图来进行需求分析把: 一些普通的CRUD,值得一做的就是状态之间的切换了.停用和发布切换. 值得注意的是:在信息内容中,它可以带 ...

  2. 纳税服务系统【异常处理、抽取BaseAction】

    前言 本博文主要讲解在项目中异常是怎么处理的.一般我们都不会直接把后台异常信息返回给用户,用户是看不懂的.让用户看见一大串的错误代码,这是不合理的.因此我们需要对报错进行处理. 我们在开发的时候是使用 ...

  3. 纳税服务系统【自动受理,Quartz任务调度】

    需求 回到我们的需求: 自动投诉受理:在每个月月底最后一天对本月之前的投诉进行自动处理:将投诉信息的状态改为 已失效.在后台管理中不能对该类型投诉进行回复. 这个需求需求我们要怎么弄呢????要在每个 ...

  4. 纳税服务系统【抽取BaseService、条件查询】

    抽取BaseService 到目前为止,我们已经写了三个模块的开发了.我们已经抽取过了BaseAction.BaseDao,我们这次来看看我们的Service接口. UserService /** * ...

  5. 纳税服务系统【用户模块之使用POI导入excel、导出excel】

    前言 再次回到我们的用户模块上,我们发现还有两个功能没有完成: 对于将网页中的数据导入或导出到excel文件中,我们是完全没有学习过的.但是呢,在Java中操作excel是相对常用的,因此也有组件供我 ...

  6. IT服务系统组成

    软件+硬件+数据 + 运维人员 = IT服务系统 车 司机 乘客 修车 = 车模式 效率 系统 用户 业务 运维 = 信息化 效率 如果司机不会开车,没有人会修车就不会有车轮上的世界 同样没有人会运维 ...

  7. 01——Solr学习之全文检索服务系统的基础认识

    一.为什么要用Solr,Solr是个什么东西? 1.1.Solr是个开源的搜索服务器 1.2.我们用Solr主要实现搜索功能,一般的网站首页都会有一个大大的搜索框,用来搜索此网站上的商品啊什么的,如下 ...

  8. 基于Spring Boot、Spring Cloud、Docker的微服务系统架构实践

    由于最近公司业务需要,需要搭建基于Spring Cloud的微服务系统.遍访各大搜索引擎,发现国内资料少之又少,也难怪,国内Dubbo正统治着天下.但是,一个技术总有它的瓶颈,Dubbo也有它捉襟见肘 ...

  9. SpringCloud(9)使用Spring Cloud OAuth2保护微服务系统

    一.简介 OAth2是一个标准的授权协议. 在认证与授权的过程中,主要包含以下3种角色. 服务提供方 Authorization Server. 资源持有者 Resource Server. 客户端 ...

随机推荐

  1. How to make sure your machine is always online without sleep

    1. Create a "NeverOff" power plan: Control Panle->System and Security->Power Options ...

  2. python web入门程序

    python2.x web入门程序 #!/usr/bin/python # -*- coding: UTF-8 -*- # 只在python2.x 有效 import os #Python的标准库中的 ...

  3. 【Win10】zip安装MySQL

    1. mysqld初始化时my.ini的第二个默认位置是%windir%/my.ini rem 1.查看此变量对应的目录,在此目录下编辑 my.ini,mysqld会自动找到 echo %WINDIR ...

  4. mysql 数据库选定 创建 删除 变更

    use db_name select * from db_name.tbl_name 显示所有数据库 mysql> select schema_name from information_sch ...

  5. 80C51学习 流水灯

    /* c语言常用预处理命令 1.#define使用 #define A PO 后面不用加分号. #define PI 3.14 2.循环左移右移函数 _crol_(a,b)循环左移函数,a是左移的值, ...

  6. Java重载重写与实现方法的规则

    这几天在实训过程中做到了一个题,这个题目问的是 非抽象类实现接口后,必须实现接口中的所有抽象方法,除了abstract外,方法头必须完全一致.这句话是错误的.然后在做错以后自己总结一下重载 重写 和实 ...

  7. Servlet---基础、转发重定向、编码问题解析

    servlet   是运行在服务器端的三大web组件之一 [web三大组件:Servlet  Filter   Listener]      是处理客户端请求的 还有表单提交的请求         接 ...

  8. NPOI office 组件资料汇总 (excel, word)

    POI 是一套用Java写成的库,能够帮助开发者在没有安装微软Office的情况下读写Office 的文件,支持的文件格式包括xls, doc, ppt等. NPOI 是POI的.net 版本. 最新 ...

  9. IntelliJ IDEA使用(一)基本设置与类、方法模板设置

    其实之前一直开发都是在使用的是Eclipse,但是最近在做Maven项目的时候要用IntelliJ IDEA,据说这个idea功能非常的强大,最近在使用的时候发现如果适应的真的是非常的强大.感觉是比E ...

  10. [转载]webarchive文件转换成htm文件

    原文地址:webarchive文件转换成htm文件作者:xhbaxf Mac OS X系统带有文件转换功能,可以把webarchive文件变成html文件.方法是:   Step 1: 建立一个文件夹 ...