首页 > 编程语言 >【Java】在树结构中给节点追加数据

【Java】在树结构中给节点追加数据

时间:2023-09-25 21:11:42浏览次数:38  
标签:node code Java 树结构 region tree onlineCount county 节点

一、功能需求

有个树状组件,展示区域层级,每个区域节点需要展示该地区下的统计信息

从来没做过,给我整不会了属实是

 

二、功能分析

原型有功能和老系统代码,查看源码后发现的结构框架

1、树组件是自己用ul + li 封装的,牛逼

2、数据加载逻辑是: 先加载区域树接口,然后加载区域所有统计数据的接口,

  再对树或者统计数据遍历,对节点进行赋值,完成渲染

3、统计数据的接口只提供有数据的区域

 

三、我的实现:

我菜逼写不来,想了想还是拿el-tree改改样式来实现

1、前端实现样式

<el-tree
  v-show="treeToggleFlag"
  ref="treeRef2"
  class="tree-expanded"
  node-key="regionCode"
  :default-expanded-keys="['360000']"
  highlight-current
  :expand-on-click-node="false"
  :data="treeData"
  :props="treeProps"
  @node-click="handleTreeNodeClick"
>
  <span slot-scope="{ node, data }" class="custom-tree-node2">
    <div class="region-bar"><span class="region-label">{{ node.label }}</span> <span class="link-color">数据统计</span></div>
    <div class="statistic-panel">
      <el-row :gutter="10">
        <el-col :span="12">
          <el-statistic group-separator="," :precision="2" :value="data.licenseCount" title="车牌号码" />
        </el-col>
        <el-col :span="12">
          <el-statistic group-separator="," :precision="2" :value="data.obuCount" title="ETC/MTC" />
        </el-col>
      </el-row>
      <el-row :gutter="10" style="margin-top: 10px;">
        <el-col :span="12">
          <el-statistic group-separator="," :precision="2" :value="data.apCount" title="行车记录仪" />
        </el-col>
        <el-col :span="12">
          <el-statistic group-separator="," :precision="2" :value="data.bleCount" title="车载蓝牙" />
        </el-col>
      </el-row>
      <el-row :gutter="10" style="margin-top: 10px;">
        <el-col :span="12">
          <el-statistic group-separator="," :precision="2" :value="data.allCount" title="设备总数" />
        </el-col>
        <el-col :span="12">
          <el-statistic title="设备在线率">
            <template slot="formatter">
              {{ data.onlineRatio }}
            </template>
          </el-statistic>
        </el-col>
      </el-row>
    </div>
  </span>
</el-tree>

组件需要的变量:

treeToggleFlag: false,
treeData: [],
treeProps: {
  label: 'regionName',
  children: 'subRegions'
},

点击事件:

handleTreeNodeClick(region, val2) {
  console.log(region, val2)
  this.currentRegion = { code: region.regionCode, level: region.levelNo }
  this.initializeOverviewData()
  this.trIdx = 0
  const option = this.tendencyRangeOption[this.trIdx]
  this.tendencyRangeChoose(option, this.trIdx)
},

修改的样式:

