SpringBoot+Vue3实现echarts数据统计
统计那些数据
1.统计不同分类下用户发布旅游攻略帖子的数量(反映出:大家比较喜欢去哪类的旅游景点)饼图
统计出的数据要有价值
2.统计不同用户发布帖子数量Top5 (反映出: 平台活跃用户Top5) 柱状图
3.统计最近一周每天平台用户发布的贴子数量(反映出:每天的活跃情况) 折线图
统计是解决一些实际数据的整合或者反馈出一些现象.所以它要具有一些实用的意义。
如何去熟悉一个统计图
1.去官网体验一下
2.改一改它的数据,找到该统计图所需要的数据在哪个地方
3.分析该数据的结构(数据结构)重要!!
饼图数据部分的数据结构:
1 2 3 4 5
| data: [ { value: 1048, name: '风景名胜' }, { value: 735, name: '历史古迹' }, { value: 580, name: '人文景观' }, ],
|
前端: [] 表示一个数组(对应多条数据) , {} 表示一个对象(对应一个数据)
后端:List 某个对象或者是Map<key,value>
该数据结构从后端返回的数据应该是一个什么样子的呢?List` 或 List<Map<key,value>>
4.后台接口封装该数据所需要的数据
1.echarts官网
官网: 快速上手 - 使用手册 - Apache ECharts
2.echarts 安装与实用
cd vue
npm install echarts --save
import * as echarts from “echarts”;
3.数据结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| let pieOptions = { title: { text: '不同分类下用户发布旅游攻略帖子的数量', subtext: '数据统计维度:攻略分类', left: 'center' }, tooltip: { trigger: 'item', formatter: '{a}<br/>{b}:{c} ({d}%)' }, legend: { orient: 'vertical', left: 'left' }, series: [ { name: '数据占比', type: 'pie', radius: '50%', center: ['50%','60%'], data: [ { value: 1048, name: '风景名胜' }, { value: 735, name: '历史古迹' }, { value: 580, name: '人文景观' }, ], } ] };
|
放在Home.vue下
问题处理:说明dom没法初始化,onMount是等页面dom元素加载完毕之后开始执行

1 2 3 4 5 6 7 8 9
| const loadPie = () => { let chartDom = document.getElementById('pie'); let myChart = echarts.init(chartDom); myChart.setOption(pieOptions); } onMounted(()=>{ loadPie() })
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| @RestController @RequestMapping("/echarts") public class EchartsController {
@Resource public CategoryService categoryService;
@Resource public IntroductionService introductionService;
@RequestMapping("/pie") public Result pie() { List<Map<String,Object>>list = new ArrayList<>(); List<Category> categories = categoryService.selectAll(new Category()); List<Introduction> introductions = introductionService.selectAll(new Introduction()); for (Category category : categories) { long count = introductions.stream().filter(x -> category.getId().equals(x.getCategoryId())).count(); Map<String,Object> map = new HashMap<>(); map.put("name",category.getTitle()); map.put("value",count); list.add(map); } return Result.success(list); }
}
|
柱状图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| let barOptions = { title: { text: '不同用户发布帖子数量Top5', subtext: '统计维度,用户昵称', left: 'center' },
grid: { top: '20%', bottom: '30%' }, legend: { orient: 'vertical', left: 'left' }, xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], name: '用户昵称', axisLabel: { interval: 0, rotate: -60, inside: false, margin: 30, align: 'right', verticalAlign: 'middle', fontSize: 12 }, nameLocation: "center", nameGap: 35 }, yAxis: { type: 'value', name: '攻略数量', }, tooltip: { trigger: 'item', }, series: [ { data: [120, 280, 150, 80, 70, 110, 130], type: 'bar', itemStyle: { normal: { color: function () { return "#" + Math.floor(Math.random()*(256*256*256-1)).toString(16); } } } } ], };
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| const loadBar = () => { request.get("/echarts/bar").then(res=>{ if(res.code === '200') { let chartDom = document.getElementById('bar'); let myChart = echarts.init(chartDom); barOptions.xAxis.data = res.data.xAxis barOptions.series[0].data = res.data.yAxis myChart.setOption(barOptions); } })
} onMounted(()=>{ loadPie() loadBar() })
|
后端:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| @GetMapping("/bar") public Result bar() { Map<String,Object>resultMap = new HashMap<>(); List<String>xList = new ArrayList<>(); List<Long>yList = new ArrayList<>(); Map<String,Long> map = new HashMap<>();
List<User>users = userService.selectAll(new User()); List<Introduction>introductions = introductionService.selectAll(new Introduction()); for (User user : users) { long count = introductions.stream().filter(x -> user.getId().equals(x.getUserId())).count();
map.put(user.getName(),count);
} LinkedHashMap<String, Long> sortedMap = map.entrySet().stream() .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
for (String key : sortedMap.keySet()) { xList.add(key); yList.add(sortedMap.get(key)); }
if(xList.size()>5 && yList.size()>5){ xList = xList.subList(0,5); yList = yList.subList(0,5); }
resultMap.put("xAxis",xList); resultMap.put("yAxis",yList); return Result.success(resultMap); }
|
折线图和柱状图几乎是一样的 改一下type就行 bar->line
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| let lineOptions = { title: { text: '最近一周每天平台用户发布帖子的数量', subtext: '统计维度: 最近一周', left: 'center' },
grid: { bottom: '3%', containLabel: true }, xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], name: '日期', }, yAxis: { type: 'value', name: '攻略数量', }, series: [ { data: [120, 280, 150, 80, 70, 110, 130], type: 'line', smooth: true, markLine: { data: [{type: 'average',name: '最近一周攻略发布数量平均值'}] }, markPoint: { data: [ {type: 'max',name: '最大值'}, {type: 'min',name: '最小值'}, ] } } ], };
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| @GetMapping("/line") public Result line() { Map<String,Object>resultMap = new HashMap<>(); List<Long>yList = new ArrayList<>(); Date today = new Date(); DateTime start = DateUtil.offsetDay(today, -7); List<String> xList = DateUtil.rangeToList(start, today, DateField.DAY_OF_YEAR).stream().map(DateUtil::formatDate).toList();
List<Introduction> introductions = introductionService.selectAll(new Introduction()); for (String day : xList) { long count = introductions.stream().filter(x -> ObjectUtil.isNotEmpty(x.getTime()) && x.getTime().contains(day)).count(); yList.add(count); }
resultMap.put("xAxis",xList); resultMap.put("yAxis",yList); return Result.success(resultMap); }
|