当前位置:   article > 正文

家庭财务管理系统实战6-使用Highcharts插件动态展示支出趋向图饼图(pie)和线图(line)_支出趋势图

支出趋势图

本篇用highcharts控件展示支出去向图和支出趋势图。

研究了一阵儿,控件挺好用的,而且效果也不错。

本篇实现家庭财务管理系统首页的展示,参考了一下“随手记”,打算在首页展示以下内容:

1.收支表

收入情况:本周收入,本月收入,本年收入;

支出情况:本周支出,本月支出,本年支出。

2.当月支出去向图,以饼图展示各种类型的支出情况。

3.当月支出趋势图,以线图展示当月每天的支出情况。

首先看1的实现,controller代码如下:

  1. @RequestMapping("/payincome.do")
  2. @ResponseBody
  3. public Object getPayincomeData()
  4. {
  5. Calendar cal = Calendar.getInstance();
  6. int year = cal.get(Calendar.YEAR);
  7. int month = cal.get(Calendar.MONTH) + 1;
  8. String monday = this.getCurrentMonday();
  9. String sunday = this.getPreviousSunday();
  10. String stryear = String.valueOf(year);
  11. String strmonth = stryear + String.valueOf(month);
  12. List<Map<String,String>> result = this.commonService.getPayincomeData(stryear,strmonth,monday,sunday);
  13. return result;
  14. }

统计本月本年的数据好说,sql中like '201301%'、like ‘2013%’就可以了,统计本周的数据则要拿到本周一到周日的日期,获取本周一周日的代码如下,网上找的:

  1. // 获得当前日期与本周一相差的天数
  2. private int getMondayPlus()
  3. {
  4. Calendar cd = Calendar.getInstance();
  5. // 获得今天是一周的第几天,星期日是第一天,星期二是第二天......
  6. int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK);
  7. if (dayOfWeek == 1)
  8. {
  9. return -6;
  10. } else
  11. {
  12. return 2 - dayOfWeek;
  13. }
  14. }
  15. // 获得当前周- 周一的日期
  16. private String getCurrentMonday()
  17. {
  18. int mondayPlus = getMondayPlus();
  19. GregorianCalendar currentDate = new GregorianCalendar();
  20. currentDate.add(GregorianCalendar.DATE, mondayPlus);
  21. Date monday = currentDate.getTime();
  22. DateFormat df = new SimpleDateFormat("yyyyMMdd");
  23. String preMonday = df.format(monday);
  24. return preMonday;
  25. }
  26. // 获得当前周- 周日 的日期
  27. private String getPreviousSunday()
  28. {
  29. int mondayPlus = getMondayPlus();
  30. GregorianCalendar currentDate = new GregorianCalendar();
  31. currentDate.add(GregorianCalendar.DATE, mondayPlus + 6);
  32. Date monday = currentDate.getTime();
  33. DateFormat df = new SimpleDateFormat("yyyyMMdd");
  34. String preMonday = df.format(monday);
  35. return preMonday;
  36. }

参数都准备好了,下面看service的代码:

  1. public List<Map<String, String>> getPayincomeData(String stryear, String strmonth, String monday, String sunday)
  2. {
  3. List<Map<String,String>> result = new ArrayList<Map<String,String>>();
  4. Map<String,String> map = new HashMap<String,String>();
  5. map.put("paymenttype", "1");
  6. map.put("monday", monday);
  7. map.put("sunday", sunday);
  8. Integer week1 = dao.getWeekSum(map);
  9. map.put("paymenttype", "2");
  10. Integer week2 = dao.getWeekSum(map);
  11. map = new HashMap<String,String>();
  12. map.put("paymenttype", "1");
  13. map.put("day", strmonth+"%");
  14. Integer month1 = dao.getMonthSum(map);
  15. map.put("paymenttype", "2");
  16. Integer month2 = dao.getMonthSum(map);
  17. map = new HashMap<String,String>();
  18. map.put("paymenttype", "1");
  19. map.put("day", stryear+"%");
  20. Integer year1 = dao.getMonthSum(map);
  21. map.put("paymenttype", "2");
  22. Integer year2 = dao.getMonthSum(map);
  23. Map<String,String> data1 = new HashMap<String,String>();
  24. data1.put("type", "收入");
  25. data1.put("week", week1 == null?"0":week1.toString());
  26. data1.put("month", month1 == null?"0":month1.toString());
  27. data1.put("year", year1 == null?"0":year1.toString());
  28. result.add(data1);
  29. data1 = new HashMap<String,String>();
  30. data1.put("type", "支出");
  31. data1.put("week", week2 == null?"0":week2.toString());
  32. data1.put("month", month2 == null?"0":month2.toString());
  33. data1.put("year", year2 == null?"0":year2.toString());
  34. result.add(data1);
  35. return result;
  36. }

