首先介绍项目背景:
把如下图所示,把这个做成表格然后打印出来。
点击显示图表出现如图以下的界面:
1、首先导入echarts所需要的js文件,css文件。
将echarts所需要的东西考进来(图上的js文件并不是所有的都需要。)
2、引入以下文件
<title>药品统计</title>
<!--ico图标-->
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="content-type" content="text/html; charset=UTF-8"> -->
<%@ include file="/common/common_css.jsp"%>
<%@ include file="/common/common_js.jsp"%>
<script src="${baseurl}/business/analyze/js/echarts.js"></script>
<!--加载主题-->
<script src="${baseurl}/business/analyze/js/zhuti/macarons.js"></script>
<script src="${baseurl}/business/analyze/js/codemirror.js"></script>
3、js代码:
<script type="text/javascript">
function query(){
// Step:3 conifg ECharts's path, link to echarts.js from current page.
// Step:3 为模块加载器配置echarts的路径,从当前页面链接到echarts.js,定义所需图表路径
require.config({
paths: {
echarts: '/business/analyze/js'
}
});
// Step:4 require echarts and use it in the callback.
// Step:4 动态加载echarts然后在回调函数中开始使用,注意保持按需加载结构定义图表路径
require(
[
'echarts',
'echarts/chart/bar',
'echarts/chart/line'
],
function(ec) {
//--- 声明一个折柱 ---
myChart = ec.init(document.getElementById('main'), 'macarons');
initData();//加载数据
// --- 地图 ---
/* 读取数据时加载效果 */
myChart.showLoading();
initData();//加载数据
}
);
}
/* 加载数据ajax */
function initData(){
//表单参数序列化
var params = $("#drugyzreaqueryForm").serializeJson();
//刷新datagride
$("#drugyzrealist").datagrid('reload',params);
$.ajax({
type : "post",
async : false, //异步请求(同步请求将会锁住浏览器,用户其他操作必须等待请求完成才可以执行)
url : "${baseurl}/analyze/ajaxDrugyzrea_bar.action", //请求发送到TestServlet处
data : params,
dataType : "json", //返回数据形式为json
success : function(result) {
//请求成功时执行该函数内容,result即为服务器返回的json对象
//清空画布,防止缓存---------------------------------
myChart.clear();
// myChart.setOption({});//初始化数据
myChart.setOption(result);
myChart.hideLoading();
//如果不清空,图形数据将不会更改
},
error : function(errorMsg) {
//请求失败时执行该函数
alert("图表请求数据失败!");
}
})
}
</script>
4、表现层代码:
/**
* 该方法用于ajax获取药品统计数据的option
*
* @throws IOException
*/
public void ajaxDrugyzrea_bar() throws IOException {
// 创建数据承载对象
GsonOption option = new GsonOption();
// 初始化
List<Object> xAxisList = new ArrayList<>();
List<Object> barList = new ArrayList<>();
List<Object> barList2 = new ArrayList<>();
// ****准备数据,写死了二十条
List<Yybusiness> ypxxList = yybusinessService.list_drugyzrea(yybusinessVo.getYybusinessQueryCustom(), 0, 20);
if (ypxxList!=null) {
for (Yybusiness yybusiness : ypxxList) {
xAxisList.add(yybusiness.getYpxx().getMc());
barList.add(yybusiness.getCgl());
BigDecimal cgjeBig = new BigDecimal(yybusiness.getCgje());
cgjeBig = cgjeBig.setScale(2, BigDecimal.ROUND_HALF_UP);
barList2.add(cgjeBig.doubleValue());
}
// ******设置基本属性*******start
// 设置标题和子标题(子标题即主标题下的小文字说明)
option.title().text("药品采购数据统计").subtext("一组");
// 设置鼠标移入数据柱中提示框,可自行设置
option.tooltip().trigger(Trigger.axis);
// 添加图标图例,每个图标仅可有一个图例(就是统计图上方的统计说明)
option.legend("采购量", "采购金额");
option.toolbox().show(true).feature(Tool.mark, Tool.dataView, new MagicType(Magic.line, Magic.bar).show(true),
Tool.restore, Tool.saveAsImage);
// 设置calculable值,该值是什么?不知道
option.calculable(true);
option.xAxis(new CategoryAxis().data(xAxisList.toArray()));
// yAxis:即y轴需要显示的数据,简单来说就是数据的数值,如果直接new ValueAxis()
// 应该是根据数据的需求进行自动显示
option.yAxis(new ValueAxis());
Bar bar = new Bar("采购量");
// data:就是该bar的数据,需要和上面的城镇名称进行对应
bar.data(barList.toArray());
// 设置标注,markPoint是一个标注对象,支持链式编程,可以直接设置值,很多特效可以在这里设置
bar.markPoint().data(new PointData().type(MarkType.max).name("最大值"),
new PointData().type(MarkType.min).name("最小值"));
// 设置标线,也就是横穿数据柱的一条线,代表的是平均值,详情请看MarkType对象
bar.markLine().data(new PointData().type(MarkType.average).name("平均值"));
Bar bar2 = new Bar("采购金额");
// data:就是该bar的数据,需要和上面的城镇名称进行对应
bar2.data(barList2.toArray());
// 设置标注,markPoint是一个标注对象,支持链式编程,可以直接设置值,很多特效可以在这里设置
bar2.markPoint().data(new PointData().type(MarkType.max).name("最大值"),
new PointData().type(MarkType.min).name("最小值"));
// 设置标线,也就是横穿数据柱的一条线,代表的是平均值,详情请看MarkType对象
bar2.markLine().data(new PointData().type(MarkType.average).name("平均值"));
option.series(bar, bar2);
}else {
option.setNoDataLoadingOption(new NoDataLoadingOption().text("无数据"));
}
getResponse().setContentType("text/html;charset=utf-8");
getResponse().getWriter().write(option.toString());
}
5、业务层代码:
@Override
// 查询所有药品采购详情统计
public List<Yybusiness> list_drugyzrea(YybusinessQueryCustom yybusinessQueryCustom, Integer firstResult,
Integer maxResults) {
// 防止空指针异常
if (yybusinessQueryCustom == null) {
yybusinessQueryCustom = new YybusinessQueryCustom();
yybusinessQueryCustom.setStartDate("");
yybusinessQueryCustom.setEndDate("");
}
// 处理分页
// 在shiro中获得用户
ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
// 获取用的分组信息 判断是供应商还是卫生院还是,卫生室
String groupid = activeUser.getGroupid();
if (yybusinessQueryCustom != null && (groupid.equals("s0101") || groupid.equals("s0102"))) {
// 通过id查询到对应的单位信息
DwWsy dwWsy = dwWsyDao.findById(activeUser.getSysid());
// 获取到单位的信息 ,然后通过单位信息获取到地区对应的id
String sysWsyId = dwWsy.getId();
yybusinessQueryCustom.getDwWsy().setId(sysWsyId);
} else {
ResultUtil.throwExcepionResult("对不起,你没有访问权限");
}
// 此map是从数据库查询出来的值,在Service层转换为对象后返回Action
List<Map<String, Object>> reslutMap = yybusinessDao.list_drugyzrea(yybusinessQueryCustom, firstResult,
maxResults);
List<Yybusiness> reslutList = new ArrayList<>();
for (Map<String, Object> map : reslutMap) {
// 处理
Yybusiness yybusiness = new Yybusiness();
// 流水号
Ypxx ypxx = new Ypxx();
ypxx.setBm((String) map.get("BM"));
// 药品名称
ypxx.setMc((String) map.get("MC"));
yybusiness.setYpxx(ypxx);
// 采购量
Number cgl = (Number) map.get("CGL");
yybusiness.setCgl(cgl.intValue());
// 采购金额
Number cgje = (Number) map.get("CGJE");
yybusiness.setCgje(cgje.floatValue());
reslutList.add(yybusiness);
}
return reslutList;
}
6、Dao层代码:
@Override
// 查询所有药品采购信息
public List<Map<String, Object>> list_drugyzrea(YybusinessQuery yybusinessQuery, Integer firstResult,
Integer maxResults) {
Session session = this.getSessionFactory().getCurrentSession();
StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.append("select xx.BM,xx.MC,sum(xx.cgl) cgl,sum(xx.cgje) cgje ");
sqlBuilder.append(" from (select yy.*,yx.* ");
sqlBuilder.append(" from YYBUSINESS yy,YPXX yx,(select ws.id ");
sqlBuilder.append(
"from DW_WSS ws,(select * from DW_WSY wy ");
if (yybusinessQuery.getDwWsy() != null) {
sqlBuilder.append(" where id = '"+ yybusinessQuery.getDwWsy().getId() + "' ");
}
sqlBuilder.append(" ) za ");
sqlBuilder.append(" where ws.dq like za.dq||'%') wss ");
sqlBuilder.append(" where yy.WSS_ID in(wss.id) ");
sqlBuilder.append(" and YX.ID = YY.YPXX_ID ");
// 及订单受理完成的---------------------------------------
sqlBuilder.append(" and yy.cgzt = '01102' ");
// ---------------------------------------------------------------------
sqlBuilder.append(" ) xx ");
sqlBuilder.append(" where 1=1 ");
// 拼凑时间条件, 有四种情况 开始时间输入,结束时间未输入;开始时间未输入,结束时间输入 ;两个都输入;两个都没有输入.
if (yybusinessQuery != null) {
if (yybusinessQuery.getStartDate() != null && !yybusinessQuery.getStartDate().equals("")) {
// 如果两个都输入了
if (!yybusinessQuery.getEndDate().equals("")) {
sqlBuilder.append(" and to_char(tjsj,'yyyy-mm-dd') between '" + yybusinessQuery.getStartDate()
+ "' and '" + yybusinessQuery.getEndDate() + "' ");
} else {// 说明没有输入结束时间
sqlBuilder.append(" and to_char(tjsj,'yyyy-mm-dd') >= '" + yybusinessQuery.getStartDate() + "'");
}
} else {// 说明 没有输入开始时间
// 如果输入了结束时间
if (yybusinessQuery.getEndDate() != null && !yybusinessQuery.getEndDate().equals("")) {
sqlBuilder.append(" and to_char(tjsj,'yyyy-mm-dd') <= '" + yybusinessQuery.getEndDate() + "'");
}
}
}
sqlBuilder.append(" GROUP BY xx.bm,xx.MC order by cgje desc ");
List<Map<String, Object>> list = session.createSQLQuery(sqlBuilder.toString()).setFirstResult(firstResult)
.setMaxResults(maxResults).setResultTransformer(Transformers.aliasToBean(HashMap.class)).list();
DetachedCriteria dc = DetachedCriteria.forClass(Yybusiness.class);
return list;
}
小结:
虽然业务很复杂,Echarts也是刚接触的,但是最后还是研究通了。看看代码量就知道含量了。