VUE-ORGCHART部分功能封装

PS: 这玩意是收费的,后面换antv-G6使用了
仅按自身需求做了简单的封装操作,

  1. 继承ana模板,修改了node样式和大小,去除了img显示
  2. 使用tag动态标记不同类型的node边框样式
  3. 向父组件暴露需求使用到的方法
<!--封装OrgChart功能-->
<template>
  <div id="tree" ref="tree"></div>
</template>

<script>

  import OrgChart from '@balkangraph/orgchart.js/orgchart'

  export default {

    name: 'OrgChart',
    props: {
      nodes: {
        type: Array,
        default: () => []
      },
      handleClick: {
        type: Function,
        default: () => false
      },
      unCheckNodeIds: {
        type: Array,
        default: () => []
      },
      checkNodeIds: {
        type: Array,
        default: () => []
      }
    },
    data() {
      return {
        chart: null,
        currentId: null,
        orientation: {
          'top': OrgChart.orientation.top,
          'bottom': OrgChart.orientation.bottom,
          'left': OrgChart.orientation.left,
          'right': OrgChart.orientation.right
        }
      }
    },
    watch: {
      unCheckNodeIds: {
        handler(newValue, oldValue) {
          //console.log('------------unCheckNodeIds-----------')
          //去除class
          for (let i = 0; i < oldValue.length; i++) {
            this.removeNodeTag(oldValue[i], "error")
          }
          //添加class
          for (let i = 0; i < newValue.length; i++) {
            this.addNodeTag(oldValue[i], "error")
          }
          this.draw()
        },
        deep: true
      },
      checkNodeIds: {
        handler(newValue, oldValue) {
          //去除class
          for (let i = 0; i < oldValue.length; i++) {
            this.removeNodeTag(oldValue[i], "success")
          }
          //添加class
          for (let i = 0; i < newValue.length; i++) {
            this.addNodeTag(oldValue[i], "success")
          }
          this.draw()
        },
        deep: true
      }
    },
    methods: {
      oc: function(domEl, x) {
        console.log('--------------oc draw-------------')
        console.log(x)
        var that = this;
        this.customTemplate()
        this.chart = new OrgChart(domEl, {
          template: 'myTemplate',
          nodes: x,
          //默认合并级别
          collapse: {
            level: 2,
            allChildren: true
          },
          nodeBinding: {
            field_0: "name",
            field_1: "id",
            //img_0: "img"
          },
          orientation: OrgChart.orientation.left,
          toolbar: {
            layout: false,
            zoom: true,
            fit: true,
            expandAll: false,
            fullScreen: false
          },
          /*nodeMenu: {
            details: { text: "Details" },
            add: { text: "Add New" },
            edit: { text: "Edit" },
            remove: { text: "Remove" },
            pdf: { text: "Export PDF" },
            png: { text: "Export PNG" },
            svg: { text: "Export SVG" },
            csv: { text: "Export CSV" }
          },*/
        });
        this.chart.on('click', this.onNodeClick);
        this.chart.on('add', function (sender, node) {
          // your code goes here
          // return false; to cancel the operation
          debugger
        });
        //拖动事件
        this.chart.on('drop', function (sender, draggedNodeId, droppedNodeId) {
            console.log('drop------move---' + draggedNodeId + '---to father-----' + droppedNodeId)
            if (draggedNodeId == 1){
              return false;
            }
            //TODO 暴露回调方法给外部
        })
      },
      /**
       * 自定义显示外观模板
       */
      customTemplate() {
        //继承ana外观
        OrgChart.templates.myTemplate = Object.assign({}, OrgChart.templates.ana);
        //node位置,同node的width和height
        OrgChart.templates.myTemplate.size = [140, 60];
        //node外形
        OrgChart.templates.myTemplate.node =
          '<rect x="0" y="0" height="60" width="140" fill="#039BE5" stroke-width="1" stroke="#aeaeae" rx="5" ry="5"></rect>';
        //node显示字段显示
        OrgChart.templates.myTemplate.field_0 =
          '<text width="130" class="field_0"  style="font-size: 14px;" fill="#ffffff" x="64" y="40" text-anchor="middle">{val}</text>';
        OrgChart.templates.myTemplate.field_1 =
          '<text width="60" text-overflow="multiline" class="field_1"  style="font-size: 10px;" fill="#ffffff" x="130" y="20" text-anchor="end">{val}</text>';
        //不要图片显示
        OrgChart.templates.myTemplate.img_0 = '';
        //menu菜单按钮显示
        OrgChart.templates.myTemplate.nodeMenuButton = '<g style="cursor:pointer;" transform="matrix(1,0,0,1,225,105)" control-node-menu-id="{id}"><rect x="-4" y="-10" fill="#000000" fill-opacity="0" width="22" height="22"></rect><circle cx="-105" cy="-52" r="2" fill="#ffffff"></circle><circle cx="-98" cy="-52" r="2" fill="#ffffff"></circle><circle cx="-91" cy="-52" r="2" fill="#ffffff"></circle></g>';
        //节点显示
        //节点位置
        OrgChart.templates.myTemplate.expandCollapseSize = 20;
        //节点十字
        OrgChart.templates.myTemplate.plus = '<circle cx="10" cy="10" r="10" fill="#ffffff" stroke="#aeaeae" stroke-width="1"></circle><line x1="-1" y1="10" x2="21" y2="10" stroke-width="1" stroke="#aeaeae"></line><line x1="10" y1="-1" x2="10" y2="21" stroke-width="1" stroke="#aeaeae"></line>';
        //节点形状
        OrgChart.templates.myTemplate.minus =
          '<circle cx="10" cy="10" r="10" fill="#ffffff" stroke="#aeaeae" stroke-width="1"></circle><line x1="-1" y1="10" x2="21" y2="10" stroke-width="1" stroke="#aeaeae"></line>';
      },
      /**
       * chart.addNode({ id: 4, pid: 2, name: "Name 1", title: "Title 1" });
       * @param nodeData
       */
      addNode(nodeData) {
        this.chart.addNode(nodeData)
      },
      /**
       * chart.removeNode(5);
       * @param id
       */
      removeNode(id) {
        this.chart.removeNode(id)
      },
      /**
       * 只更新有效值字段
       * chart.updateNode({ id: 4, pid: 2, name: "Updated Name", title: "Updated Title" });
       * @param nodeData
       */
      updateNode(nodeData) {
        if (!nodeData.id) {
          console.error('update error not id')
          return
        }
        var nodeDetail = this.chart.get(nodeData.id)
        if (nodeDetail && nodeData.pid) {
          nodeDetail.pid = nodeData.pid
        }
        if (nodeDetail && nodeData.name) {
          nodeDetail.name = nodeData.name
        }
        if (nodeDetail && nodeData.dmId) {
          nodeDetail.dmId = nodeData.dmId
        }
        this.chart.updateNode(nodeDetail)
      },
      onNodeClick(sender, args) {
        var chart = this.chart;
        if (this.currentId == null) {
          this.currentId = args.node.id
          chart.addNodeTag(args.node.id, "selected");
        } else {
          chart.removeNodeTag(this.currentId, "selected");
          this.currentId = args.node.id
          chart.addNodeTag(args.node.id, "selected");
        }
        chart.draw()

        var nodeDetail = chart.get(args.node.id)
        if (this.handleClick(nodeDetail)) {
          //afterClick
        }
        return false
      },
      changeDirection(orientation) {
        var chart = this.chart
        if (orientation && this.orientation[orientation]) {
          chart.config.orientation = this.orientation[orientation]
        } else {
          if (chart.config.orientation == OrgChart.orientation.top) {
            chart.config.orientation = OrgChart.orientation.left
          } else {
            chart.config.orientation = OrgChart.orientation.top
          }
        }
        chart.draw()
      },
      addNodeTag(id, tag) {
        this.chart.addNodeTag(id, tag);
      },
      removeNodeTag(id, tag) {
        this.chart.removeNodeTag(id, tag)
      },
      draw() {
        this.chart.draw()
      },
      get(id) {
        if (id) {
          return this.chart.get(id)
        }
        return null
      }
    },

    mounted(){
      this.oc(this.$refs.tree, this.nodes)
    }
  }
</script>

<style type="text/css">
  /*partial*/
  .node.selected rect {
    fill: #F57C00;
  }
  .node.error rect {
    stroke-width: 3;
    stroke: red;
  }
  .node.success rect {
    stroke-width: 3;
    stroke: green;
  }
</style>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。