echart樹形圖實(shí)現(xiàn)點(diǎn)擊節(jié)點(diǎn)完整鏈路更換顏色

在某些需求下需要用到樹形圖來表達(dá)數(shù)據(jù)結(jié)構(gòu)刊头,我使用的是echarts逛绵,關(guān)于echart樹形圖的基礎(chǔ)配置和使用這里就不展開椿访。

直接上圖,這是一個(gè)基礎(chǔ)的樹形圖demo:


image.png

當(dāng)點(diǎn)擊非最末節(jié)點(diǎn)的時(shí)候,echart的默認(rèn)行為為收縮該節(jié)點(diǎn)的子節(jié)點(diǎn),這個(gè)行為會(huì)與下面實(shí)現(xiàn)的效果有關(guān)系加酵,效果:


image.png

現(xiàn)在回到標(biāo)題的需求根灯,當(dāng)點(diǎn)擊節(jié)點(diǎn)的時(shí)候,實(shí)現(xiàn)整條鏈路高亮中符,也就是更換線的顏色姜胖,因?yàn)榉亲钅┕?jié)點(diǎn)的節(jié)點(diǎn)可能對(duì)應(yīng)多個(gè)子節(jié)點(diǎn),所以只有最末節(jié)點(diǎn)才存在一對(duì)一的關(guān)系淀散,所以需求就是點(diǎn)擊末節(jié)點(diǎn)的時(shí)候右莱,實(shí)現(xiàn)整條鏈路高亮,效果:
image.png

下面進(jìn)入實(shí)現(xiàn)档插,一開始思考這個(gè)需求的時(shí)候慢蜓,以為跟經(jīng)常做的柱狀圖點(diǎn)擊更換柱子顏色一樣,都是去替換配置郭膛,當(dāng)然某種情況下也是可以實(shí)現(xiàn)的晨抡,先簡單說一下樹形圖的data結(jié)構(gòu),是使用children屬性層層嵌套的結(jié)構(gòu):

[
  {
    name: '',
    value: 0,
    itemStyle: {},
    lineStyle: {},
    children: [...]
  }
]

按上面的思路,只要監(jiān)聽節(jié)點(diǎn)的點(diǎn)擊事件耘柱,然后獲取對(duì)應(yīng)鏈路相關(guān)的節(jié)點(diǎn)如捅,更改他們的lineStyle,然后echart實(shí)例重新setOption就可以帆谍,下面看一下大概實(shí)現(xiàn):

myChart.on('click', function (params) {
  console.log(params)
})

看一下點(diǎn)擊節(jié)點(diǎn)伪朽,echart帶的參數(shù)

image.png

關(guān)注里面的兩個(gè)屬性,一個(gè)data汛蝙,也就是我們自己給節(jié)點(diǎn)添加的屬性烈涮,然后是treeAncestors屬性,它就代表了節(jié)點(diǎn)的鏈路關(guān)系窖剑,尋找唯一的父節(jié)點(diǎn)一直到根節(jié)點(diǎn)坚洽,這里只保留了name、value西土、dataIndex三個(gè)關(guān)鍵屬性讶舰,dataIndexechart生成的唯一索引,在我們的原始數(shù)據(jù)中沒有需了,而name很有可能出現(xiàn)同名的情況跳昼,所以假設(shè)我們生成一個(gè)唯一的value,通過這個(gè)treeAncestors數(shù)組的每一個(gè)value和我們原始配置的數(shù)據(jù)中的value去匹配肋乍,相同的話就更換它的lineStyle屬性鹅颊,最后重新setOption
具體實(shí)現(xiàn):

      myChart.on('click', function (params) {
        console.log(params)
        // 深拷貝墓造,防止原始配置被修改
        const copyOption = JSON.parse(JSON.stringify(initOption))
        const data = params.data
        if (data.children) {
          return
        } else {
          const treeAncestors = params.treeAncestors
          treeAncestors.forEach((item) => {
            if(item.value !== undefined) {
              findSameValue(copyOption.series[0].data, item.value)
            }
          })
          myChart.setOption(copyOption)
        }
      })

      function findSameValue(data, value) {
        data.forEach((item) => {
          if(item.value === value) {
            item.lineStyle = {
              color: '#42cccc'
            }
          }
          if(item.children) {
            findSameValue(item.children, value)
          }
        })
      }

到這里這種點(diǎn)擊更換相關(guān)節(jié)點(diǎn)linestyle的方式就實(shí)現(xiàn)堪伍,但是這種方式有兩個(gè)問題:
1.上面我們是假設(shè)value是唯一的,如果實(shí)際開發(fā)中value有實(shí)際用途不能讓我們生成唯一的值觅闽,這種方法就無法實(shí)現(xiàn)帝雇。但這個(gè)還不是致命的。
2.上面說到蛉拙,非最末節(jié)點(diǎn)點(diǎn)擊時(shí)尸闸,會(huì)收縮與展開它的子節(jié)點(diǎn),而我們上面實(shí)現(xiàn)高亮的時(shí)候是重新setOption刘离,會(huì)將已操作的交互覆蓋掉室叉,點(diǎn)擊前效果:

image.png

點(diǎn)擊后:
image.png

可以看到,原本收起來的節(jié)點(diǎn)回到一開始的展開效果了硫惕,這對(duì)交互效果來說是致命的茧痕,setOption無法做到還保留之前的交互效果,所以這種實(shí)現(xiàn)方法要放棄了恼除。

