iT邦幫忙

2021 iThome 鐵人賽

DAY 12
0
Modern Web

三十天成為D3.js v7 好手系列 第 12

Day12-D3 的 Tooltips

本篇大綱:tooltips 基礎設定、tooltips 進階應用

今天我們要來講解算是D3最輕鬆簡單的 tooltips 啦!其實所謂的tooltips就是在觸發事件時,加上一個 < text > 或 < div > 去建立想呈現的資訊框,我們先來看看以下的範例

https://i.imgur.com/zbu95Ek.gif

Tooltips 基礎設定

接著來看看程式碼吧~現在畫面上有一個綠色圓點點

// html
<div class="tooltip1"></div>

//js 
const svg = d3.select('.tooltip1')
                .append('svg')
                .attr('width', 300)
                .attr('height', 300);

// 圓點點
svg.append('circle')
   .attr("id", "dot")
   .attr("cx", 150)
   .attr("cy", 150)
   .attr("r", 40)
   .attr("fill", "#69b3a2");

我們先來建立 tooltips

const tooltip = d3.select(".tooltip1")
      .append("div")
      .style("position", "absolute")
      .style("visibility", "hidden") // 一開始tooltips是隱藏的
      .style("background-color", "white")
      .style("border", "solid")
      .style("border-width", "1px")
      .style("border-radius", "5px")
      .style("padding", "10px")
      .html("<p>我是tooltip!</p>"+
             "<p>這邊可以隨意放入任何想放的資料</p>"+
            "<img src='https://github.com/holtzy/D3-graph-gallery/blob/master/img/section/ArcSmal.png?raw=true'></img>"+
            "<p>甚至圖片也可以唷</p>");

接著再設定要觸發的事件:滑鼠滑過時要呈現tooltips並設定它的位置,滑鼠移開時tooltips則消失

// 加上滑鼠事件
d3.select('#dot')
  .style('cursor', 'pointer')
  .on('mouseover', function() {
      return tooltip.style("visibility", "visible")
    })
  .on("mousemove", function() {
      // 設定 tooptip位置
      return tooltip.style("top", "250px").style("left","280px")
    })
  .on('mouseleave', function(){
      return tooltip.style("visibility", "hidden")
     });

這樣就完成啦~~是不是很簡單!但這個只是最基礎的範例,我們接著再來做點進階的tooltips範例吧!

Tooltips 進階應用

現在我們不只有一個圓點點,而是有一整組資料要綁定到svg上,程式碼如下:

// html
<div class="tooltip2"></div>

//js 
const tooltipsData =[
  {'r': 17 , 'x': 134, y: 181, 'color':'red'},
  {'r': 23 , 'x': 294, y: 131, 'color':'yellow'},
  {'r': 14 , 'x': 84, y: 273, 'color':'orange'},
  {'r': 9 , 'x': 323, y: 59, 'color':'blue'},
  {'r': 18 , 'x': 172, y: 251, 'color':'green'},
  {'r': 26 , 'x': 404, y: 154, 'color':'pink'}
]

我們先將資料轉換成畫面上的圓點點

d3.select('.tooltip2').style('position', 'relative')
const dots = d3.select('.tooltip2')
                      .append('svg')
                      .attr('width', 500)
                      .attr('height', 300)
                      .selectAll('circle')
                      .data(tooltipsData)
                      .enter()
                      .append('circle')
                      .attr('r', d => d.r)
                      .attr('cx', d => d.x)
                      .attr('cy', d => d.y)
                      .attr('fill', d => d.color)
                      .style('cursor', 'pointer');

這樣一來畫面上就多了六個大小、顏色、位置都不同點點啦

https://ithelp.ithome.com.tw/upload/images/20210924/20134930lsyIdG3nQT.jpg

再來,我們要在滑鼠hover上圓點點時,顯示此圓點點的半徑。先來建立要顯示資訊的tooltips

// 建立tooltips
  const tooltips = d3.select(".tooltip2")
                    .append("div")
                    .style("opacity", 0)
                    .style('position', 'absolute')
                    .attr("class", "tooltip")
                    .style("background-color", "white")
                    .style("border", "solid")
                    .style("border-width", "2px")
                    .style("border-radius", "5px")
                    .style("padding", "5px")

接著來設定圓點點的 mouseover 、mousemove 事件,讓滑鼠hover過去時,tooltip 顯示在我們設定好的位置上

dots.on('mouseover', function(){
         tooltips.style("opacity", 1) // 顯示tooltip
       })
       .on('mousemove', function(d){
        let pt = d3.pointer(event, this) // 抓圓點位置
        tooltips.style("opacity", 1)
                .style('left', pt[0]+30+'px'). // 設定tooltips位置
                .style('top', pt[1]+'px')
                .html('圓半徑:' + d.target.__data__.r) // 抓到綁定在DOM元素的資料
       })

這邊的設定比較複雜,我們一一來解釋一下:

  1. d3.pointer ⇒ (如果不知道這個方法是什麼,請去看前面在講事件的篇章)
    使用這個方法先抓到此圓點的xy軸位置,接著再把圓點的x軸位置多加個30xp並設定給tooltip,這樣一來tooltip就會出現在圓點的右方30px方位;y軸也是使用一樣的邏輯去設定

  2. html 圓半徑 ⇒
    我們把圓點綁定的參數d 帶入 mousemove 事件,接著透過 d.target._data_ 去抓到綁定在DOM元素上面的 r 資料,這樣一來就能順利取得圓點的半徑了

完成的效果就是這樣:
https://i.imgur.com/jjyzCzH.gif

接著還差最後一步~我們希望滑鼠移走時,tooltips會跟著消失,因此要設定 moseleave 時隱藏tooltips

dots.on('mouseover', function(){
         tooltips.style("opacity", 1)
       })
       .on('mousemove', function(d){
        let pt = d3.pointer(event, this)
        tooltips.style("opacity", 1)
                .html('圓半徑:' + d.target.__data__.r)
                .style('left', pt[0]+30+'px')
                .style('top', pt[1]+'px')
       })
       .on('mouseleave', function(){. //設定滑鼠離開時tooltips隱藏
        tooltips.style("opacity", 0)
       });

這樣就完成啦!
https://i.imgur.com/y2gDdxE.gif

透過動態添加 tooltips,我們就能用事件互動的方式呈現更多圖表資訊。今天就先講到這邊啦,之後的範例也會示範更多tooltips的用法~


Github Page 圖表與 Github 程式碼

這邊附上本章的程式碼與圖表 GithubGithub Page,需要的人請自行取用~


上一篇
Day11-D3 Mouse Event 滑鼠事件
下一篇
Day13-D3 的 Drag 拖曳
系列文
三十天成為D3.js v7 好手30

尚未有邦友留言

立即登入留言