两种数据:收入和支出,paymenttype=1是收入,paymenttype=2是支出,上面代码将周月年的收入支出都统计了一遍,下面是mapper.xml内容:

  1. <select id="getWeekSum" parameterType="Map" resultType="Integer">
  2. <![CDATA[
  3. select SUM(value) from payments
  4. where paymenttype = #{paymenttype} and day >= #{monday} and day <= #{sunday}
  5. ]]>
  6. </select>
  7. <select id="getMonthSum" parameterType="Map" resultType="Integer">
  8. <![CDATA[
  9. select SUM(value) from payments
  10. where paymenttype = #{paymenttype} and day like #{day}
  11. ]]>
  12. </select>

<![DATA]]里面的内容表示不是xml标记,如果不加这个,它会把sql里的<号当成xml标记。

下面看2、3的实现:

2、3主要是要获取饼状图和线图的数据,在后台将数据准备好:

  1. @RequestMapping("/getMonthSumByType.do")
  2. @ResponseBody
  3. public Object getMonthSumByType()
  4. {
  5. Calendar cal = Calendar.getInstance();
  6. int year = cal.get(Calendar.YEAR);
  7. int month = cal.get(Calendar.MONTH) + 1;
  8. String strmonth = String.valueOf(year) + String.valueOf(month);
  9. int days = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
  10. Map<String,String> ret = this.commonService.getMonthSumByType(strmonth,days);
  11. return ret;
  12. }

getMonthSumByType方法将获取本月的分类支出数据,和本月每天的支出情况,需要两个参数,strmonth:本月月份(201301类似),days:本月有多少天(一个sql应该能统计一个月内每天的支出情况,没想出来怎么写,就用了笨方法,一天一天的取出来的。)。

getMonthSumByType方法如下:

  1. public Map<String, String> getMonthSumByType(String month,int days)
  2. {
  3. Map<String,String> retmap = new HashMap<String,String>();
  4. List<Map> list = this.dao.getMonthSumByType(month + "%");
  5. String data = "[{name:'花费',data:[";
  6. for (Map m:list)
  7. {
  8. String temp = "['%s',";
  9. data += String.format(temp, m.get("typename"));
  10. temp = "%s],";
  11. data += String.format(temp, m.get("value"));
  12. }
  13. if (data.length() > 18)
  14. data = data.substring(0, data.length() - 1);
  15. data += "]}]";
  16. retmap.put("data1", data);
  17. data = "[{name:'日期',data:[";
  18. String beginday = month + "01";
  19. int ibeginday = Integer.parseInt(beginday);
  20. for (int i = 0; i < days; i++)
  21. {
  22. String temp = String.valueOf(ibeginday + i);
  23. Integer value = this.dao.getDayValue(temp);
  24. data += String.format("['%d号',", Integer.parseInt(temp.substring(6)));
  25. data += String.format("%s],", value == null?"0":value.toString());
  26. }
  27. if (data.length() > 18)
  28. data = data.substring(0, data.length() - 1);
  29. data += "]}]";
  30. retmap.put("data2", data);
  31. return retmap;
  32. }

上面准备了两组数据,data1是饼图数据类似:[{name:'花费',data:[[‘买菜’,100],['房租',10000],['买衣服',1000]]}],data2是线图的数据,类似:[{name:'日期',data:[[‘1号’,100],[‘2号’,100],[‘3号’,100]]}],具体格式可去highcharts查文档。