實(shí)現(xiàn)高亮的核心還是更換節(jié)點(diǎn)屬性的linestyle踪旷,但是不能通過重新setOption來實(shí)現(xiàn)曼氛,在翻遍echart配置項(xiàng)的時(shí)候,最后看到了一個(gè)屬性和一個(gè)方法:

image.png

image.png

emphasis其實(shí)是定義鼠標(biāo)移入節(jié)點(diǎn)時(shí)的效果令野,但是在echart api中可以用dispatchAction來手動(dòng)觸發(fā)這個(gè)效果舀患,通過傳入type='highlight',那么只要在點(diǎn)擊的時(shí)候气破,通過dispatchAction觸發(fā)相關(guān)節(jié)點(diǎn)的emphasis效果聊浅,那我們的需求就能實(shí)現(xiàn)了。dispatchAction可以傳入節(jié)點(diǎn)的唯一索引dataIndex或者多個(gè)dataIIndex組成的數(shù)組现使,代表手動(dòng)高亮哪些節(jié)點(diǎn)低匙;且還有相對(duì)應(yīng)的取消emphasis效果的api,通過dispatchAction傳入type='downplay'來實(shí)現(xiàn)碳锈,很完美顽冶。

實(shí)現(xiàn):

先在echart配置項(xiàng)中添加emphasis時(shí)的效果:

series:[
  {
    ....,
    emphasis: {
      lineStyle: {
        color: '#42cccc'
      }
    }
  }
]

因?yàn)?strong>emphasis屬性默認(rèn)是鼠標(biāo)移入節(jié)點(diǎn)時(shí)的效果,所以我們手動(dòng)觸發(fā)高亮?xí)湍J(rèn)行為沖突售碳,需要一個(gè)數(shù)組保存點(diǎn)擊高亮的節(jié)點(diǎn)dataIndex强重。

let currentDataIndexs = []

點(diǎn)擊時(shí)手動(dòng)觸發(fā)相關(guān)節(jié)點(diǎn)的高亮:

myChart.on('click', function (params) {
  // 先取消已高亮的節(jié)點(diǎn)連線
  myChart.dispatchAction({
    type: 'downplay',
    dataIndex: currentDataIndexs
  })

  // 針對(duì)非最尾節(jié)點(diǎn)點(diǎn)擊收縮展開后已高亮線路失效
  if (params.data.children) {
    myChart.dispatchAction({
      type: 'highlight',
      dataIndex: currentDataIndexs
    })
    return
  }

  const treeAncestors = params.treeAncestors
  const dataIndexs = treeAncestors.map((item) => item.dataIndex)
  // 重新保存當(dāng)前高亮的節(jié)點(diǎn)
  currentDataIndexs = dataIndexs

  // 高亮相關(guān)節(jié)點(diǎn)連線
  myChart.dispatchAction({
    type: 'highlight',
    dataIndex: dataIndexs
  })
})

還需要覆蓋emphasis的默認(rèn)行為,也就是鼠標(biāo)移入事件:

// 節(jié)點(diǎn)鼠標(biāo)移入事件
myChart.on('mouseover', function (params) {
  // 取消當(dāng)前節(jié)點(diǎn)的高點(diǎn)贸人,頂替默認(rèn)事件
  myChart.dispatchAction({
    type: 'downplay',
    dataIndex: params.dataIndex
  })

  // 高亮點(diǎn)擊已保存的相關(guān)節(jié)點(diǎn)的連線间景,防止上一步取消了已保存節(jié)點(diǎn)的高亮
  myChart.dispatchAction({
    type: 'highlight',
    dataIndex: currentDataIndexs
  })
})

實(shí)現(xiàn)效果:
點(diǎn)擊前:


image.png

點(diǎn)擊后:


image.png

實(shí)現(xiàn)了。
我是鴨子艺智,祝你幸福拱燃。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市力惯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌召嘶,老刑警劉巖父晶,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異弄跌,居然都是意外死亡甲喝,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門铛只,熙熙樓的掌柜王于貴愁眉苦臉地迎上來埠胖,“玉大人,你說我怎么就攤上這事淳玩≈背罚” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵蜕着,是天一觀的道長谋竖。 經(jīng)常有香客問我红柱,道長,這世上最難降的妖魔是什么蓖乘? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任锤悄,我火速辦了婚禮,結(jié)果婚禮上嘉抒,老公的妹妹穿的比我還像新娘零聚。我一直安慰自己,他們只是感情好些侍,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布隶症。 她就那樣靜靜地躺著,像睡著了一般娩梨。 火紅的嫁衣襯著肌膚如雪沿腰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天狈定,我揣著相機(jī)與錄音颂龙,去河邊找鬼。 笑死纽什,一個(gè)胖子當(dāng)著我的面吹牛措嵌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播芦缰,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼企巢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了让蕾?” 一聲冷哼從身側(cè)響起浪规,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎探孝,沒想到半個(gè)月后笋婿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡顿颅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年缸濒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片粱腻。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡庇配,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出绍些,到底是詐尸還是另有隱情捞慌,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布柬批,位于F島的核電站卿闹,受9級(jí)特大地震影響揭糕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜锻霎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一著角、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧旋恼,春花似錦吏口、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蜀细,卻和暖如春舟铜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背奠衔。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來泰國打工谆刨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人归斤。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓痊夭,卻偏偏與公主長得像,于是被迫代替她去往敵國和親脏里。 傳聞我的和親對(duì)象是個(gè)殘疾皇子她我,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容