echarts树状图中的不同层级之间json的数据处理

  • 2020-03-23
    最近由于疫情的原因,在家里快闷坏了…
    这么久没更新是因为在做一些设计上的工作,技术上遇到的问题比较少,今天又遇到一个很有意思的需求,我拿出来给大家展示一下~


页面的最终效果是这样:
在这里插入图片描述



得到的json格式

这个需求的主要难点在json格式上,如果想得到上图的样式,那么按照echarts中树状图的官方标准格式应该是这样展示的:

{
        "name": "根元素",
        "children": [{
            "children": [{
				"name": '属性1',
				"value": '1'
			},{
				"name": '属性2',
				"value": '1'
			},{
				"name": '属性3',
				"value": '1'
			},{
				"name": '属性4',
				"value": '1'
			}],
            "name": "子元素1"
       	},{
            "children": [{
                "children": [{
					"name": '属性1',
					"value": '1'
				},{
					"name": '属性2',
					"value": '1'
				},{
					"name": '属性3',
					"value": '1'
				},{
					"name": '属性4',
					"value": '1'
				}],
                "name": "孙子元素"
           	}],
            "name": "子元素2"
        }]
}

但是我得到的接口数据是这样的:

{
        "name": "根元素",
        "children": [{
            "children": "属性1:1; 属性2:null; 属性3: null; 属性4:null; ",
            "name": "子元素1"
       	},{
            "children": [{
                "children": "属性1:1; 属性2:null; 属性3: null; 属性4:null; ",
                "name": "孙子元素"
           	}],
            "name": "子元素2"
        },{
            "children": [{
                "children": "属性1:1; 属性2:null; 属性3: null; 属性4:null; ",
                "name": "孙子元素1"
           	}],
            "children": [{
                "children": "属性1:1; 属性2:null; 属性3: null; 属性4:null; ",
                "name": "孙子元素2"
           	}],
            "name": "子元素3"
        },{
            "children": [{
	            "children": [{
	                "children": "属性1:1; 属性2:null; 属性3: null; 属性4:null; ",
	                "name": "重孙子元素"
	           	}],
                "name": "孙子元素"
           	}],
            "name": "子元素4"
        }]
}

由于后端同事使用的是map格式返回的数据,所以在格式上肯定是不对的,导致在echarts里面不能正确展示。总之,我们要先对这个json格式进行处理。



将map格式转换为对象数组

可以看到,接口中map返回的是字符串格式,那么先不考虑层级关系,我们先要把它转换成json格式。

//整理json格式 - 将map转换为对象数组
function collationFormat_mapToArr(data){
	//因为我的是字符串格式,我就使用截取字符串了
	//如果已经是json字符串格式,就可以用for(key in value)直接处理了
	var arr = data.split(';');
	var newArr = [];
	$(arr).each(function(i,item){
		if(item.indexOf(":") >= 0){
			var tex = item.split(':');
			var obj = {
				"name": tex[0],
				"value": tex[1]
			}
			newArr.push(obj);
		}
	})
	return newArr;
}

这样,我们就可以用这个方法将字符串转换为json对象了。
注意,要把这个方法单独拿出来写,因为处理层级关系时会有很多地方调用这个方法。



处理层级关系

格式已经处理好了,那么就要开始处理层级关系了。
最简单的马上能想到的方法是遍历节点,在每个children中判断并更改格式。
但是在这个案例中,children所有的层级不确定,有几个children也不确定,我们不能把循环写死,而且那样代码的行数也太多了,显然是不合理的。


那么我们先整理一下思路,画一个逻辑上的流程图。
Created with Raphaël 2.2.0 开始:拿到根节点 遍历child,拿到子节点 判断是否为map格式 将map转换为对象数组 获取下一个子节点 判断是否包括子元素 yes no yes no

(不太会用这个流程图哈,大家凑合看看)
然后当根元素遍历结束,我们就可以拿着这个数据画图了。


下面是代码部分,为了便于理解,我把打印的数据留着了,不需要的话可以删掉。

//首先 - 根节点中,遍历子节点
function collationFormat(data){
	for(var i = 0; i < data.children.length; i++){
		data.children[i] = collationFormat_typeof(data.children[i], i);
		console.log("    第" + i + "个根节点的child处理完成,当前格式为: ", data);
	}
	console.log("根节点处理完成数据: ",data);
	//当结束后调用echarts绘图方法。
	draw_chart(data);
}

//其次 - 判断child是否为map格式
function collationFormat_typeof(data, i){
	console.log(" ");
	console.log('    --------child判断 ' + i + '--------');
	if( typeof(data.children) == 'string'){
		//已经是最终节点,需要把map转换为对象数组
		data.children = collationFormat_mapToArr(data.children);
		console.log("    str转换结束,返回数据: ", data.children);
		return data;
	}else if( typeof(data.children) == 'object'){
		//里面还有子节点,需要再次遍历
		console.log("    子节点再次遍历", data);
		var newChild = collationFormat_eachChild(data);
		console.log("newChild: ",newChild);
		return newChild;
	}else{
		//undefined 没有子元素了
	}
}

//再次 - 如果子节点为object格式,则说明子节点内还包括孙子节点,则需要再次遍历child
//这个和根元素的遍历是一样的,但是在根元素遍历结束后需要调用画图方法,所以分开写了
//这里相当于一个循环嵌套,孙子元素和重孙子都会调用这个方法,直到没有map格式的为止
function collationFormat_eachChild(data){
	for(var i = 0; i < data.children.length; i++){
		data.children[i] = collationFormat_typeof(data.children[i], i);
	}
	console.log("        子节点遍历完成,返回数据为: ", data);
	return data;
}

以上就是代码部分了。
需要注意的是,这里我使用return返回值来修改源数据,所以return语句很重要,有用,不要删除。



  • ps: 我一开始还想为什么会这样返回给我接口数据,我问了一下后端同事,他说不这样的话会有什么冲突(反正我也没记住),然后我想,那好吧…我前端处理一下数据格式好了
    费了九牛二虎之力,终于改完之后我才觉得好像有哪里不对…然后我截图问后端同事,“你是想要这种效果吗?”
    后端同事答:“不是啊,这些属性在悬浮窗里面显示就可以了”
    我:“ !!!∑(゚Д゚ノ)ノ ”
    我同事:“ Σ(っ°Д°;)っ ”
    我:“… 那我改回来好了 (´¬`)… ”
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值