引言
本文适用于 echarts4.0 版本,官网中没有自动展开树图和异步获取的实例,所以分享一篇可自动加载展开节点的文章,希望对大家有所帮助并融合到自己项目中。
图中节点样式可通过数据中进行设置,详情请参照官网:
https://echarts.apache.org/
本文实例下载地址:
https://pan.baidu.com/s/16C6qJntiJWi_ceEoiYasMw
准备文件
- tree.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ECharts</title>
<!-- 引入 echarts.js 此处改为自己的引用路径或使用线上地址-->
<script src="echarts.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="tree.js"></script>
</head>
<body>
<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<div id="main" style="width: 100%;height:741px;"></div>
</body>
</html>
- tree.js
//缓存全局的 图形 option 对象
var _option;
var myChart;
$(function(){
initcharts();
function initcharts(){
var main_div = document.getElementById('main');
// 基于准备好的dom,初始化echarts实例
myChart = echarts.init(main_div);
myChart.showLoading();
myChart.on('click', 'series', clickFun);
myChart.setOption(getoption());
}
function getoption(){
var option;
$.ajaxSettings.async = false;
$.get('echartsTree.json', function (data) {
myChart.hideLoading();
echarts.util.each(data.children, function (datum, index) {
index % 2 === 0 && (datum.collapsed = true);
});
option = {
tooltip: {
trigger: 'item',
triggerOn: 'mousemove',
formatter:function(params, ticket, callback){
return params.data.name;
}
},
series: [
{
type: 'tree',
data: [data],
top: '1%',
left: '7%',
bottom: '1%',
right: '20%',
symbolSize: 7,
initialTreeDepth:1,//展开层级为一层
/*layout:'radial',
symbol: 'emptyCircle',*/
label: {
normal: {
position: 'top',
verticalAlign: 'middle',
align: 'right',
fontSize: 20,
//color:'yellow'
}
},
leaves: {
label: {
normal: {
position: 'right',
verticalAlign: 'middle',
align: 'left'
}
}
},
expandAndCollapse: true,
animationDuration: 550,
animationDurationUpdate: 750
}
]
}
});
return option;
}
setInterval(function () {
reloadNode();
}, 3000);
/**
* 1、取到根节点数据,判断是否全部展示完成,完成则销毁图形,重新构建一个新的树
* 2、逐级取节点,判断节点时候展开,未展开则展开数据,取到子节点数据,递归使用该步骤,判断无子节点后本节节点添加完成
* 标识,该步骤为核心步骤
* 3、得到节点有完成标识则跳过,取下一条节点继续走第二步,同级节点没有下一节点是,将父级节点添加完成标识
* 4、取子节点数据,返回为空则直接继续第二步,继续展示数据,不为空则跳出循环完成本次操作,展示数据,等待下次任务开始
* 5、图形自身得到子数据,没有完成标识则展开,添加完成标识后,结束本次操作
* @constructor
*/
function reloadNode(){
_option = myChart.getOption();
var root = _option.series[0].data[0];
//本次操作节点
var operatingnode = getOperatingNode();
//没有操作节点则重新构建图形
if($.isEmptyObject(operatingnode)){
var option = getoption();
myChart.setOption(option)
return;
}
//操作节点下有子数据
if(operatingnode.children && operatingnode.children.length > 0){
//展开子节点
expandNode(operatingnode);
return;
}
//操作节点名称
var operatingnodename = operatingnode.name;
//分布获取的子数据信息
var childrenData = getDataByNode(operatingnodename);
//没有子数据添加完成标识
if($.isEmptyObject(childrenData)){
addCompleteIdent(operatingnode);
reloadNode();
return;
}
//得到子数据,展开子数据
operatingnode.children = childrenData;
//展开子节点
expandNode(operatingnode);
}
//得到本次操作节点
function getOperatingNode(){
//根节点
var root = _option.series[0].data[0];
//未完成节点
var undonenode = getUndoneNode(root);
if(root.completeident){ //检查是否展开完成
return null;
}
//未完成节点不为空直接返回该节点
if($.isEmptyObject(undonenode) === false){
return undonenode;
}
return getOperatingNode();
}
//获取未完成节点,设置已完成节点父节点为完成
function getUndoneNode(node){
//取节点子节点信息
var nodearr = node.children;
var lebgth = nodearr.length || '';
//将对象转化为单一数组
if(lebgth == ''){
nodearr = [nodearr];
}
var currentNode = null;
for (var i = 0 , len = nodearr.length; i < len; i++) {
currentNode = nodearr[i];
//该节点数据已展示完成则继续下一次循环
if(currentNode.completeident){
continue;
}
//该节点下有子节点,则取子节点未完成数据
if(currentNode.children){
return getUndoneNode(currentNode);
}
return currentNode;
}
//子节点全部完成,设置父节点为完成
addCompleteIdent(node);
return null;
}
//关闭树节点
function collapseNode(node){
node.hasChild = true;
node.collapsed = true;
//chart 刷新重新加载
myChart.setOption(_option);
}
//展开树节点
function expandNode(node){
node.hasChild = false;
node.collapsed = false;
//chart 刷新重新加载
myChart.setOption(_option);
}
//为节点添加完成标识
function addCompleteIdent(node) {
if($.isEmptyObject(node)){
return;
}
//completeident: 该字段为记录完成标识
node.completeident = true;
//chart 刷新重新加载
myChart.setOption(_option);
}
//树点击事件
function clickFun(param) {
//存在节点数据时,点击表示关闭
if(param.data.children && param.data.children.length > 0){
//root节点会在refresh时读children的length
if(param.data.collapsed){
param.data.hasChild = false;
param.data.collapsed= false;
}else{
param.data.hasChild = true;
param.data.collapsed= true;;
}
}else{
var nodedata = getDataByNode(param.data.name);
param.data.children = nodedata;
//设置节点展开
param.data.hasChild =false;
param.data.collapsed=false;
}
//chart 刷新重新加载
var option = myChart.getOption();
myChart.setOption(option);
}
//模拟分步请求数据加载
function getDataByNode(name){
var nodeData = null;
$.ajaxSettings.async = false;
$.get('businessData.json', function (data) {
nodeData = data[name];
},'json')
if($.isArray(nodeData)){
return nodeData;
}
if($.isEmptyObject(nodeData)){
return null
}
return [nodeData];
}
});
- echartsTree.json
本文件为数据构造文件,数据初始化所用到的数据对象
{
"name": "flare",
"itemStyle": {
"color": "blue"
},
"children": [
{
"name": "analytics"
},
{
"name": "animate"
},
{
"name": "data"
},
{
"name": "display"
},
{
"name": "flex"
},
{
"name": "physics"
},
{
"name": "query"
},
{
"name": "scale"
},
{
"name": "util"
},
{
"name": "vis"
}
]
}
- businessData.json
节点分部获取展开数据,由于是 Demo 实例,自定义的数据获取结构。
{
"analytics": [{"name": "analytics001","value": "001"},{"name": "analytics002","value": "002"}],
"animate": [{"name": "animate001","value": "001"},{"name": "animate002","value": "002"}],
"data": [{"name": "data001","value": "001"},{"name": "data002","value": "002"}],
"display": [{"name": "display001","value": "001"},{"name": "display002","value": "002"}],
"flex":[{"name": "flex001","value": "001"},{"name": "flex002","value": "002"}],
"physics":[{"name": "physics001","value": "001"},{"name": "physics002","value": "002"}],
"query":[{"name": "query001","value": "001"},{"name": "query002","value": "002"}],
"scale":[{"name": "scale001","value": "001"},{"name": "scale002","value": "002"}],
"util":[{"name": "util001","value": "001"},{"name": "util002","value": "002"}],
"vis":[{"name": "vis001","value": "001"},{"name": "vis002","value": "002"}],
"analytics001":{"name": "analytics0011","value": "0011"},
"animate001":[{"name": "animate0011","value": "0011"},{"name": "animate0022","value": "0022"}],
"data001":[{"name": "data0011","value": "0011"},{"name": "data0022","value": "0022"}],
"display001":[{"name": "display0011","value": "0011"},{"name": "display0022","value": "0022"}],
"flex001":[{"name": "flex0011","value": "0011"},{"name": "flex0022","value": "0022"}],
"physics001":[{"name": "physics0011","value": "0011"},{"name": "physics0022","value": "0022"}],
"query001":[{"name": "query0011","value": "0011"},{"name": "query0022","value": "0022"}],
"scale001":[{"name": "scale0011","value": "0011"},{"name": "scale0022","value": "0022"}],
"util001":[{"name": "util0011","value": "0011"},{"name": "util0022","value": "0022"}],
"vis001":{"name": "vis0011","value": "0011"},
"data0011":{"name": "data00111","value": "00111"},
"query0011":{"name": "query00111","value": "00111"},
"vis0011":{"name": "vis00111","value": "00111","itemStyle":{"color": "blue"}}
}
新人博客,望大家多多指教,谢谢观看。