Echarts -- 條件查詢ajax動態獲取資料
最近因為需要用到了Echarts這個外掛,下面是自己的一點使用心得
效果圖:
直接上程式碼:
js:
<%@ page import="org.apache.commons.lang3.RandomStringUtils" %> <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %> <%@include file="../common/base.jsp" %> <spring:message code="ui.normal" var="normal"/> <spring:message code="ui.frozen" var="frozen"/> <spring:message code="ui.notify" var="notify"/> <spring:message code="ui.details" var="details"/> <spring:message code="ui.pay" var="pay"/> <% request.setAttribute("id0", RandomStringUtils.randomAlphabetic(8)); %> <script src="//cdn.bootcss.com/echarts/3.6.2/echarts.min.js"></script> <style> th { background-color: #d3d3d3; } </style> <div class="box"> <!-- /.box-header --> <div class="row"> <div class="col-md-10"> <div class="form-group"> <label>Mode:</label> <input type="radio" name="mode" value="0" checked>Currency <input type="radio" name="mode" value="1">Merchant <input type="radio" name="mode" value="2">Channel </div> </div> </div> <div class="row"> <div class="col-md-2"> <div class="form-group"> <label>Currency:</label> <lp:currency currencyId="currencyCode" currencyName="currencyCode" currencyClass="form-control"/> </div> </div> <div class="col-md-3"> <div class="form-group"> <label>Create Time:</label> <div class="input-group input-medium date-picker input-daterange"> <div class="input-group-addon"> <i class="fa fa-calendar"></i> </div> <input name="startDate" id="startDate" class="form-control" style="font-size: 13px;" type="text"/> <span class="input-group-addon">~</span> <input name="endDate" id="endDate" class="form-control" style="font-size: 13px;" type="text"/> </div> </div> </div> <div class="col-md-2" id="merchantQueryLabel" style="display: none"> <div class="form-group"> <label>Merchant:</label> <input type="text" name="userId" id="userId" class="form-control"> </div> </div> <div class="col-md-2" id="channelCodeQueryLabel" style="display: none"> <div class="form-group"> <label>Payment Channel:</label> <select class="form-control" name="channelCode"> <option value="">All</option> <c:forEach items="${channel}" var="channel"> <option value="${channel.orgCode}">${channel.orgCode}</option> </c:forEach> </select> </div> </div> <div class="col-md-1"> <div class="form-group"> <label> </label> <button type="button" class="form-control btn btn-info" name="search">${ ui_search }</button> </div> </div> <div class="col-md-1"> <div class="form-group"> <label> </label> <button type="button" class="form-control btn btn-info" name="export">${ ui_export }</button> </div> </div> </div> <div class="box-body"> <div id="main" style="width: 100%;height: 300px;"></div> </div> <%--<script type="script-data" class="script-data">--%> <script type="text/javascript"> /** * 查詢請求 */ $("button[name='search']").on({ click: function () { loadTable(); getCurrencyCodeList(); paymentRateDate(); } }); var results = {}; var colors = ['#000000', '#FF0000', '#44CEF6', '#A88462', '#00E500', '#FA8C35', '#789262', '#801DAE', '#6E511E', '#FF461F']; var lineStyle = function () { return { normal: { color: 0 } }; }; /** * 獲取折線圖的圖例資料(根據選擇的條件不同為幣種或商戶) */ function getCurrencyCodeList() { var mode = $("input[name='mode']:checked").val(); $.ajax({ type: "post", url: "paymentrate/getCurrencyCodeList", dataType: "json", data: { 'currencyCode': $("select[name='currencyCode']").val(), 'startDate': $("input[name='startDate']").val(), 'mode': $("input[name='mode']:checked").val(), 'endDate': $("input[name='endDate']").val(), 'userId': $("#userId").val() }, success: function (result) { if (result) { results.legends = []; /** * 獲取圖例資料放入Echarts引數legends中 */ for (var i = 0; i < result.length; i++) { if (mode === '1') { results.legends.push(result[i].userId); } else { results.legends.push(result[i].currencyCode); } initChart(results); } } } } ); } function paymentRateDate() { $.ajax({ type: "post", url: "paymentrate/paymentRateLine", dataType: "json", data: { 'currencyCode': $("select[name='currencyCode']").val(), 'startDate': $("input[name='startDate']").val(), 'mode': $("input[name='mode']:checked").val(), 'endDate': $("input[name='endDate']").val(), 'userId': $("#userId").val() }, success: function (result) { if (result) { //獲取X軸的時間資料 results.xAxis = result.xAxis; var seriesData = []; $.each(result.seriesList, function (i, series) { $.each(series, function (j, item) { var p = colors[j]; var ls = lineStyle(); ls.normal.color = p; item.lineStyle = ls; seriesData.push(item); }) }); results.series = seriesData; initChart(results); } } }); } var formatter = function (params) { var title = results.xAxis[params[0].dataIndex]; var res = title + '<br/>'; for (var i = 0; i < params.length; i++) { var source = results.series[params[i].seriesIndex].source; res += '<span style="display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:' + colors[i] + ';"></span>' + source + ' : ' + params[i].data + '<br/>'; } return res; }; var myChart = null; function initChart(data) { if (!myChart) { myChart = echarts.init(document.getElementById('main')); } var firstLegend = data.legends[0]; var option = { toolbox: { feature: { saveAsImage: { title: 'Save' } } }, legend: { show: true, data: data.legends, selected: {}, selectedMode: 'single' }, tooltip: { trigger: 'axis', axisPointer: { type: 'cross', label: { backgroundColor: '#6a7985' } }, formatter: formatter }, xAxis: { data: data.xAxis }, yAxis: { scale: true }, grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true }, series: data.series }; option.legend.selected[firstLegend] = true; for (var i = 1; i < data.legends.length; i++) { option.legend.selected[data.legends[i]] = false; } myChart.setOption(option, true); } /** * 載入收銀臺訂單表格 */ function loadTable() { $('#totalRate').text(""); var timestamp = (new Date()).valueOf(); var dataUrl = "paymentrate/queryByPage?timestamp=" + timestamp; if (table == null) { table = $('#${id0}').DataTable({ ajax: { url: dataUrl, type: 'POST', data: function (param) { param.currencyCode = $("select[name='currencyCode']").val(); param.startDate = $("input[name='startDate']").val(); param.endDate = $("input[name='endDate']").val(); param.mode = $("input[name='mode']:checked").val(); param.channelCode = $("select[name='channelCode']").val(); param.userId = $("#userId").val(); }, dataSrc: function (result) { return result.data; } }, columns: columns, paging: true, pagingType: "simple_numbers", lengthChange: true, searching: false, ordering: false, info: true, autoWidth: true, scrollX: true, scrollCollapse: true, processing: true, serverSide: true, retrieve: true }).on('draw', function () { var sumRateUrl = "paymentrate/countpayrate"; $.ajax({ url: sumRateUrl, type: 'POST', data: { currencyCode: $("select[name='currencyCode']").val(), startDate: $("input[name='startDate']").val(), endDate: $("input[name='endDate']").val(), mode: $("input[name='mode']:checked").val(), userId: $("#userId").val() }, dataType: 'json', success: function (data) { if (data.payRates != null) { $('#totalRate').text(data.payRates); } if (data.amountRates != null) { $('#totalAmountRate').text(data.amountRates); } } }); }); } else { table.ajax.reload(null, true); } } /** * 匯出CSV格式請求 */ $("button[name='export']").on({ click: function () { var url = "paymentrate/export?startDate=" + $("input[name='startDate']").val() + "&endDate=" + $("input[name='endDate']").val() + "&mode=" + $("input[name='mode']:checked").val() + "&userId=" + $("#userId").val() + "¤cyCode=" + $("select[name='currencyCode']").val(); window.open(url); } }); }); </script>
java:
@ResponseBody @RequestMapping("/getCurrencyCodeList") public String getCurrencyCodeList(Model model, PaymentRateForm form) { List<PaymentRateDO> paymentRateDOList; //根據條件查詢不同的檢視 if (StringUtils.equals(form.getMode(), "1")) { paymentRateDOList = paymentRateDAO.queryMerchantList(form.getStartDate(), form.getEndDate(), form.getCurrencyCode(), form.getUserId()); } else { paymentRateDOList = paymentRateDAO.queryCurrencyCodeList(form.getStartDate(), form.getEndDate(), form.getCurrencyCode()); } return JSON.toJSONString(paymentRateDOList); } @ResponseBody @RequestMapping("/paymentRateLine") public String paymentRateList(Model model, PaymentRateForm form) { try { List<PaymentRateDO> paymentRateDOList = new ArrayList<>(); if (StringUtils.equals(form.getMode(), "0") || StringUtils.equals(form.getMode(), "2")) { paymentRateDOList = paymentRateDAO.queryPaymentRate(form.getStartDate(), form.getEndDate(), form.getCurrencyCode()); } if (StringUtils.equals(form.getMode(), "1")) { paymentRateDOList = paymentRateDAO.queryMerchantPaymentRate(form.getStartDate(), form.getEndDate(), form.getCurrencyCode(), form.getUserId()); } ArrayList<String> stringArrayList = new ArrayList<>(); //獲取x軸資料的數量,過濾重複資料 for (PaymentRateDO paymentRateDO : paymentRateDOList) { if (!stringArrayList.contains(paymentRateDO.getCollectDate())) { stringArrayList.add(paymentRateDO.getCollectDate()); } } String[] xAxis = new String[stringArrayList.size()]; int i = 0; //構建三層樹形結構 <userId/currency,<currency,<date,paymentRate>>> Map<String, Map<String, Map<String, String>>> parentDict = new HashMap<>(); ArrayList<String> arrayList = new ArrayList<>(); //往x軸陣列中填充資料 for (PaymentRateDO paymentRateDO : paymentRateDOList) { if (!arrayList.contains(paymentRateDO.getCollectDate())) { arrayList.add(paymentRateDO.getCollectDate()); xAxis[i++] = paymentRateDO.getCollectDate(); } Map<String, Map<String, String>> dict = new HashMap<>(); //查詢條件為幣種和商戶 if (StringUtils.equals(form.getMode(), "1")) { dict = parentDict.get(paymentRateDO.getUserId()); if (dict == null) { dict = new HashMap<>(); parentDict.put(paymentRateDO.getUserId(), dict); } } //查詢條件為幣種,因暫時無法獲取渠道的支付資料,故查詢條件不考慮渠道 if (StringUtils.equals(form.getMode(), "0") || StringUtils.equals(form.getMode(), "2")) { dict = parentDict.get(paymentRateDO.getCurrencyCode()); if (dict == null) { dict = new HashMap<>(); parentDict.put(paymentRateDO.getCurrencyCode(), dict); } } Map<String, String> subDist = dict.get(paymentRateDO.getCurrencyCode()); if (subDist == null) { subDist = new HashMap<>(); dict.put(paymentRateDO.getCurrencyCode(), subDist); } //保留小數點後兩位,得到百分比 String paymentRate = String.format("%.2f", (paymentRateDO.getOrderSuccessNum().doubleValue() / paymentRateDO.getOrderCreateNum().doubleValue()) * 100); subDist.put(paymentRateDO.getCollectDate(), paymentRate); } Map<String, List<Series>> dateResult = turnToEchartsFormat(parentDict, xAxis); Map<String, Object> resultMap = new HashMap<>(); resultMap.put("xAxis", xAxis); resultMap.put("seriesList", dateResult); //如果resultMap中有值 return JSON.toJSONString(resultMap); } catch (Exception e) { log.error("query payment rate error", e); return null; } } //按照echarts需要的格式填入相應的資料 private Map<String, List<Series>> turnToEchartsFormat(Map<String, Map<String, Map<String, String>>> parentDict, String[] xAxis) { Map<String, List<Series>> dataResult = new HashMap<>(); for (Map.Entry<String, Map<String, Map<String, String>>> entry1 : parentDict.entrySet()) { Map<String, Map<String, String>> currencyMap = entry1.getValue(); List<Series> seriesList = new ArrayList<>(); dataResult.put(entry1.getKey(), seriesList); for (Map.Entry<String, Map<String, String>> entry2 : currencyMap.entrySet()) { Map<String, String> dateMap = entry2.getValue(); String[] data = new String[xAxis.length]; int i = 0; Series series = Series.build(entry1.getKey(), entry2.getKey()); //如果資料為空,則設為0 for (String str : xAxis) { String s = dateMap.get(str); data[i++] = s == null ? "0.00" : s; } series.setData(data); seriesList.add(series); } } return dataResult; } @ResponseBody @RequestMapping("/export") public String export(HttpServletResponse response, PaymentRateForm form) { try { WhereCriteria whereCriteria = buildWhereCriteria(form); Pagination page = new Pagination(); List<PaymentRateDO> paymentRateDOS = new ArrayList<>(); String mode = form.getMode(); String sTitle = ""; if (StringUtil.equals(mode, "0")) { paymentRateDOS = paymentRateDAO.findPaymentRatePage(whereCriteria); } if (StringUtil.equals(mode, "1")) { paymentRateDOS = paymentRateDAO.findMerchantPaymentRatePage(whereCriteria); sTitle = "MerchantId,"; } if (StringUtil.equals(mode, "2")) { paymentRateDOS = paymentRateDAO.findChannelPaymentRatePage(whereCriteria); sTitle = "ChannelCode,"; } sTitle += "Date,Currency,CreateNum,CreateAmount,SuccessNum,SuccessAmount,PayRate,AmountRate"; StringBuilder body = new StringBuilder(sTitle); body.append("\r\n"); NumberFormat numberFormat = NumberFormat.getInstance(); // 設定精確到小數點後2位 numberFormat.setMaximumFractionDigits(2); if (paymentRateDOS != null && !paymentRateDOS.isEmpty()) { for (PaymentRateDO paymentRateDO : paymentRateDOS) { if (StringUtil.equals(mode, "1")) { body.append("\t" + paymentRateDO.getUserId()).append(","); } if (StringUtil.equals(mode, "2")) { body.append(paymentRateDO.getChannelCode()).append(","); } body.append(paymentRateDO.getCollectDate()).append(","); body.append(paymentRateDO.getCurrencyCode()).append(","); body.append(paymentRateDO.getOrderCreateNum()).append(","); Money createAmount = new Money(); createAmount.setCent(paymentRateDO.getOrderCreateAmount()); body.append(createAmount.toString()).append(","); body.append(paymentRateDO.getOrderSuccessNum()).append(","); Money successAmount = new Money(); successAmount.setCent(paymentRateDO.getOrderSuccessAmount()); body.append(successAmount.toString()).append(","); if (paymentRateDO.getOrderSuccessNum() == 0 || paymentRateDO.getOrderCreateNum() == 0) { body.append(0).append(","); } else { String result = numberFormat .format((float) paymentRateDO.getOrderSuccessNum() / (float) paymentRateDO.getOrderCreateNum() * 100) + "%"; body.append(result).append(","); } if (paymentRateDO.getOrderSuccessAmount() == 0 || paymentRateDO.getOrderCreateAmount() == 0) { body.append(0).append(","); } else { String result = numberFormat .format((float) paymentRateDO.getOrderSuccessAmount() / (float) paymentRateDO.getOrderCreateAmount() * 100) + "%"; body.append(result).append(","); } body.append("\r\n"); } } //寫入resp ExportUtil.responseSetProperties(response); ExportUtil.doExport(body.toString(), response); return null; } catch (Exception e) { log.error("export pending pay order error", e); return null; } }
工作中肯定會遇到很多從沒有用過的外掛,那麼這個時候怎麼快速的去熟悉這個外掛並且獲得基本的使用功能就尤為重要了。
個人有一點小心得,先訪問外掛的官網,儘量使用中文版的(易於閱讀),或者使用谷歌頁面翻譯成中文,當然如果英語很厲害的就另說了。
根據自己的需求去檢視官方例項,要帶著目的去看,不能盲目的一頭扎進去,外掛的功能強大的話,整體看下來其實收穫不了什麼。帶著需求去的話,你看了某一個例項正是你想要的那種結果,你就會繼續去看js是怎麼寫的,以及其中每個引數有什麼意義,需要一些什麼資料就可以顯示出那樣的效果。
到了這裡,你就可以開始考慮你的程式碼實現了,傳什麼資料給js,以及怎麼去獲取這些資料。
如果碰到一些問題,第一谷歌,去看看別人有沒有碰到,基本你碰到的問題,別人也會碰到,畢竟使用的人多了,坑基本都被人家踩過了。
第二官方文件,谷歌解決不了,你就回歸本質,到文件中去看看,是哪個引數引起的問題,還是哪些功能有問題,或者顯示有問題。興許就是你少加了個引數或者ture啊false啊 什麼的,效果會截然不同。
第三,去加一些外掛的QQ群,裡面都是一些正在使用或者使用過的人,向裡邊的人取取經,會有意外的收穫。
詳細的程式碼已經上傳到資源(包括js和後臺程式碼,資料庫檢視,功能為根據多個條件來顯示折線圖,以及datatable表格):http://download.csdn.net/download/wj18570504421/10169716
總結到最後,還是覺得要培養自己解決問題的能力,使用過程中,肯定會碰到很多BUG,但是怎麼去排查出來並且解決它,那個思維過程很重要!