t对需要数据进行分析
需要过滤的数据是一个数组,该数组中每条数据都是由name$$ID$$parentID$$status$$type
,需要实现根据相关状态值进行筛选,筛选完成后,对于没有叶子结点的分类菜单,需要移出,不在树上展示。
name | ID | parentID | status | type |
---|---|---|---|---|
该条数据名称 | 该条数据Id号 | 该条数据的父ID | 数据的状态(共四种) | 数据的分类(1表示菜单,0表示叶子结点) |
思路分析
经过对数据的分析,可以看出来这些记录组成的数据是一种逻辑上的链表结构,由叶子结点(type为0)可以逐级向上查找父节点,父节点在向上查找父节点,直到父节点的parentID为0。
要想让菜单栏底下没有叶子结点时,菜单栏不在树上展示,同时考虑到父节点与叶子节点的数据类型一致,所以考虑现根据type把过滤数据划分为父节点数组和叶子结点数组,然后从叶子节点数组开始遍历,通过parentID在父节点数组中遍历如果父节点中有该数据则添加到过滤数组,叶子节点则直接添加到过滤数组,所有遍历结束,则可以获得拥有叶子结点的数据。由于一些叶子结点拥有相同的父节点,所有最后需要对过滤的数组去重,最后就可以实现了。
根据四种状态过滤数据
- 首先,在html页面上添加四个input输入框,分别对应四种状态,添加一个按钮,用来查询过滤,定义树结构div。
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#search {
background-color: #618CE2FF;
margin-left: 5px;
background-repeat: no-repeat;
background-position: 25px center;
padding: 6px 20px;
padding-left: 25px;
padding-right: 25px;
border-radius: 4px;
color: #FFFFFFFF;
text-align: center;
height: 33px;
font-size: 14px;
font-family: MicrosoftYaHei;
font-weight: bold;
border-color: rgba(255, 255, 255, 0);
}
</style>
</head>
<body style="background-color: darkgrey">
<div>
<span>状态:</span>
<span>
<span style="margin-left: 30px">
<input type="checkbox" id="notrun" name="checkboxBug" value="0">
<label for="notrun">未运行</label>
</span>
<span style="margin-left: 30px">
<input type="checkbox" id="notslove" name="checkboxBug" value="1">
<label for="notslove">未解决</label>
</span>
<span style="margin-left: 30px">
<input type="checkbox" id="solve" name="checkboxBug" value="2">
<label for="solve">解决</label>
</span>
<span style="margin-left: 30px">
<input type="checkbox" id="run" name="checkboxBug" value="3">
<label for="run">已运行</label>
</span>
</span>
<span id="search" class="btn btn-primary" style="margin-left: 30px">查询</span>
</div>
<div class="col-lg-3 col-md-3 col-sm-3 col-xs-3 col-pad-3 change-width3" style="width: 21%;">
<div class="border_left" style="overflow: auto;min-height: 800px;max-height: 1000px;margin-bottom: 30px;">
<div id="tree"></div>
</div>
</div>
- 声明数据
var data = ['I$$0$$1$$0$$1',
'love$$1$$2$$0$$1',
'yq$$2$$3$$0$$0',
'nn$$0$$4$$0$$1',
'cc$$4$$5$$3$$0',
'fool$$2$$6$$3$$0',
'hahha$$1$$7$$3$$0',
'aha$$1$$8$$3$$0',
'ok$$1$$9$$3$$0',
'baby$$1$$10$$3$$0',
'bye$$1$$11$$1$$0',
'heartForYou$$1$$12$$1$$0',
'love_with_you$$1$$13$$3$$0',
'wo$$1$$14$$3$$0',
'heart$$1$$15$$1$$0',
'love$$2$$16$$3$$0',
'mps$$2$$17$$3$$0'
];
- 根据输入框进行第一轮数据过滤
var notrun = false;
var notrun_code = -1;
$("#notrun").prop("checked", true);
$("#notslove").prop("checked", true);
$("#solve").prop("checked", true);
$("#run").prop("checked", true);
var obj = document.getElementById("notrun");
notrun = obj.checked;
if (notrun == true) {
notrun_code = $('#notrun').val();
} else {
notrun_code = -1;
}
$('#notrun').on('click', function () {
var obj = document.getElementById("notrun");
notrun = obj.checked;
if (notrun == true) {
notrun_code = $('#notrun').val();
} else {
notrun_code = -1;
}
})
var notslove = false;
var notslove_code = -1;
var obj = document.getElementById("notslove");
notslove = obj.checked;
if (notslove == true) {
notslove_code = $('#notslove').val();
} else {
notslove_code = -1;
}
$('#notslove').on('click', function () {
var obj = document.getElementById("notslove");
notslove = obj.checked;
if (notslove == true) {
notslove_code = $('#notslove').val();
} else {
notslove_code = -1;
}
})
var solve_code = -1;
var solve = false;
var obj = document.getElementById("solve");
solve = obj.checked;
if (solve == true) {
solve_code = $('#solve').val();
} else {
solve_code = -1;
}
$('#solve').on('click', function () {
var obj = document.getElementById("solve");
solve = obj.checked;
if (solve == true) {
solve_code = $('#solve').val();
} else {
solve_code = -1;
}
})
var run_code = -1;
var run = false;
var obj = document.getElementById("run");
run = obj.checked;
if (run == true) {
run_code = $('#run').val();
} else {
run_code = -1;
}
$('#run').on('click', function () {
var obj = document.getElementById("run");
run = obj.checked;
if (run == true) {
run_code = $('#run').val();
} else {
run_code = -1;
}
})
$('#search').on('click', function () {
var filter = {};
filter['code'] = 1;
filter['not_run'] = notrun_code;
filter['run'] = run_code;
filter['not_solve'] = notslove_code;
filter['solve'] = solve_code;
initTree(filter)
})
var filter = {};
filter['code'] = 1;
filter['not_run'] = notrun_code;
filter['run'] = run_code;
filter['not_solve'] = notslove_code;
filter['solve'] = solve_code;
if (condition['not_run'] != -1) {
var not_run = condition['not_run'];
}
if (condition['run'] != -1) {
var run = condition['run'];
}
if (condition['not_solve'] != -1) {
var not_solve = condition['not_solve'];
}
if (condition['solve'] != -1) {
var solve = condition['solve'];
}
var type_filter = [];
for (let i in data) {
let temp = data[i].split("$$");
if (temp[4] == 1) {
type_filter.push(data[i]);
} else {
var code = data[i].split("$$")[3];
// console.log(code);
if (not_run == code || run == code || not_solve == code || solve == code) {
type_filter.push(data[i]);
}
}
}
- 数据过滤后,先把数据转换成一个json文件,在根据文件中的id来定义字典集合
let info = [];
for (let i in type_filter) {
let temp = type_filter[i].split("$$");
if (temp[1] == "0") {
info[i] = {
Id: parseInt(temp[2]),
text: temp[0],
status: temp[3],
type: temp[4]
};
} else {
info[i] = {
Id: parseInt(temp[2]),
text: temp[0],
parent: temp[1],
status: temp[3],
type: temp[4]
};
}
}
let map = {};
info.forEach(item => {
map[item.Id] = item;
});
- 将数据划分为父节点和叶子节点数组
var type = [];
var leaf = [];
for (let j = 0; j < info.length; j++) {
if (info[j].type == 1) {
type.push(info[j]);
} else if (info[j].type == 0) {
leaf.push(info[j]);
}
}
- 把包含叶子结点的父节点以及叶子节点放到过滤数组中,并利用set去重
var filter_data = [];
leaf.forEach(item => {
filter_data.push(item);
let parent = map[item.parent];
if (parent != undefined) {
filter_data.push(parent);
type.forEach(info => {
if (parent.parent != undefined) {
parent = map[parent.parent];
filter_data.push(parent);
}
})
}
})
unique(filter_data);
function unique(arr) {
return Array.from(new Set(arr))
}
function toTree(data) {
let result = []
if (!Array.isArray(data)) {
return result
}
data.forEach(item => {
delete item.nodes;
});
let map = {};
data.forEach(item => {
map[item.Id] = item;
});
data.forEach(item => {
let parent = map[item.parent];
if (parent) {
(parent.nodes || (parent.nodes = [])).push(item);
} else {
result.push(item);
}
});
for (let i = 0; i < result.length; i++) {
if (result[i].type = 1 && result[i].nodes == undefined) {
result.splice(i);
}
}
console.log(result)
return result;
}
- 将过滤后的数据转化为树结构
let treeData = toTree(unique(filter_data));
function toTree(data) {
let result = []
if (!Array.isArray(data)) {
return result
}
data.forEach(item => {
delete item.nodes;
});
let map = {};
data.forEach(item => {
map[item.Id] = item;
});
data.forEach(item => {
let parent = map[item.parent];
if (parent) {
(parent.nodes || (parent.nodes = [])).push(item);
} else {
result.push(item);
}
});
for (let i = 0; i < result.length; i++) {
if (result[i].type = 1 && result[i].nodes == undefined) {
result.splice(i);
}
}
console.log(result)
return result;
}
- 前端加载树结构数据
$('#tree').treeview({
data: treeData,
highlightSelected: true,// 选中项不高亮,避免和上述制定的颜色变化规则冲突
multiSelect: false,// 不允许多选,因为我们要通过check框来控制
showCheckbox: false,// 展示checkbox
collapsed: true,//收缩全部节点
onhoverColor: "#f5f5f5", //鼠标滑过的颜色
levels: 1, // 展开级别 Default: 2
selectedBackColor: "pink",
onNodeSelected: function (event, data) {
let id = data.id;
let nodes = data.nodes;
if (nodes == undefined) {
alert("这是节点:"+ data.text)
} else {
// console.log( $("#tree").find("ul > li> span").eq(0).attr("class"));
// $("#tree").find("ul > li> span").eq(0).attr("class", "")
// $("#tree").find("ul > li> span").eq(0).html(`
// <img src = "/images/icon_new/7-加.png" style="margin-top:-5px;"/>
// `)
let select_node = $('#tree').treeview('getSelected');
if (select_node[0].state.expanded) {
$('#tree').treeview('collapseNode', select_node);
select_node[0].state.selected = false;
} else {
$('#tree').treeview('expandNode', select_node);
select_node[0].state.selected = false;
}
}
}
});
}
-
效果图:
-
才进入
-
按要求搜索
-
完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#search {
background-color: #618CE2FF;
margin-left: 5px;
background-repeat: no-repeat;
background-position: 25px center;
padding: 6px 20px;
padding-left: 25px;
padding-right: 25px;
border-radius: 4px;
color: #FFFFFFFF;
text-align: center;
height: 33px;
font-size: 14px;
font-family: MicrosoftYaHei;
font-weight: bold;
border-color: rgba(255, 255, 255, 0);
}
</style>
</head>
<body style="background-color: darkgrey">
<div>
<span>状态:</span>
<span>
<span style="margin-left: 30px">
<input type="checkbox" id="notrun" name="checkboxBug" value="0">
<label for="notrun">未运行</label>
</span>
<span style="margin-left: 30px">
<input type="checkbox" id="notslove" name="checkboxBug" value="1">
<label for="notslove">未解决</label>
</span>
<span style="margin-left: 30px">
<input type="checkbox" id="solve" name="checkboxBug" value="2">
<label for="solve">解决</label>
</span>
<span style="margin-left: 30px">
<input type="checkbox" id="run" name="checkboxBug" value="3">
<label for="run">已运行</label>
</span>
</span>
<span id="search" class="btn btn-primary" style="margin-left: 30px">查询</span>
</div>
<div class="col-lg-3 col-md-3 col-sm-3 col-xs-3 col-pad-3 change-width3" style="width: 21%;">
<div class="border_left" style="overflow: auto;min-height: 800px;max-height: 1000px;margin-bottom: 30px;">
<div id="tree"></div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
</body>
<script src="bootstrap-treeview.js"></script>
<!--<script src="layui/layui.all.js"></script>-->
<script>
$(document).ready(function () {
var data = ['I$$0$$1$$0$$1',
'love$$1$$2$$0$$1',
'yq$$2$$3$$0$$0',
'nn$$0$$4$$0$$1',
'cc$$4$$5$$3$$0',
'fool$$2$$6$$3$$0',
'hahha$$1$$7$$3$$0',
'aha$$1$$8$$3$$0',
'ok$$1$$9$$3$$0',
'baby$$1$$10$$3$$0',
'bye$$1$$11$$1$$0',
'heartForYou$$1$$12$$1$$0',
'love_with_you$$1$$13$$3$$0',
'wo$$1$$14$$3$$0',
'heart$$1$$15$$1$$0',
'love$$2$$16$$3$$0',
'mps$$2$$17$$3$$0'
];
var notrun = false;
var notrun_code = -1;
$("#notrun").prop("checked", true);
$("#notslove").prop("checked", true);
$("#solve").prop("checked", true);
$("#run").prop("checked", true);
var obj = document.getElementById("notrun");
notrun = obj.checked;
if (notrun == true) {
notrun_code = $('#notrun').val();
} else {
notrun_code = -1;
}
$('#notrun').on('click', function () {
var obj = document.getElementById("notrun");
notrun = obj.checked;
if (notrun == true) {
notrun_code = $('#notrun').val();
} else {
notrun_code = -1;
}
})
var notslove = false;
var notslove_code = -1;
var obj = document.getElementById("notslove");
notslove = obj.checked;
if (notslove == true) {
notslove_code = $('#notslove').val();
} else {
notslove_code = -1;
}
$('#notslove').on('click', function () {
var obj = document.getElementById("notslove");
notslove = obj.checked;
if (notslove == true) {
notslove_code = $('#notslove').val();
} else {
notslove_code = -1;
}
})
var solve_code = -1;
var solve = false;
var obj = document.getElementById("solve");
solve = obj.checked;
if (solve == true) {
solve_code = $('#solve').val();
} else {
solve_code = -1;
}
$('#solve').on('click', function () {
var obj = document.getElementById("solve");
solve = obj.checked;
if (solve == true) {
solve_code = $('#solve').val();
} else {
solve_code = -1;
}
})
var run_code = -1;
var run = false;
var obj = document.getElementById("run");
run = obj.checked;
if (run == true) {
run_code = $('#run').val();
} else {
run_code = -1;
}
$('#run').on('click', function () {
var obj = document.getElementById("run");
run = obj.checked;
if (run == true) {
run_code = $('#run').val();
} else {
run_code = -1;
}
})
$('#search').on('click', function () {
var filter = {};
filter['code'] = 1;
filter['not_run'] = notrun_code;
filter['run'] = run_code;
filter['not_solve'] = notslove_code;
filter['solve'] = solve_code;
initTree(filter)
})
var filter = {};
filter['code'] = 1;
filter['not_run'] = notrun_code;
filter['run'] = run_code;
filter['not_solve'] = notslove_code;
filter['solve'] = solve_code;
initTree(filter);
function initTree(condition) {
if (condition['not_run'] != -1) {
var not_run = condition['not_run'];
}
if (condition['run'] != -1) {
var run = condition['run'];
}
if (condition['not_solve'] != -1) {
var not_solve = condition['not_solve'];
}
if (condition['solve'] != -1) {
var solve = condition['solve'];
}
var type_filter = [];
for (let i in data) {
let temp = data[i].split("$$");
if (temp[4] == 1) {
type_filter.push(data[i]);
} else {
var code = data[i].split("$$")[3];
// console.log(code);
if (not_run == code || run == code || not_solve == code || solve == code) {
type_filter.push(data[i]);
}
}
}
let info = [];
for (let i in type_filter) {
let temp = type_filter[i].split("$$");
if (temp[1] == "0") {
info[i] = {
Id: parseInt(temp[2]),
text: temp[0],
status: temp[3],
type: temp[4]
};
} else {
info[i] = {
Id: parseInt(temp[2]),
text: temp[0],
parent: temp[1],
status: temp[3],
type: temp[4]
};
}
}
var type = [];
var leaf = [];
for (let j = 0; j < info.length; j++) {
if (info[j].type == 1) {
type.push(info[j]);
} else if (info[j].type == 0) {
leaf.push(info[j]);
}
}
let map = {};
info.forEach(item => {
map[item.Id] = item;
});
var filter_data = [];
leaf.forEach(item => {
filter_data.push(item);
let parent = map[item.parent];
if (parent != undefined) {
filter_data.push(parent);
type.forEach(info => {
if (parent.parent != undefined) {
parent = map[parent.parent];
filter_data.push(parent);
}
})
}
})
let treeData = toTree(unique(filter_data));
$('#tree').treeview({
data: treeData,
highlightSelected: true,// 选中项不高亮,避免和上述制定的颜色变化规则冲突
multiSelect: false,// 不允许多选,因为我们要通过check框来控制
showCheckbox: false,// 展示checkbox
collapsed: true,//收缩全部节点
onhoverColor: "#f5f5f5", //鼠标滑过的颜色
levels: 1, // 展开级别 Default: 2
selectedBackColor: "pink",
onNodeSelected: function (event, data) {
let id = data.id;
let nodes = data.nodes;
if (nodes == undefined) {
alert("这是节点:"+ data.text)
} else {
// console.log( $("#tree").find("ul > li> span").eq(0).attr("class"));
// $("#tree").find("ul > li> span").eq(0).attr("class", "")
// $("#tree").find("ul > li> span").eq(0).html(`
// <img src = "/images/icon_new/7-加.png" style="margin-top:-5px;"/>
// `)
let select_node = $('#tree').treeview('getSelected');
if (select_node[0].state.expanded) {
$('#tree').treeview('collapseNode', select_node);
select_node[0].state.selected = false;
} else {
$('#tree').treeview('expandNode', select_node);
select_node[0].state.selected = false;
}
}
}
});
}
})
function unique(arr) {
return Array.from(new Set(arr))
}
function toTree(data) {
let result = []
if (!Array.isArray(data)) {
return result
}
data.forEach(item => {
delete item.nodes;
});
let map = {};
data.forEach(item => {
map[item.Id] = item;
});
data.forEach(item => {
let parent = map[item.parent];
if (parent) {
(parent.nodes || (parent.nodes = [])).push(item);
} else {
result.push(item);
}
});
for (let i = 0; i < result.length; i++) {
if (result[i].type = 1 && result[i].nodes == undefined) {
result.splice(i);
}
}
console.log(result)
return result;
}
</script>
</html>