赞
踩
前面 用Echarts 制作一个数据库表的关联关系图(一) 中提到了几个问题,接下来一个一个解决。
目前项目背景为:左边是展示数据库表的 ztree 树,树的上面是一些对ztree 树进行操作的一些按钮,我的思路是在左边按钮区域添加一个按钮,选中树节点后(可支持多选),点击按钮后做添加操作。
- let [ ...temp ] = this.gData; // 节点的数据存在vuex state中
- temp.push({ // 保存节点的名字和ID
- name: nodes[0].name,
- value:nodes[0].tableId,
- x: 0,
- y: 0
- });
这样数据就保存起来了。
当节点变化时,在 commit 后,先计算节点个数,再计算每个点的坐标,计算坐标的核心代码如下:
- // 表格关联关系 节点坐标计算
- export function getXYbyCount(count,width,height){
- let w = width | 500;
- let h= height | 400;
- let centerX=(w-100)/2;
- let centerY =(h-100)/2;
- let r = centerX < centerY ? centerX:centerY;
- let pointX = 100+centerY;
- let pointY = 100+centerY;
- let point = [];
- for(let i=0;i<count;i++){
- point.push(
- {
- x:pointX-r*Math.cos(i*2*Math.PI/count),
- y:pointY-r*Math.sin(i*2*Math.PI/count)
- }
- );
- }
- return point;
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
不多说了,学过数学的都能看懂。
vue 中双向绑定必须绑定到 html 元素,才能用 watch 监控直接改变的 state ,如下所示:
- watch:{
- // 鉴定节点的变化 重新加载图表
- gData:function (val) {
- this.initGraph();
- }
- },
echarts 点击节点时,可以捕捉到点击事件,于是就可以设置个超时时间,把点击的节点记录下来,做连线,
- // 点击事件
- handleClick(handler) {
- // 判断是节点 还是 连线
- if(handler.dataType === 'node'){
- if(this.tableSchemas[handler.value] === undefined){
- this.getTableSchemaByid(handler.value);
- }
-
- // 判断是否已经存在节点
- if(_.indexOf(this.nodeArr,handler.name+"#"+handler.value) === -1){
- this.nodeArr.push(handler.name+"#"+handler.value);
- }
- // console.log(this.nodeArr);
- // 点击超时 清空
- setTimeout(()=>{
- this.nodeArr=[];
- },2000);
- // 点击了两个节点
- if(this.nodeArr.length >= 2){
- // 判断重复使用 两种组合方式 有连线了就不再连接了
- let lineValue1 = ''; // 该行和以下非真实代码
- let lineValue2 = '';
- let tmp = {
- source: sourceNode,
- target: targetNode,
- lineStyle: {
- normal: {
- width: 5,
- curveness: 0.2
- }
- },
- value:lineValue1
- };
-
- // 控制重复连线
- if( (_.indexOf(this.optionLinks,lineValue1) === -1) &&
- (_.indexOf(this.optionLinks,lineValue2) === -1) ){
- this.optionLinks.push(lineValue1);
- // 设置连线
- this.option.series[0].links.push(tmp);
- }
-
- this.myChart.setOption(this.option);
- this.nodeArr=[];
- }
- }
- else{
- if(this.allCondition[handler.value]){
- // 已经保存过条件处理逻辑
- }
- else {
- // 重新初始化 为了防止值重复 { 一些处理代码}
- // some code
- }
-
- }
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
当点击节点时候去请求并记录节点的信息。在本地保存临时变量,如果已存在该表格信息,就不再请求服务器。
用一个条件框,切换节点或者连线的时候做更新,效果
如图所示:
上图所示的弹出层,我们只需要一个,vue是数据驱动的,当连线切换时候,我们去更新数据就行,
- // 选择的所有关联条件
- allCondition:{},
-
- // 存放表的字段信息 key :tavleId value:schemas
- tableSchemas:{},
- // 选中表格1 的字段
- tableFirst:[],
- // 选中表格2 的字段
- tableSecond:[],
-
-
- // 当前连线的的信息
- currentItem:
- {
- count:1,
- // 起始表格名字
- tableSource:'',
- // 目标表格名字
- tableTarget:'',
- tableIds:'',
- // 表格直接的关联方式
- tableConnector:'INNER',
- data:[
- {
- itemId:1,
- tableFirstId:'tableFirstId1',
- tableRightId:'tableRightI1',
- },
- ]
- },
- // 弹出框是否显示
- modalRelation:false,
-
- // 连接线
- optionLinks:[],
-
- // 当前图表
- myChart: {},
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
相信一看到这些数据结构及定义,就懂了。
用上个步骤的 allCondition 即可。保存到后端时,转换成相应的数据结构,前端需要再次展示的时候,还原回来即可。
这就是开发表关联的一个思路和大部分代码,做的时候不要急,也不能乱,一个个小功能拆分出来,向上累积,最终就会达到我们想要的效果。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。