[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-public-gb01JPC2":3,"public-project-articles-gb01JPC2":17},{"id":4,"uuid":5,"project_id":6,"title":7,"content":8,"type":9,"status":10,"public_enabled":10,"views":11,"sort":12,"created_at":13,"updated_at":14,"project_title":15,"project_slug":16},1283,"gb01JPC2",49,"16. Springboot3+Vue3实现echarts数据统计","## 统计哪些数据\n1. 统计不同分类下用户发布旅游攻略帖子的数量（反映出：大家比较喜欢去哪类的旅游景点）-饼图\n2. 统计不同用户发布帖子数量Top5（反映出：平台活跃用户Top5）-柱状图\n3. 统计最近一周每天平台用户发布的帖子数量（反映出：每天的活跃情况）-折线图\n\n统计是解决一些实际数据的整合或者反馈出的一些现象，所以它要具有一些实用的意义。\n\n## 如何去\u003Cfont style=\"color:#DF2A3F;\">把玩\u003C\u002Ffont>一个统计图\n1. 去官网体验一下\n2. 改一改它的数据，找到该统计图所需要的数据在哪个地方\n3. 分析该数据的结构（**\u003Cfont style=\"color:#DF2A3F;\">数据结构\u003C\u002Ffont>**）重要！！\n\n饼图数据部分的数据结构：\n\n```java\ndata: [\n    { value: 1048, name: '风景名胜' },\n    { value: 735, name: '历史古迹' },\n    { value: 580, name: '人文景观' }\n],\n```\n\n前端：[ ] 表示一个数组（**对应多条数据**），{ } 表示一个对象（**对应一条数据**），\n\n对应的后端：List（对应多条数据），某个对象或者是Map\u003Ckey, value>\n\n该数据结构从后端返回的数据应该是一个什么样子的呢？List\u003CXxx> 或者 List\u003CMap\u003Ckey, vaule>\n\n4. 后台接口封装该数据结构所需要的数据\n\n## echarts官网\necharts官网（新版）：[https:\u002F\u002Fecharts.apache.org\u002Fexamples\u002Fzh\u002Findex.html](https:\u002F\u002Fecharts.apache.org\u002Fexamples\u002Fzh\u002Findex.html)\n\necharts官网（旧版）：[https:\u002F\u002Fecharts.apache.org\u002Fv4\u002Fexamples\u002Fzh\u002Findex.html](https:\u002F\u002Fecharts.apache.org\u002Fv4\u002Fexamples\u002Fzh\u002Findex.html)\n\n## echarts安装与使用\ncd vue（视情况而定）\n\nnpm install echarts --save\n\nimport * as echarts from \"echarts\";\n\n## 数据结构\n```javascript\n\u002F\u002F 平滑折线图\nlet lineOptions = {\n  title: {\n    text: '最近一周每天平台用户发布的帖子数量',\n    subtext: '统计维度：最近一周',\n    left: 'center'\n  },\n  legend: {\n    data: [],\n    template:\"\"\n  },\n  grid: {\n    left: '3%',\n    right: '4%',\n    bottom: '3%',\n    containLabel: true\n  },\n  tooltip: {\n    trigger: 'item'\n  },\n  xAxis: {\n    name: '日期',\n    type: 'category',\n    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']\n  },\n  yAxis: {\n    name: '攻略数量',\n    type: 'value'\n  },\n  series: [\n    {\n      name: '攻略数量',\n      data: [820, 932, 901, 934, 1290, 1330, 1320],\n      type: 'line',\n      smooth: true,\n      markLine: {\n        data: [{ type: 'average', name: '最近一周场攻略发布数量平均值' }]\n      },\n      markPoint: {\n        data: [\n          { type: 'max', name: '最大值' },\n          { type: 'min', name: '最小值' }\n        ]\n      },\n    },\n  ]\n};\n\u002F\u002F 柱状图\nlet barOptions = {\n  title: {\n    text: '不同用户发布帖子数量Top5', \u002F\u002F 主标题\n    subtext: '统计维度：用户昵称', \u002F\u002F 副标题\n    left: 'center'\n  },\n  grid : {   \u002F\u002F ---------------------------增加这个属性，bottom就是距离底部的距离\n    top: '20%',\n    bottom : '20%'\n  },\n  legend: {\n    orient: 'vertical',\n    left: 'left'\n  },\n  xAxis: {\n    type: 'category',\n    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], \u002F\u002F 示例数据：统计的维度（横坐标）\n    name: '用户昵称',\n    axisLabel: {\n      show: true, \u002F\u002F 是否显示刻度标签，默认显示\n      interval: 0, \u002F\u002F 坐标轴刻度标签的显示间隔，在类目轴中有效；默认会采用标签不重叠的策略间隔显示标签；可以设置成0强制显示所有标签；如果设置为1，表示『隔一个标签显示一个标签』，如果值为2，表示隔两个标签显示一个标签，以此类推。\n      rotate: -60, \u002F\u002F 刻度标签旋转的角度，在类目轴的类目标签显示不下的时候可以通过旋转防止标签之间重叠；旋转的角度从-90度到90度\n      inside: false, \u002F\u002F 刻度标签是否朝内，默认朝外\n      margin: 6, \u002F\u002F 刻度标签与轴线之间的距离\n    },\n  },\n  yAxis: {\n    type: 'value',\n    name: '攻略数量',\n  },\n  tooltip: {\n    trigger: 'item',\n  },\n  series: [\n    {\n      data: [120, 200, 150, 80, 70, 110, 130], \u002F\u002F 示例数据：横坐标维度对应的值（纵坐标）\n      type: 'bar',\n      itemStyle: {\n        normal: {\n          color: function () {\n            return \"#\" + Math.floor(Math.random() * (256 * 256 * 256 - 1)).toString(16);\n          }\n        },\n      },\n    }\n  ]\n};\n\u002F\u002F 饼图\nlet pieOptions = {\n  title: {\n    text: '不同分类下用户发布旅游攻略帖子的数量', \u002F\u002F 主标题\n    subtext: '统计维度：攻略分类', \u002F\u002F 副标题\n    left: 'center'\n  },\n  tooltip: {\n    trigger: 'item',\n    formatter: '{a} \u003Cbr\u002F>{b} : {c} ({d}%)'\n  },\n  legend: {\n    orient: 'vertical',\n    left: 'left'\n  },\n  series: [\n    {\n      name: '数量占比', \u002F\u002F 鼠标移上去显示内容\n      type: 'pie',\n      radius: '50%',\n      center: ['50%', '60%'],\n      data: [\n        {value: 1048, name: '瑞幸咖啡'}, \u002F\u002F 示例数据：name表示维度，value表示对应的值\n        {value: 735, name: '雀巢咖啡'},\n        {value: 580, name: '星巴克咖啡'},\n        {value: 484, name: '栖巢咖啡'},\n        {value: 300, name: '小武哥咖啡'}\n      ]\n    }\n  ]\n}\n```\n\n进多少天怎么处理？\n\n```java\nDate today = new Date();\nDateTime start = DateUtil.offsetDay(today, -90);\nList\u003CString> list = DateUtil.rangeToList(start, today, DateField.DAY_OF_YEAR).stream().map(DateUtil::formatDate).toList();\n```\n\n## 后端接口\n```java\n@GetMapping(\"\u002Fpie\")\npublic Result pie() {\n    List\u003CMap\u003CString, Object>> list = new ArrayList\u003C>();\n    \u002F\u002F 查询出所有的分类信息\n    List\u003CCategory> categories = categoryService.selectAll(new Category());\n    \u002F\u002F 查询出所有的帖子信息\n    List\u003CIntroduction> introductions = introductionService.selectAll(new Introduction());\n    for (Category category : categories) {\n        long count = introductions.stream().filter(x -> category.getId().equals(x.getCategoryId())).count();\n        Map\u003CString, Object> map = new HashMap\u003C>();\n        map.put(\"name\", category.getTitle());\n        map.put(\"value\", count);\n        list.add(map);\n    }\n    return Result.success(list);\n}\n\n@GetMapping(\"\u002Fbar\")\npublic Result bar() {\n    Map\u003CString, Object> resultMap = new HashMap\u003C>();\n    List\u003CString> xList = new ArrayList\u003C>();\n    List\u003CLong> yList = new ArrayList\u003C>();\n\n    Map\u003CString, Long> map = new HashMap\u003C>();\n\n    \u002F\u002F 查询所有的用户\n    List\u003CUser> users = userService.selectAll(new User());\n    \u002F\u002F 查询出所有的帖子信息\n    List\u003CIntroduction> introductions = introductionService.selectAll(new Introduction());\n    for (User user : users) {\n        long count = introductions.stream().filter(x -> user.getId().equals(x.getUserId())).count();\n        map.put(user.getName(), count);\n    }\n\n    \u002F\u002F 对map进行排序，按照value来倒序\n    LinkedHashMap\u003CString, Long> collectMap = map.entrySet().stream()\n            .sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))\n            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));\n\n    for (String key : collectMap.keySet()) {\n        xList.add(key);\n        yList.add(collectMap.get(key));\n    }\n\n    \u002F\u002F top几的的问题，截断一下\n    if (xList.size() > 5 && yList.size() > 5) {\n        xList = xList.subList(0, 5);\n        yList = yList.subList(0, 5);\n    }\n\n    resultMap.put(\"xAxis\", xList);\n    resultMap.put(\"yAxis\", yList);\n    return Result.success(resultMap);\n}\n\n@GetMapping(\"\u002Fline\")\npublic Result line() {\n    Map\u003CString, Object> resultMap = new HashMap\u003C>();\n    List\u003CLong> yList = new ArrayList\u003C>();\n\n    \u002F\u002F 获取最近多少天的年月日List\n    Date today = new Date();\n    DateTime start = DateUtil.offsetDay(today, -7);\n    List\u003CString> xList = DateUtil.rangeToList(start, today, DateField.DAY_OF_YEAR).stream().map(DateUtil::formatDate).toList();\n\n    \u002F\u002F 把所有的帖子查出来\n    List\u003CIntroduction> introductions = introductionService.selectAll(new Introduction());\n\n    for (String day : xList) {\n        long count = introductions.stream().filter(x -> ObjectUtil.isNotEmpty(x.getTime()) && x.getTime().contains(day)).count();\n        yList.add(count);\n    }\n\n    resultMap.put(\"xAxis\", xList);\n    resultMap.put(\"yAxis\", yList);\n    return Result.success(resultMap);\n}\n```\n\n## 问题处理\n![](https:\u002F\u002Fcdn.nlark.com\u002Fyuque\u002F0\u002F2025\u002Fpng\u002F38425080\u002F1740987078157-e0ef0757-9c56-4c06-b706-813701741c05.png)\n\n说明dom没法初始化，onMounted是等页面dom元素加载完毕之后开始执行。\n\n\n\n","coding",1,4307,1530,"2025-03-03 16:58:21","2026-05-03 22:49:02","带小白做毕设2025系列课程","graduation-project-2025",{"project":18,"items":19},{"id":6,"title":15,"slug":16},[20,28,35,42,49,56,63,70,77,84,91,98,105,112,119,126,133,134,141,148,155],{"id":21,"uuid":22,"project_id":6,"title":23,"type":9,"status":10,"public_enabled":10,"views":24,"sort":25,"created_at":26,"updated_at":27,"project_title":15,"project_slug":16},766,"XmlcAcY0","00. 带小白做毕设2025课程介绍",19012,1512,"2025-02-22 15:29:01","2026-05-07 15:33:28.189425+00",{"id":29,"uuid":30,"project_id":6,"title":31,"type":9,"status":10,"public_enabled":10,"views":32,"sort":33,"created_at":34,"updated_at":14,"project_title":15,"project_slug":16},767,"nmjXCdVH","01. 前端Vue3 框架的快速搭建以及项目工程的讲解",15797,1513,"2025-02-13 17:13:40",{"id":36,"uuid":37,"project_id":6,"title":38,"type":9,"status":10,"public_enabled":10,"views":39,"sort":40,"created_at":41,"updated_at":14,"project_title":15,"project_slug":16},768,"pMdPrVeH","02. 使用Vue3集成Element-Plus快速搭建一个管理系统的页面框架",15959,1514,"2025-02-14 11:25:07",{"id":43,"uuid":44,"project_id":6,"title":45,"type":9,"status":10,"public_enabled":10,"views":46,"sort":47,"created_at":48,"updated_at":14,"project_title":15,"project_slug":16},771,"8PikYMQU","03. Springboot3框架的快速搭建以及项目工程的讲解",12768,1517,"2025-02-21 17:21:51",{"id":50,"uuid":51,"project_id":6,"title":52,"type":9,"status":10,"public_enabled":10,"views":53,"sort":54,"created_at":55,"updated_at":14,"project_title":15,"project_slug":16},772,"Q1TCG9Jj","04. Springboot3整合MyBatis实现数据库操作",11144,1518,"2025-03-07 15:50:30",{"id":57,"uuid":58,"project_id":6,"title":59,"type":9,"status":10,"public_enabled":10,"views":60,"sort":61,"created_at":62,"updated_at":14,"project_title":15,"project_slug":16},773,"De7YPnEc","05. Springboot3+vue3实现增删改查、分页查询、批量删除（上）",10827,1519,"2025-02-22 15:09:19",{"id":64,"uuid":65,"project_id":6,"title":66,"type":9,"status":10,"public_enabled":10,"views":67,"sort":68,"created_at":69,"updated_at":14,"project_title":15,"project_slug":16},774,"YKEHfsPd","06. Springboot3+vue3实现增删改查、分页查询、批量删除（下）",7760,1520,"2025-02-22 22:00:02",{"id":71,"uuid":72,"project_id":6,"title":73,"type":9,"status":10,"public_enabled":10,"views":74,"sort":75,"created_at":76,"updated_at":14,"project_title":15,"project_slug":16},775,"sNDKpWVJ","07. Springboot3+Vue3实现excel批量导入导出",6552,1521,"2025-02-23 10:49:24",{"id":78,"uuid":79,"project_id":6,"title":80,"type":9,"status":10,"public_enabled":10,"views":81,"sort":82,"created_at":83,"updated_at":14,"project_title":15,"project_slug":16},776,"1uMP9O6C","08. Springboot3+vue3实现登录注册功能",7964,1522,"2025-02-23 18:14:13",{"id":85,"uuid":86,"project_id":6,"title":87,"type":9,"status":10,"public_enabled":10,"views":88,"sort":89,"created_at":90,"updated_at":14,"project_title":15,"project_slug":16},777,"WahvQp1v","09. Springboot3+vue3实现JWT登录鉴权",7151,1523,"2025-02-23 21:58:00",{"id":92,"uuid":93,"project_id":6,"title":94,"type":9,"status":10,"public_enabled":10,"views":95,"sort":96,"created_at":97,"updated_at":14,"project_title":15,"project_slug":16},778,"QFFAqZh1","10. Springboot3+vue3实现文件上传和下载",6171,1524,"2025-02-24 14:16:27",{"id":99,"uuid":100,"project_id":6,"title":101,"type":9,"status":10,"public_enabled":10,"views":102,"sort":103,"created_at":104,"updated_at":14,"project_title":15,"project_slug":16},1278,"S2eL2g5L","11. Springboot3+vue3实现个人中心、修改密码",5945,1525,"2025-02-24 18:10:59",{"id":106,"uuid":107,"project_id":6,"title":108,"type":9,"status":10,"public_enabled":10,"views":109,"sort":110,"created_at":111,"updated_at":14,"project_title":15,"project_slug":16},1279,"LkN8Mmsn","12. Springboot3+Vue3实现系统公告功能",4967,1526,"2025-02-25 11:50:13",{"id":113,"uuid":114,"project_id":6,"title":115,"type":9,"status":10,"public_enabled":10,"views":116,"sort":117,"created_at":118,"updated_at":14,"project_title":15,"project_slug":16},1280,"i7wziuEN","13. Springboot3+Vue3实现角色权限控制",4446,1527,"2025-02-25 11:51:38",{"id":120,"uuid":121,"project_id":6,"title":122,"type":9,"status":10,"public_enabled":10,"views":123,"sort":124,"created_at":125,"updated_at":14,"project_title":15,"project_slug":16},1281,"pGwiTCRn","14. Springboot3+Vue3实现富文本编辑器功能",4578,1528,"2025-02-26 16:04:58",{"id":127,"uuid":128,"project_id":6,"title":129,"type":9,"status":10,"public_enabled":10,"views":130,"sort":131,"created_at":132,"updated_at":14,"project_title":15,"project_slug":16},1282,"tZ8iDql5","15. Springboot3+Vue3实现模块之间的关联",4454,1529,"2025-02-26 18:28:55",{"id":4,"uuid":5,"project_id":6,"title":7,"type":9,"status":10,"public_enabled":10,"views":11,"sort":12,"created_at":13,"updated_at":14,"project_title":15,"project_slug":16},{"id":135,"uuid":136,"project_id":6,"title":137,"type":9,"status":10,"public_enabled":10,"views":138,"sort":139,"created_at":140,"updated_at":14,"project_title":15,"project_slug":16},1284,"59bDkSFf","17. Springboot3+Vue3实现提交审核业务功能",3793,1531,"2025-03-04 11:58:16",{"id":142,"uuid":143,"project_id":6,"title":144,"type":9,"status":10,"public_enabled":10,"views":145,"sort":146,"created_at":147,"updated_at":14,"project_title":15,"project_slug":16},1285,"gApyb58X","18. Springboot3+Vue3实现预约审核业务功能",3332,1532,"2025-03-05 20:07:24",{"id":149,"uuid":150,"project_id":6,"title":151,"type":9,"status":10,"public_enabled":10,"views":152,"sort":153,"created_at":154,"updated_at":14,"project_title":15,"project_slug":16},1286,"XfpY5re0","19. Springboot3+Vue3实现前台首页的设计",3508,1533,"2025-03-05 20:08:12",{"id":156,"uuid":157,"project_id":6,"title":158,"type":9,"status":10,"public_enabled":10,"views":159,"sort":160,"created_at":161,"updated_at":14,"project_title":15,"project_slug":16},1287,"BnSPRBOc","20. Springboot3+Vue3实现前台轮播图和详情页的设计",4062,1534,"2025-03-17 17:13:36"]