两个dao方法对应的mapper.xml内容如下:

  1. <select id="getMonthSumByType" parameterType="String" resultType="java.util.HashMap">
  2. SELECT typename,SUM(VALUE) AS value FROM vpayments WHERE paymenttype = '2' and day like #{month} GROUP BY TYPE
  3. </select>
  4. <select id="getDayValue" parameterType="String" resultType="Integer">
  5. select sum(value) from payments where day = #{day}
  6. </select>

下面看首页的jsp代码:

  1. <%@ page language="java" contentType="text/html; charset=utf-8"
  2. pageEncoding="UTF-8"%>
  3. <%
  4. String path = request.getContextPath();
  5. String basePath = request.getScheme() + "://"
  6. + request.getServerName() + ":" + request.getServerPort()
  7. + path ;
  8. %>
  9. <script>
  10. $(function(){
  11. $('#datagrid_payincome').datagrid({//收支表
  12. title:'收支表',
  13. url:'<%=basePath%>/payincome.do',
  14. border:false,
  15. height:105,
  16. columns:[[
  17. {field:'type',title:'类型',width:250,
  18. styler: function(value,row,index){
  19. if (index == 0)
  20. return 'color:red;';
  21. else
  22. return 'color:blue;';
  23. }
  24. },
  25. {field:'week',title:'本周',width:250,
  26. styler: function(value,row,index){
  27. if (index == 0)
  28. return 'color:red;';
  29. else
  30. return 'color:blue;';
  31. }},
  32. {field:'month',title:'本月',width:250,
  33. styler: function(value,row,index){
  34. if (index == 0)
  35. return 'color:red;';
  36. else
  37. return 'color:blue;';
  38. }},
  39. {field:'year',title:'本年',width:250,
  40. styler: function(value,row,index){
  41. if (index == 0)
  42. return 'color:red;';
  43. else
  44. return 'color:blue;';
  45. }}
  46. ]]
  47. });
  48. $.ajax({
  49. type: 'POST',
  50. url: '<%=basePath%>/getMonthSumByType.do',//请求饼图和线图数据
  51. data: '',
  52. dataType:'text',
  53. success: function(msg){
  54. var temp = $.parseJSON(msg);
  55. createChart('zcqxt','本月支出去向图',eval(temp.data1),'pie',350,390,'元');
  56. createChart('zcqst','本月支出趋势图',eval(temp.data2),'line',360,950,'元');
  57. }
  58. });
  59. });
  60. </script>
  61. <div id="layout" class="easyui-layout" data-options="fit:true">
  62. <div data-options="region:'north',split:true,border:false" style="height:110px">
  63. <table id="datagrid_payincome"></table>
  64. </div>
  65. <div data-options="region:'west',split:true,border:false" style="width:400px">
  66. <div id="zcqxt"></div>
  67. </div>
  68. <div data-options="region:'center',border:false">
  69. <div id="zcqst"></div>
  70. </div>
  71. </div>

createChart代码:

  1. function createChart(container,title,yaxisData,chartType,height,width,unit)
  2. {
  3. options = {
  4. chart: {
  5. renderTo: container,
  6. type: chartType,
  7. height:height,
  8. width:width
  9. },
  10. title: {
  11. text: title,
  12. },
  13. xAxis: {
  14. categories: []
  15. },
  16. yAxis: {
  17. min: 0,
  18. title: {
  19. text: '花费'
  20. }
  21. },
  22. tooltip: {
  23. formatter: function() {
  24. return ''+ this.key +': '+this.y + unit;
  25. }
  26. },
  27. plotOptions: {
  28. series: {
  29. allowPointSelect: true
  30. }
  31. },
  32. series: []
  33. };
  34. //options.xAxis.categories = xaxisData;
  35. options.series = yaxisData;
  36. var chart = new Highcharts.Chart(options);
  37. return chart;
  38. }

highcharts可去官网看文档,这里只是粗略实现。

下面看截图:



声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/270658
推荐阅读
  

闽ICP备14008679号