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>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352