Echarts tree结构使用

需求:关系族谱图,多叉树结构展示

技术:Echarts tree结构

难点

  1. 控制节点的缩起和展开状态
  2. 同一个等级的只能展开一个节点
  3. 控制高度的自动伸缩

知识

  1. 数组的递归
  2. ES6 map的使用

tree结构的数据结构以及配置项

option: {
    series: [
      {
        type: 'tree',  // 类型是tree
        top: '1%',  //距离div块top距离
        left: '10%',
        bottom: '1%',
        right: '10%',
        // 每个节点都有文字,label属性是设置字体(位置,大小,样式)
        label: {
          normal: {
            position: 'left',
            verticalAlign: 'middle',
            align: 'right',
            fontSize: 12
          }
        },
        // 当此节点下还有子节点时候,设置的节点样式,用于区别 没有子节点的节点的样式
        itemStyle: {
          normal: {
            color: '#b22125'
          },
          emphasis: {
            borderColor: '#ccc'
          }
        },
        // 叶子节点设置
        leaves: {
          label: {
             normal: {
               position: 'right',
               verticalAlign: 'middle',
               align: 'left',
               fontSize: 12
             }
           }
        },
        // 图形大小
        symbolSize: 20,
        initialTreeDepth: 2,   // 一开始展开深度
        // expandAndCollapse  全部打开,全部收缩,值未布尔类型
        data: []
      }
    ]
  }

一切准备就绪,开始上代码

  1. 初始化echarts
<div id="tree">
  <div id="myChart"></div>
</div>
this.myChart = echarts.init(document.getElementById('myChart'))
this.myChart.on('contextmenu', this.handleClick)  // 右击,弹窗弹出此节点的详情;有一个参数param(可以打印出来)
this.myChart.on('click', this.handleClickCircle)  // 左击,控制节点的展开和伸缩;有一个参数param(可以打印出来)
  1. 右击,弹窗弹出此节点的详情,在此处,右击浏览会弹出菜单,需要屏蔽掉默认事件
// 自带param参数
handleClick(param) {
  let _this = this
  param.event.event.preventDefault()  //屏蔽浏览器默认行为
  this.Ajax.post(url, data, this,
    function(data, context) {
      Object.keys(data.data).forEach(key => {
       // 对数据进行一些处理
      })
    }
  )
}
  1. 左击,控制节点的伸缩和展开,高度计算
//右击的时候,需要判断此节点是否已经展开
//节点的展开和收缩状态存储在一个map中,map中的key是此节点的唯一标示(唯一标识自己和后台定啦),value为true或者false(true为收缩状态,false为展开状态);每次点击取到这个节点的唯一标识,然后从map中取出此节点是展开还是缩起的状态
//如果已经展开,就执行默认的行为(收缩起来);并且将map中此节点的唯一标示改为true
//如果点击节点并且此节点是缩起的状态,这个时候需要将同级的节点全部收起来,只设置此节点是展开状态;并且将map中此节点的唯一标示改为false
handleClickCircle(param) {
    let index = param.data.index  // 获取当钱节点的深度param.data是自己传的数据
    this.findId(this.option.series[0].data, param.value, 'getObj')   // 获取当前节点
    // 判断此节点是展开还是收缩状态
    if (this.map.get(this.currentClickObj.value)) {
        // 收缩状态,执行下面代码
        this.map.set(this.currentClickObj.value, false)
        // 将同级的全部收缩   this.option.series[0].data是本树的data数据(数组)
        this.handleCollapsed(this.option.series[0].data, index)
        // 当前节点展开
        this.findId(this.option.series[0].data, param.value, 'setCollapsed')
        this.map.set(this.currentClickObj.value, true)  // 将当前节点设置为收缩状态
        // 重新渲染  echart中的data更改的时候,需要重新渲染
        this.myChart.clear()
        this.myChart.setOption(this.option)
    }
    // 计算高度
    //计算高度这个点,我是查找此子树的每个级别的节点,并找出最多的节点数,根据这个子节点数来计算高度
    this.listNumber = []
    let charts = document.getElementById('myChart')
    this.findMostLeaves(param.data.index + 1)
    // Math.max.apply(null, this.listNumber) 取出listNumber中的最大值并且计算高度
    charts.style.height = Math.max.apply(null, this.listNumber) * 80 + 500 + 'px'
    // 重要的一步,小编当时就是漏掉此步,导致没办法更新高度,敲黑板
     this.myChart.resize()
  },
//////////////////////////分割线//////////////////////////
// 将同级的全部收缩
handleCollapsed(array, index) {
  array.forEach((value, i) => {
    if (value.index == index) {
      value.collapsed = true  // collapsed属性为true,设置此节点收缩状态
      this.map.set(value.value, false)  // 并且将此节点设置为可收缩状态(map)
    } else {
      if (value.children.length > 0) {
        // 递归
        this.handleCollapsed(value.children, index)
      } else {
        return
      }
    }
  })
}
//////////////////////////分割线//////////////////////////
// 查找当前节点  当前节点展开
findId(array, id, flag) {
  array.forEach((value, i) => {
    if (value.value == id) {
      if (flag == 'setCollapsed') {
        value.collapsed = false  //collapsed属性为true,设置此节点展开状态
        this.map.set(value.value, true)  // 并且将此节点设置为可展开状态(map)
      } else {
        this.currentClickObj = value
      }
    } else {
      if (value.children.length > 0) {
        this.findId(value.children, id, flag)
      } else {
        return
      }
    }
  })
}
//////////////////////////分割线//////////////////////////
// 找出最多的节点
findMostLeaves(index) {
  // this.myChart._chartsViews[0]._data.tree._nodes 此值是tree数据将结构中的数据,左击的时候就可以获取到此数值,并且里面的isExpand就是判断当前节点的展开和收缩状态
  this.myChart._chartsViews[0]._data.tree._nodes.forEach(value => {
    if (value.depth <= index) {
      if (value.isExpand) {
        // 将每一个等级的叶子数量存入listNumber中
        this.listNumber.push(value.children.length)
      }
    }
  })
}
  1. 我当时这篇文章帮了我很多,可以参考
  2. 此过程中用到的map类型,将在下期总结ES6的map和set的用法(敬请期待鸭)

感谢您的view,留个赞再走呗

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