java树型结构的数据展现设计
在做一个需求管理的页面时,需求的展现是不限层级树型结构,需求下还可以分拆任务,页面要展现的字段有20多个,而且需求采用通用表单设计,db采用大宽表存储,有一百多个字段。目前数据量不大,第一版采用普通的同步加载数据方式,页面加载速度慢,慢的原因主要是代码逻辑没有做到最优,不如存在重复查询的问题,组织树型结构的时候也存在冗余的查询。加上页面渲染出全部数据,使得整个页面打开速度很慢。
针对以上问题,同事做了第二版优化,主要采用ajax加载页面,滚动条采用代码控制,拖动滚动条的位置计算要显示的数据,然后从数据库取出相应的数据。第二版主要存在问题是每次滚动鼠标都会发起请求加载数据,并且每次请求的数据都会覆盖已经加载的数据,在加载过程中使用遮罩禁止重复滚动加载数据。以上问题使得用户体验很差,所以我临时接手进行了第二次优化。
思路:
1.针对每个项目的需求和任务,在第一次访问的时候,将当前访问的项目的全部需求和任务树型结构组织好并缓存起来,缓存过期时间控制在2-4小时(依数据量和内存大小灵活设置),注意采用indexMap.put(i++, row);的形式,这样方便后期分屏加载。row的定义为Map<String, Object> row ;//Object可存需求和任务,通过key区分。
2.获取查询条件,如果为空,则从数据库取最后一次保存的查询条件,否则保存最新查询条件。
3.通过遍历indexMap,统计满足条件的需求和任务数量。
4.返回框架页面,并发送ajax请求真实数据。
5.对请求分页处理,分页大小控制在一次请求50条,太大页面渲染时间慢,太小又需较多次加载。遍历indexMap,取出满足分页条件和查询条件的数据,返回给客户端。
6.页面滚动到末尾,自动发起ajax加载后面的数据。
通过瀑布流的形式,解决了树型结构的分页问题,不用一次全部取出数据,使用缓存,提高加载速度。通过第三次优化。用户体验得到了较大提升。
注意点:使用原生ajax返回50条数据拼接到原有数据末尾的时候,ie容易内存溢出。
部分关键代码:
/**
判断最后一行是否进入可视区域
obj:有滚动条的容器box
lastRow:最后一行
**/
function see(obj, lastRow){
if(obj && lastRow){
var seeHeight = document.documentElement.clientHeight || document.body.clientHeight;//可视高度
var winScroll = obj.scrollTop;//获取滚动条当前位置
var lastSee = obj.scrollHeight;//最后一行
return lastSww< (seeHeight + winScroll)?true:false;
}else{
return true;
}
}
/**
将ajax数据拼接到页面末尾
**/
function append(parent, text){
if(typeof text ==='string'){
var temp = document.createElement('div');
temp.innerHTML = text;
var frag = document.createDocumentFragment();
while(temp.firstChild){
frag.appendChild(temp.firstChild);
}
parent.appendChild(frag);
delete temp;
delete frag;
CollectGarbage();
}
}
/**
组织treeIndex
**/
... ...
int i = 0;
for(ProjectDemand mode: items){
Map<String, Object> row = new HashMap<String, Object>();
if(attachMap.get(mode.getId())!=null){
mode.setArrachmetCount(attachMap.get(mode.getId()));
}
row.put.("demand", mode);
indexMap.put(i++, row);
if(ScrumTaskMap.get(mode.getId())!=null){
List<Task> tasklist = scrumTaskMap.get(mode.getId());
for(Task task : tasklist){
Map<String, object> rowTask = new HashMap<String, Object>();
rowTask.put("task", task);
indexMap.put(i++, rowTask);
}
}
}
/**
统计需求和任务数量
**/
private String projectDemandStatistics(Map indexMap, Map<String,String> filter, Map<integer, FormBase> showDemandAll, Map<Integer, Task> showTaskAll ){
int demandAllCount=0;
int leafCount=0;
int taskCount = 0;
int allCount = indexMap.size();
FormBase demand = null;
FormBase tempDemand = null;
Task task = null;
Map<String, String>SignMap = SZSEUtils.getItemsSign(indexMap);
String showDemandFlag = TypeUtils.nullToString(filter.get("showDemandFlag"));
Map<Integer, FormBase> iteredDemand = new HashMap();//已遍历需求
for(int i=0; i<allCount;i++){
Map<String, Object> row = (Map<String, Object>) indexMap.get(i);
if(row==null) break;
if(row.get("demand")!=null){
demand = (FormBase) row.get("demand");
iteredDemand.put(demand.getId(), demand);
if(isShowDemand(filter, demand)){\
if(showDemandAll!=null) showDemandAll.p;ut(demand.getId(), demand);//在这里记录要显示的需求map,供任务显示与否判断时用
demandAllCount++;
if(!"+".equals(signMap.get(demand.getId()+""))){
leafCount++;
}
//拾遗父需求
tempDemand = demand;
while(showDemandAll !=null
&& SZSEUtils.isNotEmpty(tempDemand.getNum01())
&& !"0".equals(tempDemand.getNum01())
&&showDemandAll.get(TypeUtils.nullToInt(tempDemand.getNum01()))==null){
tempDemand = itereDemand.get(Typeutils.nullToInt(tempDemand.getNum01()));
showDemandAll.put(tempDemand.getId(), tempDemand);
demandAllCount++;
if(!"+".equals(signMap.get(tempDemand.getId()+""))){
leafCount++;
}
}
}
}else if("true".equals(showDemandFlag)){//显示任务
task = (Task) row.get("taskId");
if(isShowTask(filter, task)){
int parentID = TypeUtils.nullToInt(task.getStr07());
if(showDemandAll!=null && showDemandAll.get(parentID)!=null){//如果需求不显示,则任务也不显示
showTaskAll.put(task.getId9), task);
taskCount++;
}
}
}
}
String countMessage = "共"+ demandAllCount +"个需求,共"+leafCount+"个叶子需求";
if("true".equals(showDemandFlag)) countMessage +="; 共"+taskCount+"个任务";
countMessage+=".";
return countMessage;
}
java树型结构的数据展现设计的更多相关文章
- dzzoffice的树型结构用户管理设计
在DzzOffice1.1的开发中,针对用户使用群体重新设计了,机构.部门.用户管理应用. 传统OA,企业相关程序,一般是设置机构-设置部门-设置职位-添加用户这样的步骤.每个步骤分为不同的管理界面. ...
- JSP中的一个树型结构
看方力勋的javaWeb,采用左右值来表示树型结构(就是俺门的多级分类)表结构 页面代码 <%@ page language="java" import="java ...
- 20-Ubuntu-文件和目录命令-查看目录树型结构-tree
tree 以树状图列出当前目录下的文件目录结构 选项 含义 -d 只显示当前目录的子目录树型结构 显示当前目录的子目录和文件树型结构 例: 1.查看文档目录下的子目录和文件树型结构 2.查看文档目 ...
- 分享使用NPOI导出Excel树状结构的数据,如部门用户菜单权限
大家都知道使用NPOI导出Excel格式数据 很简单,网上一搜,到处都有示例代码. 因为工作的关系,经常会有处理各种数据库数据的场景,其中处理Excel 数据导出,以备客户人员确认数据,场景很常见. ...
- Java实现树形结构的数据转Json格式
在项目中难免会用到树形结构,毕竟这是一种常用的组织架构.楼主这里整理了两个实现的版本,可以直接拿来使用,非常方便. 楼主没有单独建项目,直接在以前的一个Demo上实现的.第一种,看下面代码: pack ...
- java实现树型结构样式
import javax.swing.*; import javax.swing.event.*; import javax.swing.tree.*; public class Root exten ...
- java树状结构之二叉树
参考:http://blog.csdn.net/zhangerqing/article/details/8822476 前面已经提到过树和二叉树的相关概念内容,下面主要来介绍下关于二叉树的创建,遍历, ...
- Delphi实现树型结构
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...
- Delphi实现树型结构具体实例
unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, ...
随机推荐
- epoll 的accept , read, write
http://www.ccvita.com/515.html 在一个非阻塞(fcntl)的socket上调用read/write函数, 返回EAGAIN或者EWOULDBLOCK(注: EAGAIN就 ...
- 戴尔iDRAC服务器远程控制设置
对于远程的服务器,我们不能经常性的去机房维护,所以远程控制对于服务器来说就显得至关重要.那么你是用什么方式对服务器进行远程控制呢?远程桌面?还是KVM切换器?NO,你OUT了!如果你用的是戴尔的服务器 ...
- Centos6.4安装Zimbra初步教程
环境: 1.centos6.4*64位版本 2.主机最好内存设置在2G以上,要不安装的时候卡死你 3.下载最新的开源的Zimbra安装包,下载zcs-8.0.4_GA_5737.RHEL6_64.20 ...
- 深度学习-theano-windows -cuda-环境搭建
本文将具体介绍深度学习之cuda的环境搭建 工具:支持CUDA的显卡(安装cuda6.5),VS2013.Anaconda. 步骤: 1.安装cuda6.5 这个不具体介绍,网上有很多文章.注意选择你 ...
- HDU 5407 CRB and Candies(LCM +最大素因子求逆元)
[题目链接]pid=5407">click here~~ [题目大意]求LCM(Cn0,Cn1,Cn2....Cnn)%MOD 的值 [思路]来图更直观: 这个究竟是怎样推出的.说实话 ...
- You don't have permission to access ××× on this server.
之前开发项目一直在linux上用的xampp集成环境,前几天突然想移到window上面去. 開始在window上安装了一个集成环境(名字大概是 Uniform Service),把项目文件已过去, o ...
- Thinkphp中使用PHPmailer发送邮件
在ThinkPHP\Extend\Vendor\目录下放入PHPMailer文件夹,里面包含以下文件 重置密码发送邮件 public function recover(){ if($this-> ...
- YII2 的授权(Authorization)
说明:翻译本不是我应该做的,由于我的英语水平实在太差.但由于对YII的兴趣.所以也做一点.同一时候也能显示出我的胆量还是有的...希望不误导您. 由于这里MD语法的内容显示不全.您能够去这里看看. A ...
- Oracle中长度为0字符串与null等价
不试不知道,Oracle中,长度为0的字符串'' 居然与null等价! 众所周知,null代表空,什么都不存在,而一个字符串'',虽然长度为0,但毕竟已经是一个字符串,二者怎么能等价,混为一谈呢. 在 ...
- SDK Manager配置
改Host的都是扯淡,现在不好使了.. 还是使用东软的国内镜像好使,打开SDK Manager Tools - Options Http proxy Server: mirrors.neusoft. ...