本篇大纲:click、hover、mouseover、mousemove
由於 D3.js 是操作DOM元素去建构图表,因此DOM元素能使用的触发事件,D3也一样能够使用~我们现在就来看看该怎麽使用d3的事件,以及有哪些事件可以用吧!
想触发d3.js的事件要使用的 API 是 selection.on( ),这个方法一样归纳在selection之下,因为我们要先选定节点,才能将事件绑定到这个节点上。
selection.on( ) 能使用所有DOM元素原生的事件,而一般来说最常用的有:
这些事件能结合上一篇介绍的 .transition( ) 做出各种有趣的效果,例如:
click
:点击方块时,它会移动位置并改变颜色// html
<svg class="event"></svg>
// js
// rect
d3.select('.event')
.append('rect')
.attr('class', 'rect')
.attr('width', 30)
.attr('height', 30)
.attr('fill', 'blue')
.append('rect')
// 加上事件
d3.select('.rect')
.on('mouseover', function(){
d3.select(this)
.transition()
.attr('cursor', 'pointer')
.attr('fill', 'green')
.attr('transform', 'translate(250, 0)')
})
mouseover、mouseleave
:滑鼠滑过时改变位置与颜色,滑鼠离开时回到原本状态// html
<div class="chartContainer">
<div class="box1">
<p>aa</p>
<p>aa</p>
<p>aa</p>
<p>aa</p>
</div>
</div>
// js
// hover (mouseover / mouseleave)
d3.selectAll('p')
.on('mouseover', function () {
d3.select(this)
.style("color", "red")
.transition()
.style('cursor', 'pointer')
.style("transform", "translate(50px)");
})
.on("mouseleave", function () {
d3.select(this).style("color", "black")
.transition().style("transform", "translate(0)");
});
但光是会使用DOM的事件还不够,大部分的时候一个完整的图表会包含许多DOM元素,我们需要知道各别DOM元素在图表中的位置,才能正确选定想操作的DOM元素,例如:
这个时候,我们就要运用 d3.pointer( ) 这个方法了
以前想取得DOM节点的座标轴时,可以根据不同事件去找对应的方法,例如:使用 d3.mouse、d3.touch、 d3.touches、d3.clientPoint 等等;但後来 d3 在第六版时进行了一些调整,把这些方法全部合并到 d3.pointer,再透过带入参数的方式去指定想触发的事件,想更深入了解的人可以看看这个 v5~v6 Migration Guide
现在,我们一样先来看到 d3.pointer( )的官方文件介绍
d3.pointer(事件, target) 这个方法会根据所带入的事件,返还指定target的 [x,y]座标轴,我们就可以透过这个座标轴去抓到指定的DOM元素。
先来个小范例看看要怎麽使用吧!
范例:滑鼠移动时,显示目前滑鼠所在的座标轴
首先,我们先建立svg视窗大小,接着绑定 mousemove 的事件
// html
<h5 class="mt-5">3. pointer()找出目前滑鼠所在 X Y 轴座标</h5>
<div class="position"></div>
// js
// 先建立svg并设定大小
const svg = d3.select('.position').append('svg');
svg.attr('width', 500)
.attr('height', 500);
// 设定svg滑鼠事件
svg.on('mousemove', function () {
});
接着我们使用 d3.pointer()的方法带入目前事件与要操作的 node 结点,并把返还的数值console出来看看
// 设定svg滑鼠事件
svg.on('mousemove', function () {
let pt = d3.pointer(event, svg.node())
console.log(pt)
});
返还的数值是一个阵列,内含的两笔资料分别代表X跟Y轴的座标
最後我们简单设定一个 tooltip 来呈现滑鼠当下的座标轴吧!详细的tooltip设定下一篇会讲解,这边大家就稍微看一下程序码就好~
//pointer()、tooltip
let txt = svg.append("text");
svg.on('mousemove', function () {
//d3.pointer 会回传阵列[X,Y]
let pt = d3.pointer(event, svg.node())
txt.attr('x', pt[0]) //取[x]
.attr('y', pt[1]) //取[Y]
.text(`X:${parseInt(pt[0])} | Y:${parseInt(pt[1])}`)
console.log(pt)
});
结果如下~滑鼠移动到哪,就会显示当下的座标轴
这下就可以玩很多花样啦~我们结合d3的画面、事件、座标轴、动画来玩玩看看吧!
// html
<div class="combined"></div>
//js
const data = [130, 210, 90, 250]
const combined = d3.select('.combined')
.append('svg')
.attr('width', 500)
.attr('height', 300);
const dots = combined.selectAll('circle')
.data(data)
.enter()
.append('circle')
.attr('cx', d=>d)
.attr('cy', (d,i)=>(i+1)*60)
.attr('r', '15')
.attr('fill', 'blue')
.attr('cursor', 'pointer')
// 绑定事件
dots.on('mouseover', function(){
let pt = d3.pointer(event, event.target)
d3.select(this)
.attr('fill', 'red')
.transition()
.attr('cx', pt[0]+100)
});
是不是很有趣呢?d3 的事件部分就讲到这边,之後的图表就能搭配事件跟动画,做出一连串酷炫的效果啦~
这边附上本章的程序码与图表 Github 、 Github Page,需要的人请自行取用~
<<: 【没钱买ps,PyQt自己写】Day 8 – 我们的第二个 input 手段 – QLineEdit
CollectionView:Storyboard、Xib + Collection View + ...
由於不是设计师,对於UI/UX相关的东西懂得可能就跟完全没接触过的人一样, 所以在想做一个自己的Ap...
unRaid系统会要求使用者要先配置硬碟,才能使用各个功能(如VM,共享资料夹…等) 今天先深入了解...
今天努力了一个下午,终於算是勉强搞出了一组能动的 playbook,这边就来记录一下过程以及就我所知...
以前我绝对是对哲学避之唯恐不及的 但某一年意外看到「正义 一场思辨之旅」以及「超译 尼采」後 开始...