时间作为横轴的图表(morris.js)超越昨天的自己系列(8)
超越昨天的自己系列(8)
morris.js的官网有详细的例子:http://www.oesmith.co.uk/morris.js/
特别注意它的依赖:
<link rel="stylesheet" href="http://cdn.oesmith.co.uk/morris-0.4.3.min.css"> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script> <script src="http://cdn.oesmith.co.uk/morris-0.4.3.min.js"></script>
放个div:
<div class="graph-container"> 20天内用户增长数量 <div id="examplefirst" class="graph" style="position: relative;"> <div id="myfirstchart" style="height: 250px;"></div> </div> </div>
script:
<script > // 后台传来的数据 var data = '$data'; data = data.replace(/"/g, '"'); var array = eval(data); new Morris.Line({ xLabels: "day", // ID of the element in which to draw the chart. element: 'myfirstchart', // Chart data records -- each entry in this array corresponds to a point on // the chart. data: array, // The name of the data record attribute that contains x-values. xkey: 'year', // A list of names of data record attributes that contain y-values. ykeys: ['value'], // Labels for the ykeys -- will be displayed when you hover over the // chart. labels: ['Value'] }); </script>
就可以展示啦~ 只要注意插件中参数data是个数组即可。
后台传来的数据类似:
[ { year: '2008', value: 20 }, { year: '2009', value: 10 }, { year: '2010', value: 5 }, { year: '2011', value: 5 }, { year: '2012', value: 20 } ]
所以后台的查询我做成了循环查询的方式,本人觉得一定是有更优的方式能够一次查出全部需求数据。先看下实现(hibernate):
action处理:注意循环部分的查询,每次只查一天内的量,如果数量过多可能会影响数据库性能
// y轴末尾时间 时间处理成: 20130201 23:59:59:999 Date endDate = WXDateUtil.getTodayLastTime(); // y轴开始时间 默认20天前到现在 Date beginDate = WXDateUtil.getBeforeDays(endDate, 20); // y轴上时间点列表 List<Date> dateList = new ArrayList<Date>(); // 先放开始时间 Date midDate = beginDate; while(endDate.after(midDate)){ dateList.add(midDate); // 下一天 midDate = WXDateUtil.getNextDay(midDate); } // 再放结束时间 dateList.add(endDate); JSONArray array = new JSONArray(); if(dateList.size() > 0){ for (int i = 0; i < dateList.size() - 1; i++) { long count = clientService.getCountByTypeAndTime(0, dateList.get(i), dateList.get(i+1)); JSONObject object = new JSONObject(); object.put("year", WXDateUtil.dateToStr(dateList.get(i+1), "yyyy-MM-dd" )); object.put("value", count); array.add(object); } } context.put("data", array.toJSONString());
时间处理 Util的包:
public class WXDateUtil { private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd"; /** * 把日期型转换成字符串形式。 * * @param date 日期 * @param dateFormat 日期格式,例如"yyyy/MM/dd"、"yyyy年MM月dd" * @return 日期字符串 */ public static String toLocaleString(Date date, String dateFormat) { if (date == null) { return ""; } if (StringUtil.isBlank(dateFormat)) { return new SimpleDateFormat(DEFAULT_DATE_FORMAT).format(date); } return new SimpleDateFormat(dateFormat).format(date); } /** * 把日期型转换成"yyyy/MM/dd/"字符串形式。 * * @param date * @return 日期字符串 */ public static String toLocaleString(Date date) { return toLocaleString(date, null); } /** * 获得sysdate+hours后的时间 * * @param hours 提前或者推后的时间 * @return sysdate+hours后的时间 */ public static Date getSysDate(int hours) { Calendar time = Calendar.getInstance(); time.add(Calendar.HOUR, hours); return time.getTime(); } /** * 方法说明:天数差 * * @param firstDate * @param lastDate */ public static int getTimeIntervalDays(Date firstDate, Date lastDate) { long intervals = lastDate.getTime() - firstDate.getTime() + (60 * 1000); if (intervals > 0) { long daysd = intervals / (24 * 60 * 60 * 1000); return new Long(daysd).intValue(); } return 0; } /** * 方法说明:小时差 * * @param firstDate * @param lastDate */ public static int getTimeIntervalHours(Date firstDate, Date lastDate) { long intervals = lastDate.getTime() - firstDate.getTime() + (60 * 1000); if (intervals > 0) { long longHours = (intervals / (60 * 60 * 1000)) % 24; return new Long(longHours).intValue(); } return 0; } /** * 方法说明:分钟差 * * @param firstDate * @param lastDate */ public static int getTimeIntervalMins(Date firstDate, Date lastDate) { long intervals = lastDate.getTime() - firstDate.getTime() + (60 * 1000); if (intervals > 0) { long longMins = (intervals / (60 * 1000)) % 60; return new Long(longMins).intValue(); } return 0; } /** * 方法说明:parse date * * @param date * @param dateformat */ public static Date parseDate(String date, String dateformat) { SimpleDateFormat sdf = new SimpleDateFormat(dateformat); try { return sdf.parse(date); } catch (ParseException e) { return null; } } /** * 比较日期是否大于当前日期 */ public static boolean afterNow(Date date) { if (date == null) { return false; } Calendar nowCar = Calendar.getInstance(); Calendar car = Calendar.getInstance(); car.setTime(date); return car.after(nowCar); } /* * 查看是否早几天 */ public static boolean afterDays(Date date, int day) { if (date == null) { return false; } Calendar levelDay = Calendar.getInstance(); Calendar createDay = Calendar.getInstance(); createDay.setTime(date); createDay.add(Calendar.DATE, day); if (createDay.after(levelDay)) { return true; } else { return false; } } public static String getIconPathDay(){ GregorianCalendar now; String year, day, month, hour; now = new GregorianCalendar(); year = String.valueOf(now.get(Calendar.YEAR)); month = (now.get(Calendar.MONTH) + 1) < 10 ? "0" + String.valueOf(now.get(Calendar.MONTH) + 1) : String.valueOf(now.get(Calendar.MONTH) + 1); day = String.valueOf(now.get(Calendar.DAY_OF_MONTH)); StringBuilder sb = new StringBuilder(); sb.append(year).append("/"); sb.append(month).append("/"); sb.append(day).append("/"); return sb.toString(); } /* * 查看是否早几小时 */ public static boolean afterHours(Date date, int hours) { if (date == null) { return false; } Calendar levelDay = Calendar.getInstance(); Calendar createDay = Calendar.getInstance(); createDay.setTime(date); createDay.add(Calendar.HOUR, hours); if (createDay.after(levelDay)) { return true; } else { return false; } } /** * 取得系统当前日期 */ public static Date getCurrentTime() { return new Date(); } /** * 返回多少时间的前的时间, seconds 可以是负的 * * @param when * @param seconds */ public static Date addTime(Date when, int seconds) { Calendar c = Calendar.getInstance(); c.setTime(when); c.add(Calendar.SECOND, seconds); return c.getTime(); } /** * @param date * @param pattern "yyyy-MM-dd HH:mm:ss.SSS" * @return */ public static String dateToStr(Date date, String pattern) { if (pattern == null) { pattern = "yyyy-MM-dd HH:mm:ss.SSS"; } DateFormat ymdhmsFormat = new SimpleDateFormat(pattern); return ymdhmsFormat.format(date); } /** * @param str * @param pattern "yyyy-MM-dd HH:mm:ss.SSS" * @return * @throws ParseException */ public static Date strToDate(String str, String pattern) { if (pattern == null) { pattern = "yyyy-MM-dd HH:mm:ss.SSS"; } DateFormat ymdhmsFormat = new SimpleDateFormat(pattern); try { return ymdhmsFormat.parse(str); } catch (ParseException e) { return null; } } /** * 获得当天日期 * * @date 2009-2-20 */ public static Date getToday() { Calendar ca = Calendar.getInstance(); return ca.getTime(); } /** * @date 2009-2-20 */ public static Date mkDate(int year, int month, int date) { Calendar ca = Calendar.getInstance(); ca.set(year, month - 1, date); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); sdf.format(ca.getTime()); return ca.getTime(); } /** * <li></li> * * @param date1 * @param date2 <li></li> */ public static boolean compareTwoDate(Date date1, Date date2) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd HH:mm"); return simpleDateFormat.format(date1).equals(simpleDateFormat.format(date2)); } /** * <li></li> * * @param date1 * @param date2 <li></li> */ public static boolean compareTwoDateDay(Date date1, Date date2) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd"); return simpleDateFormat.format(date1).equals(simpleDateFormat.format(date2)); } /** * 通过文件路径获取文件名,类似Linux下basename命令 * @param path * @return */ public static String getFileName(String path){ String str[] = path.split("/"); return str[str.length-1]; } /** * 取得今天最后时间的Date * @return 23:59:59 */ public static Date getTodayLastTime(){ Calendar cal = Calendar.getInstance(); // represents right now, i.e. today's date cal.set(Calendar.HOUR_OF_DAY, 23); cal.set(Calendar.MINUTE, 59); cal.set(Calendar.SECOND, 59); cal.set(Calendar.MILLISECOND, 999); // credit to f1sh return cal.getTime(); } /** * 指定日期向后推几天的日期 * @param date * @param n 天数 * @return */ public static Date getBeforeDays(Date date, int n){ Long dateTime = date.getTime() - n*24*60*60*1000; return new Date(dateTime); } /** * 指定日期向后推1天的日期 * @param date * @return */ public static Date getNextDay(Date date){ Long dateTime = date.getTime() + 24*60*60*1000; return new Date(dateTime); } /** * * @param args */ public static void main(String[] args) { System.out.println(getToday()); } }
然后了解下hibernate查询count的方式:
参考了:http://stackoverflow.com/questions/1372317/how-do-we-count-rows-using-hibernate
例子:
public long getCountByTypeAndTime(int type, Date beginTime, Date endTime) { Criteria criterion = this.getSession().createCriteria(ClientDO.class); if(type!= 0){ criterion.add(Restrictions.eq("type", type)); } if (beginTime != null) { criterion.add(Restrictions.ge("createTime", beginTime)); } if (endTime != null) { criterion.add(Restrictions.le("createTime", endTime)); } return (Long)criterion.setProjection(Projections.rowCount()).uniqueResult(); }