提交 2dcdcfd7 编写于 作者: zlt2000's avatar zlt2000

增加天流量趋势,并优化首页图表样式

上级 bd692901
package com.central.search.service.impl;
import cn.hutool.core.util.StrUtil;
import com.central.common.constant.CommonConstant;
import com.central.search.model.AggItemVo;
import com.central.search.service.IAggregationService;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
......@@ -19,6 +21,7 @@ import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
......@@ -107,7 +110,8 @@ public class AggregationServiceImpl implements IAggregationService {
public Map<String, Object> requestStatAgg(String indexName, String routing) {
DateTime currDt = DateTime.now();
LocalDate localDate = LocalDate.now();
SearchResponse response = elasticsearchTemplate.getClient().prepareSearch(indexName)
LocalDateTime curDateTime = LocalDateTime.now();
SearchRequestBuilder searchRequestBuilder = elasticsearchTemplate.getClient().prepareSearch(indexName)
.setRouting(routing)
.addAggregation(
//聚合查询当天的数据
......@@ -115,13 +119,33 @@ public class AggregationServiceImpl implements IAggregationService {
.dateRange("currDate")
.field("timestamp")
.addRange(
currDt.withHourOfDay(0).withMinuteOfHour(0).withSecondOfMinute(0).withMillisOfSecond(0), currDt
currDt.withHourOfDay(0).withMinuteOfHour(0).withSecondOfMinute(0).withMillisOfSecond(0), currDt.plusDays(1)
)
.subAggregation(
AggregationBuilders
.cardinality("uv")
.field("ip.keyword")
)
.subAggregation(
//聚合并且按小时分组查询当天内的数据
AggregationBuilders
.dateHistogram("statDate")
.field("timestamp")
.dateHistogramInterval(new DateHistogramInterval("90m"))
.format(CommonConstant.DATETIME_FORMAT)
//时区相差8小时
.timeZone(DateTimeZone.forOffsetHours(8))
.minDocCount(0L)
.extendedBounds(new ExtendedBounds(
curDateTime.minusDays(1).format(DateTimeFormatter.ofPattern(CommonConstant.DATETIME_FORMAT)),
curDateTime.format(DateTimeFormatter.ofPattern(CommonConstant.DATETIME_FORMAT))
))
.subAggregation(
AggregationBuilders
.cardinality("uv")
.field("ip.keyword")
)
)
)
.addAggregation(
//聚合查询7天内的数据
......@@ -183,10 +207,11 @@ public class AggregationServiceImpl implements IAggregationService {
.field("ip.keyword")
)
)
.setSize(0)
.get();
.setSize(0);
SearchResponse response = searchRequestBuilder.get();
Aggregations aggregations = response.getAggregations();
Map<String, Object> result = new HashMap<>(9);
Map<String, Object> result = new HashMap<>(15);
if (aggregations != null) {
setCurrDate(result, aggregations);
setCurrWeek(result, aggregations);
......@@ -206,6 +231,8 @@ public class AggregationServiceImpl implements IAggregationService {
Cardinality cardinality = bucket.getAggregations().get("uv");
result.put("currDate_pv", bucket.getDocCount());
result.put("currDate_uv", cardinality.getValue());
//赋值天趋势统计
setStatDate(result, bucket.getAggregations());
}
/**
* 赋值周统计
......@@ -271,4 +298,35 @@ public class AggregationServiceImpl implements IAggregationService {
Cardinality cardinality = bucket.getAggregations().get("uv");
result.put("currHour_uv", cardinality.getValue());
}
/**
* 赋值天趋势统计
*/
private void setStatDate(Map<String, Object> result, Aggregations aggregations) {
InternalDateHistogram agg = aggregations.get("statDate");
List<String> items = new ArrayList<>();
List<Long> uv = new ArrayList<>();
List<Long> pv = new ArrayList<>();
Cardinality cardinality;
for (InternalDateHistogram.Bucket bucket : agg.getBuckets()) {
items.add(getTimeByDatetimeStr(bucket.getKeyAsString()));
pv.add(bucket.getDocCount());
cardinality = bucket.getAggregations().get("uv");
uv.add(cardinality.getValue());
}
result.put("statDate_items", items);
result.put("statDate_uv", uv);
result.put("statDate_pv", pv);
}
/**
* 2020-03-10 01:30:00 获取时间值:03-10 01:30
* @return
*/
private String getTimeByDatetimeStr(String datetimeStr) {
if (StrUtil.isNotEmpty(datetimeStr)) {
return datetimeStr.substring(5, 16);
}
return "";
}
}
package com.central.gateway.filter;
import cn.hutool.core.util.StrUtil;
import eu.bitwalker.useragentutils.UserAgent;
import com.central.gateway.utils.ReactiveAddrUtil;
import com.central.log.monitor.PointUtil;
......@@ -32,8 +33,8 @@ public class RequestStatisticsFilter implements GlobalFilter, Ordered {
//埋点
PointUtil.debug("1", "request-statistics",
"ip=" + ReactiveAddrUtil.getRemoteAddr(request)
+ "&browser=" + userAgent.getBrowser()
+ "&operatingSystem=" + userAgent.getOperatingSystem());
+ "&browser=" + getBrowser(userAgent.getBrowser().name())
+ "&operatingSystem=" + getOperatingSystem(userAgent.getOperatingSystem().name()));
return chain.filter(exchange);
}
......@@ -42,4 +43,26 @@ public class RequestStatisticsFilter implements GlobalFilter, Ordered {
public int getOrder() {
return 0;
}
private String getBrowser(String browser) {
if (StrUtil.isNotEmpty(browser)) {
if (browser.contains("CHROME")) {
return "CHROME";
} else if (browser.contains("FIREFOX")) {
return "FIREFOX";
}
}
return browser;
}
private String getOperatingSystem(String operatingSystem) {
if (StrUtil.isNotEmpty(operatingSystem)) {
if (operatingSystem.contains("MAC_OS_X")) {
return "MAC_OS_X";
} else if (operatingSystem.contains("ANDROID")) {
return "ANDROID";
}
}
return operatingSystem;
}
}
package com.central.gateway.filter.pre;
import cn.hutool.core.util.StrUtil;
import com.central.common.utils.AddrUtil;
import com.central.log.monitor.PointUtil;
import com.netflix.zuul.ZuulFilter;
......@@ -44,9 +45,31 @@ public class RequestStatisticsFilter extends ZuulFilter {
//埋点
PointUtil.debug("0", "request-statistics",
"ip=" + AddrUtil.getRemoteAddr(req)
+ "&browser=" + userAgent.getBrowser()
+ "&operatingSystem=" + userAgent.getOperatingSystem());
+ "&browser=" + getBrowser(userAgent.getBrowser().getName())
+ "&operatingSystem=" + getOperatingSystem(userAgent.getOperatingSystem().getName()));
return null;
}
private String getBrowser(String browser) {
if (StrUtil.isNotEmpty(browser)) {
if (browser.contains("CHROME")) {
return "CHROME";
} else if (browser.contains("FIREFOX")) {
return "FIREFOX";
}
}
return browser;
}
private String getOperatingSystem(String operatingSystem) {
if (StrUtil.isNotEmpty(operatingSystem)) {
if (operatingSystem.contains("MAC_OS_X")) {
return "MAC_OS_X";
} else if (operatingSystem.contains("ANDROID")) {
return "ANDROID";
}
}
return operatingSystem;
}
}
/** layuiAdmin.std-v2020.1.24 LPPL License By https://www.layui.com/admin/ */
;layui.define(function (e) {
e("echartsTheme", {
color: ["#009688", "#1E9FFF", "#5FB878", "#FFB980", "#D87A80", "#8d98b3", "#e5cf0d", "#97b552", "#95706d", "#dc69aa", "#07a2a4", "#9a7fd1", "#588dd5", "#f5994e", "#c05050", "#59678c", "#c9ab00", "#7eb00a", "#6f5553", "#c14089"],
title: {textStyle: {fontWeight: "normal", color: "#666"}},
dataRange: {itemWidth: 15, color: ["#009688", "#e0ffff"]},
toolbox: {color: ["#1e90ff", "#1e90ff", "#1e90ff", "#1e90ff"], effectiveColor: "#ff4500"},
tooltip: {
backgroundColor: "rgba(50,50,50,0.5)",
axisPointer: {
type: "line",
lineStyle: {color: "#009688"},
crossStyle: {color: "#008acd"},
shadowStyle: {color: "rgba(200,200,200,0.2)"}
}
},
dataZoom: {dataBackgroundColor: "#efefff", fillerColor: "rgba(182,162,222,0.2)", handleColor: "#008acd"},
grid: {borderColor: "#eee"},
categoryAxis: {
axisLine: {lineStyle: {color: "#009688"}},
axisTick: {show: !1},
splitLine: {lineStyle: {color: ["#eee"]}}
},
valueAxis: {
axisLine: {lineStyle: {color: "#009688"}},
splitArea: {show: !0, areaStyle: {color: ["rgba(250,250,250,0.1)", "rgba(200,200,200,0.1)"]}},
splitLine: {lineStyle: {color: ["#eee"]}}
},
polar: {
axisLine: {lineStyle: {color: "#ddd"}},
splitArea: {show: !0, areaStyle: {color: ["rgba(250,250,250,0.2)", "rgba(200,200,200,0.2)"]}},
splitLine: {lineStyle: {color: "#ddd"}}
},
timeline: {
lineStyle: {color: "#009688"},
controlStyle: {normal: {color: "#009688"}, emphasis: {color: "#009688"}},
symbol: "emptyCircle",
symbolSize: 3
},
bar: {itemStyle: {normal: {barBorderRadius: 2}, emphasis: {barBorderRadius: 2}}},
line: {smooth: !0, symbol: "emptyCircle", symbolSize: 3},
k: {
itemStyle: {
normal: {
color: "#d87a80",
color0: "#2ec7c9",
lineStyle: {color: "#d87a80", color0: "#2ec7c9"}
}
}
},
scatter: {symbol: "circle", symbolSize: 4},
radar: {symbol: "emptyCircle", symbolSize: 3},
map: {
itemStyle: {
normal: {areaStyle: {color: "#ddd"}, label: {textStyle: {color: "#d87a80"}}},
emphasis: {areaStyle: {color: "#fe994e"}}
}
},
force: {itemStyle: {normal: {linkStyle: {color: "#1e90ff"}}}},
chord: {
itemStyle: {
normal: {
borderWidth: 1,
borderColor: "rgba(128, 128, 128, 0.5)",
chordStyle: {lineStyle: {color: "rgba(128, 128, 128, 0.5)"}}
},
emphasis: {
borderWidth: 1,
borderColor: "rgba(128, 128, 128, 0.5)",
chordStyle: {lineStyle: {color: "rgba(128, 128, 128, 0.5)"}}
}
}
},
gauge: {
axisLine: {lineStyle: {color: [[.2, "#2ec7c9"], [.8, "#5ab1ef"], [1, "#d87a80"]], width: 10}},
axisTick: {splitNumber: 10, length: 15, lineStyle: {color: "auto"}},
splitLine: {length: 22, lineStyle: {color: "auto"}},
pointer: {width: 5}
},
textStyle: {fontFamily: "微软雅黑, Arial, Verdana, sans-serif"}
})
});
\ No newline at end of file
......@@ -6,7 +6,6 @@
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<script type="text/javascript" src="../assets/libs/echarts.min.js"></script>
<style>
.layui-card-header {
text-align:left;
......@@ -20,6 +19,22 @@
font-size: 250%;
height: 30px;
}
.my-tab-item {
vertical-align: middle;
text-align: center;
line-height: 40px;
margin-right: 20px;
padding: 0 15px 12px 15px;
cursor: pointer;
}
.my-tab-item-select {
border: none;
border-radius: 0;
border-bottom: 2px solid #5FB878;
}
.my-tab-content {
height: 300px;
}
</style>
</head>
<body>
......@@ -80,8 +95,13 @@
<div class="layui-row layui-col-space10">
<div class="layui-col-lg12 layui-col-md12">
<div class="layui-card">
<div class="card-block">
<div id="week-container" style="height:350px"></div>
<div class="layui-card-header">
<a id="weekTab" class="my-tab-item my-tab-item-select">周流量趋势</a>
<a id="dayTab" class="my-tab-item">天流量趋势</a>
</div>
<div class="layui-card-body">
<div id="week-container" tabId="weekTab" class="my-tab-content"></div>
<div id="date-container" tabId="dayTab" class="my-tab-content" style="display: none"></div>
</div>
</div>
</div>
......@@ -105,75 +125,114 @@
</div>
<script type="text/javascript">
layui.use(['admin'], function () {
layui.use(['admin', "echarts"], function () {
let admin = layui.admin;
let echarts = layui.echarts;
let statData;
let browserChart = echarts.init(document.getElementById("browser-container"));
$(".my-tab-item").click(function() {
let selectId = $(this).attr('id');
$(".my-tab-item").each(function() {
let eachId = $(this).attr('id');
if (eachId === selectId) {
$(this).addClass("my-tab-item-select");
} else {
$(this).removeClass("my-tab-item-select");
}
});
$("[tabId]").each(function() {
let tabId = $(this).attr('tabId');
if (tabId === selectId) {
$(this).show();
if ($(this).html().length === 0) {
showDateChart($(this).attr('id'));
}
} else {
$(this).hide();
}
});
});
let showDateChart = function (contetnId) {
let dateChart = echarts.init(document.getElementById(contetnId), layui.echartsTheme);
dateChart.setOption({
tooltip: {trigger: "axis"},
legend: {
data: ['访问量(PV)', '独立用户(UV)']
},
xAxis: [
{
type: 'category',
boundaryGap: !1,
data: statData.statDate_items
}
],
yAxis: [{type: "value"}],
series: [
{
name: '访问量(PV)',
type: 'line',
smooth: !0,
itemStyle: {normal: {areaStyle: {type: "default"}}},
data: statData.statDate_pv
},
{
name: '独立用户(UV)',
type: 'line',
smooth: !0,
itemStyle: {normal: {areaStyle: {type: "default"}}},
data: statData.statDate_uv
}
]
});
}
let browserChart = echarts.init(document.getElementById("browser-container"), layui.echartsTheme);
browserChart.setOption({
title : {
text: '浏览器分布',
subtext: '',
x:'center'
},
tooltip : {
trigger: 'item',
formatter: "{a} <br/>{b} : {c} ({d}%)"
},
tooltip: {trigger: "item", formatter: "{a} <br/>{b} : {c} ({d}%)"},
legend: {},
series : []
});
browserChart.showLoading();
let osChart = echarts.init(document.getElementById("operatingSystem-container"));
let osChart = echarts.init(document.getElementById("operatingSystem-container"), layui.echartsTheme);
osChart.setOption({
title : {
text: '系统分布',
subtext: '',
x:'center'
},
tooltip : {
trigger: 'item',
formatter: "{a} <br/>{b} : {c} ({d}%)"
},
tooltip: {trigger: "item", formatter: "{a} <br/>{b} : {c} ({d}%)"},
legend: {},
series : []
});
osChart.showLoading();
let weekChart = echarts.init(document.getElementById("week-container"));
let weekChart = echarts.init(document.getElementById("week-container"), layui.echartsTheme);
weekChart.setOption({
title: {
text: '流量趋势'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
tooltip: {trigger: "axis"},
legend: {
data: ['访问量(PV)', '独立用户(UV)']
},
xAxis: [
{
type: 'category',
boundaryGap: false,
boundaryGap: !1,
data: []
}
],
yAxis: [
{
type: 'value'
}
],
yAxis: [{type: "value"}],
series: []
});
weekChart.showLoading();
admin.req('api-log/requestStat', {}, function (data) {
statData = data;
$('#pv').html(data.currDate_pv);
$('#uv').html(data.currDate_uv);
$('#weekPv').html(data.currWeek_pv);
......@@ -184,23 +243,16 @@
browserChart.setOption({
legend: {
orient: 'vertical',
left: 'left',
x: 'left',
data: data.browser_legendData
},
series : [
{
name: '浏览器',
name: '访问来源',
type: 'pie',
radius : '55%',
center: ['50%', '60%'],
data: data.browser_datas,
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
center: ['60%', '60%'],
data: data.browser_datas
}
]
});
......@@ -209,7 +261,7 @@
osChart.setOption({
legend: {
orient: 'vertical',
left: 'left',
x: 'left',
data: data.operatingSystem_legendData
},
series : [
......@@ -217,15 +269,8 @@
name: '操作系统',
type: 'pie',
radius : '55%',
center: ['50%', '60%'],
data: data.operatingSystem_datas,
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
center: ['60%', '60%'],
data: data.operatingSystem_datas
}
]
});
......@@ -235,7 +280,7 @@
xAxis: [
{
type: 'category',
boundaryGap: false,
boundaryGap: !1,
data: data.statWeek_items
}
],
......@@ -243,19 +288,15 @@
{
name: '访问量(PV)',
type: 'line',
areaStyle: {},
label: {
normal: {
show: true,
position: 'top'
}
},
smooth: !0,
itemStyle: {normal: {areaStyle: {type: "default"}}},
data: data.statWeek_pv
},
{
name: '独立用户(UV)',
type: 'line',
areaStyle: {},
smooth: !0,
itemStyle: {normal: {areaStyle: {type: "default"}}},
data: data.statWeek_uv
}
]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册