用Echarts 制作一个数据库表的关联关系图(二)

         前面 用Echarts 制作一个数据库表的关联关系图(一 中提到了几个问题,接下来一个一个解决。

1、添加节点

        目前项目背景为:左边是展示数据库表的 ztree 树,树的上面是一些对ztree 树进行操作的一些按钮,我的思路是在左边按钮区域添加一个按钮,选中树节点后(可支持多选),点击按钮后做添加操作。

    let [ ...temp ] = this.gData;             // 节点的数据存在vuex state中
      temp.push({                             // 保存节点的名字和ID
                   name: nodes[0].name,       
                   value:nodes[0].tableId,
                   x: 0,
                   y: 0
                });

这样数据就保存起来了。

2、节点坐标

       当节点变化时,在 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;
}

    不多说了,学过数学的都能看懂。

3、触发Echarts 刷新

    vue 中双向绑定必须绑定到 html 元素,才能用 watch 监控直接改变的 state ,如下所示:

watch:{
        // 鉴定节点的变化 重新加载图表
        gData:function (val) {
                this.initGraph();
          }
      },

4、连接线如何连接

     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 
                    }

                }
            }

5、请求节点字段信息

        当点击节点时候去请求并记录节点的信息。在本地保存临时变量,如果已存在该表格信息,就不再请求服务器。

6、连接条件框

        用一个条件框,切换节点或者连线的时候做更新,效果

如图所示:

7、添加删除修改条件逻辑

     上图所示的弹出层,我们只需要一个,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: {},

      相信一看到这些数据结构及定义,就懂了。

8、最终条件的保存

     用上个步骤的 allCondition 即可。保存到后端时,转换成相应的数据结构,前端需要再次展示的时候,还原回来即可。

 

总结

     这就是开发表关联的一个思路和大部分代码,做的时候不要急,也不能乱,一个个小功能拆分出来,向上累积,最终就会达到我们想要的效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大广-全栈开发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值