/* - - - - - - - - - - - 展开的树节点样式 - - - - - - - - - - - */
.custom-tree-node2 {
  display: block;
  width: 100%;
  /*flex: 1;*/
  /*display: flex;*/
  /*align-items: center;*/
  /*justify-content: space-between;*/
  /*font-size: 14px;*/
  /*color: white;*/
  /*padding-right: 8px;*/
  /*border: 1px dashed black;*/
}
.custom-tree-node2 .region-bar {
  width: 100%;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
.custom-tree-node2 .statistic-panel {
  width: 100%;
  height: 100%;
  margin-top: 10px;
}
.custom-tree-node2 .region-bar .region-label {
  color: white;
  font-size: 14px;
}
/*.custom-tree-node2 .region-bar .region-statistic {*/
  /*color: rgb(102, 177, 255);*/
/*}*/
/* 节点内容高度 */
/deep/ .tree-expanded .el-tree-node__content {
  height: 180px;
  width: 100%;
  border-bottom: #b8b9c226 1px dashed;
  background-color: #1A1F3E;
}
/* 点击选中的节点 */
/deep/ .el-tree-node:focus > .el-tree-node__content {
  background-color: #024588;
}
/* 高亮节点颜色 */
/deep/  .el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content {
  background-color: #024588;
}
/* - - - - - - - - - - - 展开的树节点样式 - - - - - - - - - - - */
/* 没有展开且有子节点 */
/deep/ .el-tree .el-icon-caret-right:before {
  background: url("./../../../assets/image/draw-out.png") no-repeat 0 0;
  content: "";
  display: inline-block;
  width: 16px;
  height: 16px;
  margin-left: 3px;
  background-size: 16px 16px;
}
/* 已经展开且有子节点 */
/deep/ .el-tree .el-tree-node__expand-icon.expanded.el-icon-caret-right:before {
  background: url("./../../../assets/image/draw-back.png") no-repeat 0 0;
  content: "";
  display: inline-block;
  width: 16px;
  height: 16px;
  transform: rotate(-90deg);
  background-size: 16px 16px;
}
/* 没有子节点 */
/deep/ .el-tree .el-tree-node__expand-icon.is-leaf::before {
  background: none;
}
/* 统计数据样式 */
/deep/ .custom-tree-node2 .statistic-panel .el-statistic .con .number { color: white; font-size: 18px; }
/deep/ .custom-tree-node2 .statistic-panel .el-statistic .head { font-size: 13px; color: #989AA8;  }

  

实现效果:

做不到完全一样,但是想表达的东西到位了,我尽力了

 

2、数据来源解决

Java接口:

/**
 * @author OnCloud9
 * @date 2023/9/25 15:18
 * @description
 * @params []
 * @return java.util.Map<java.lang.String,java.util.Map<java.lang.String,java.lang.Long>>
 */
@GetMapping("/region-count-data")
public Map<String, List<Map<String, Object>>> getStatisticDataRegionCountData() {
    return statisticDataService.getStatisticDataRegionCountData();
}

Service:

@Override
public Map<String, List<Map<String, Object>>> getStatisticDataRegionCountData() {
    /* distinct 获取存在数据的区域,无数据区域不查询 */
    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.DAY_OF_MONTH, -1);
    Date previousDate = calendar.getTime();
    String formatDate = DateUtil.format(previousDate, "yyyy-MM-dd");
    /* 查找当日统计的区域 */
    List<Map<String, Object>> regionData1 = obuStatisticService.selectAllRegionData(formatDate);
    List<Map<String, Object>> regionData2 = obuTDeviceService.selectAllRegionData();
    Map<String, List<Map<String, Object>>> result = new HashMap<>();
    result.put("list1", regionData1);
    result.put("list2", regionData2);
    return result;
}

统计表的SQL,三次分组查询Union结合成一张表结果:

SELECT 
 region_code AS regionCode, 
 SUM(license_count) AS licenseCount, 
 SUM(obu_count) AS obuCount, 
 SUM(ap_count) AS apCount, 
 SUM(ble_count) AS bleCount 
FROM obu_statistic 
WHERE statistic_day = #{formatDate} 
GROUP BY region_code 
UNION 
SELECT 
 CONCAT(LEFT(region_code, 4), '00') AS regionCode, 
 SUM(license_count) AS licenseCount, 
 SUM(obu_count) AS obuCount, 
 SUM(ap_count) AS apCount, 
 SUM(ble_count) AS bleCount 
FROM obu_statistic 
WHERE statistic_day = #{formatDate} 
GROUP BY LEFT(region_code, 4) 
UNION 
SELECT 
 CONCAT(LEFT(region_code, 2), '0000') AS regionCode, 
 SUM(license_count) AS licenseCount, 
 SUM(obu_count) AS obuCount, 
 SUM(ap_count) AS apCount, 
 SUM(ble_count) AS bleCount 
FROM obu_statistic 
WHERE statistic_day = #{formatDate} 
GROUP BY LEFT(region_code, 2)"

查询结果:

+------------+--------------+----------+---------+----------+
| regionCode | licenseCount | obuCount | apCount | bleCount |
+------------+--------------+----------+---------+----------+
| 360111     | 106777       | 104264   | 161533  | 246934   |
| 360100     | 106777       | 104264   | 161533  | 246934   |
| 360000     | 106777       | 104264   | 161533  | 246934   |
+------------+--------------+----------+---------+----------+

  

设备表的SQL需要统计设备在线率,这一步要把分组的表联表JOIN合并:

SELECT a.county_code, a.allCount, IFNULL(b.onlineCount, 0) AS onlineCount, ROUND(IFNULL(b.onlineCount, 0) / a.allCount, 4) AS onlineRatio
FROM (SELECT county_code, COUNT(county_code) AS allCount FROM obu_t_device GROUP BY county_code) AS a
LEFT JOIN (SELECT county_code, COUNT(county_code) AS onlineCount FROM obu_t_device WHERE run_status = 1 GROUP BY county_code) AS b
ON a.county_code = b.county_code
UNION 
SELECT a.county_code, a.allCount, IFNULL(b.onlineCount, 0) AS onlineCount, ROUND(IFNULL(b.onlineCount, 0) / a.allCount, 4) AS onlineRatio
FROM (SELECT CONCAT( LEFT(county_code, 4), '00') AS county_code, COUNT(1) AS allCount FROM obu_t_device GROUP BY CONCAT(LEFT(county_code, 4), '00')) AS a
LEFT JOIN (SELECT CONCAT( LEFT(county_code, 4), '00') AS county_code, COUNT(1) AS onlineCount FROM obu_t_device WHERE run_status = 1 GROUP BY CONCAT(LEFT(county_code, 4), '00')) AS b
ON a.county_code = b.county_code
UNION 
SELECT a.county_code, a.allCount, IFNULL(b.onlineCount, 0) AS onlineCount, ROUND(IFNULL(b.onlineCount, 0) / a.allCount, 4) AS onlineRatio
FROM (SELECT CONCAT( LEFT(county_code, 2), '0000') AS county_code, COUNT(1) AS allCount FROM obu_t_device GROUP BY CONCAT( LEFT(county_code, 2), '0000')) AS a
LEFT JOIN (SELECT CONCAT( LEFT(county_code, 2), '0000') AS county_code, COUNT(1) AS onlineCount FROM obu_t_device WHERE run_status = 1 GROUP BY CONCAT( LEFT(county_code, 2), '0000')) AS b
ON a.county_code = b.county_code

查询结果:

+-------------+----------+-------------+-------------+
| county_code | allCount | onlineCount | onlineRatio |
+-------------+----------+-------------+-------------+
| 360111      |        4 |           1 | 0.2500      |
| 360100      |        4 |           1 | 0.2500      |
| 360000      |        4 |           1 | 0.2500      |
+-------------+----------+-------------+-------------+

3、数据结果联动

async initializeTreeData() {
  const { data: treeData } = await getSysRegionTreeData('36', {})
  const { data: result } = await getStatisticDataRegionCountData()
  const list1 = result.list1
  const list2 = result.list2
  console.log(treeData)
  this.treeForeach(treeData, 'subRegions', node => {
    const d1 = list1.find(x => x.regionCode === node.regionCode)
    const d2 = list2.find(x => x.regionCode === node.regionCode)
    if (!d1 && !d2) {
      node.licenseCount = 0
      node.obuCount = 0
      node.apCount = 0
      node.bleCount = 0
      node.allCount = 0
      node.onlineCount = 0
      node.onlineRatio = `0%`
      return
    }
    if (d1) {
      const { licenseCount, obuCount, apCount, bleCount } = d1
      node.licenseCount = licenseCount
      node.obuCount = obuCount
      node.apCount = apCount
      node.bleCount = bleCount
    }
    if (d2) {
      const { allCount, onlineCount, onlineRatio } = d2
      node.allCount = allCount
      node.onlineCount = onlineCount
      node.onlineRatio = `${onlineRatio * 100}%`
    }
  })
  this.treeData = treeData
},

递归方法:

treeForeach(tree, childrenField, func) {
  tree.forEach(data => {
    func(data)
    data[childrenField] && this.treeForeach(data[childrenField], childrenField, func) // 遍历子树
  })
},

  

四、参考资料:

El-tree组件:

https://element.eleme.io/#/zh-CN/component/tree#scoped-slot

树结构的操作方法:

https://blog.csdn.net/OUalen/article/details/131438154

样式优化修改参考:

https://blog.csdn.net/Sabrina_cc/article/details/125319257

节点的操作图标:

https://www.iconfont.cn/

  

 

标签:node,code,Java,树结构,region,tree,onlineCount,county,节点
From: https://www.cnblogs.com/mindzone/p/17728798.html

相关文章

  • idea java代码注释模板制作 idea类注释模板设置【转载】
    一、类模板设置1、进入设置页面:File-->settings-->Editor-->FileandCodeTemplates-->Files2、设置类、接口、枚举模板信息3、点击Apply应用设置二、方法模板设置1、同样打开设置:File-->settings-->Editor-->LiveTemplates2、新建模板组:命名为userDefine3、选中新建的模板组,新......
  • Python与Java的语法区别
    数据容器/数组/集合Python:对数据容器的操作#对list进行切片,从1开始,4结束,步长1(默认步长为1)my_list=[0,1,2,3,4,5,6]result1=my_list[1:4]print(f"结果1:{result1}")#对tuple进行切片,从头开始,到最后结束,步长1my_tuple=(0,1,2,3,4,5,6)result2=my_tu......
  • Sentienl基于Jdk17版本运行出错:java.lang.IllegalStateException: Cannot load config
    java.lang.IllegalStateException:Cannotloadconfigurationclass:com.alibaba.csp.sentinel.dashboard.DashboardApplicationatorg.springframework.context.annotation.ConfigurationClassPostProcessor.enhanceConfigurationClasses(ConfigurationClassPostP......
  • 无涯教程-JavaScript - RSQ函数
    描述RSQ函数通过known_y和known_x中的数据点返回皮尔逊乘积矩相关系数的平方。语法RSQ(known_y's,known_x's)争论Argument描述Required/OptionalKnown_y'sAnarrayorrangeofdatapoints.RequiredKnown_x'sAnarrayorrangeofdatapoints.RequiredNotes......
  • 使用JavaScript实现无限滚动的方法
    前言在网页设计中,无限滚动是一种常见的交互方式,用户可持续地加载更多内容而无需刷新页面,提高用户体验。本文将介绍如何运用JavaScript实现无限滚动的效果,使网页能够自动加载更多数据,减轻用户加载新页的负担,为用户提供更好的访问体验。原理理解无限滚动的原理无限滚动的原理是当......
  • JavaScript——递归
    //递归:找到所有节点,并在每个节点上添加属性recursionMethod(data);constrecursionMethod=(array:any)=>{leti;for(iinarray){letarr=array[i];//是否存在children,存在则添加一个value属性,并赋值id//然后继续递归,查找arr.chi......
  • Java NIO 底层原理的基本思想?
    作者:Java架构资深进阶链接:https://zhuanlan.zhihu.com/p/268805428来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。写在前面1.1.JavaIO读写原理1.1.1.内核缓冲与进程缓冲区1.1.2.javaIO读写的底层流程1.2.四种主要的IO模型1.3.同步......
  • java有哪三大特性?
    文章目录⭐专栏介绍问题描述问题答案⭐专栏介绍本专栏会持续更新各种关于JAVA的问题,包括面试题,JAVA入门到精通等。更新速度保持在每天3—5篇问题描述java有哪三大特性?问题答案1、JAVA有三大特性,分别是:封装、继承和多态。2、封装:面向对象的封装就是把描述一个对象的属性和行为的......
  • Java -【字符串,数组,哈希表】常用操作
    一.字符串创建字符串:可以使用双引号或者String类的构造方法创建字符串。Stringstr1="HelloWorld";Stringstr2=newString("HelloWorld");连接字符串:可以使用加号或者String类的concat()方法连接字符串。Stringstr3=str1+str2;Stringstr4=str1.concat(str2);......
  • Java -【字符串,数组,哈希表】常用操作
    一.字符串创建字符串:可以使用双引号或者String类的构造方法创建字符串。Stringstr1="HelloWorld";Stringstr2=newString("HelloWorld");连接字符串:可以使用加号或者String类的concat()方法连接字符串。Stringstr3=str1+str2;Stringstr4=str1.concat(str2);获......