本篇大纲:window.resize、RWD 图表、轴线刻度数量随画面变化增减
前两篇看完比例尺跟轴线後,现在D3的知识拼图就只差最後这块啦!今天我们要学的是怎麽画「响应式图表
」,也就是让图表在画面放大或缩小时,都能够随着画面去调整图表的大小!这个章节也是轻松简单的单元,只是有比较多细节需要设定,一起来看一下吧~
在之前的篇章中,我们建立的 svg 都有固定的宽高,这样的图表在网页上看很OK,但如果要在手机或平板上看,就会发现图表太大无法看
为了使用者在手机或平板上也能够看图表,因此我们要对图表进行一些设定,让它变成下面这样
要设定RWD图表的话,我们需要使用到 window 的 onresize 事件,每当 window 监听到画面大小有变化时,就会触发设定的方法。首先,我们先用d3的选取器把window选起来接着使用 selection.on( )的方法监听 resize 事件,并设定画面 resize 的时候要做什麽事
d3.select(window).on('resize', function(){
console.log('画面变化')
});
这样一来,画面大小变化时,就会触发我们设定好的功能啦(请看画面右方的 console 讯息)~
接着,我们要来设定外容器的高度。如果我们的 svg 是包在div中的话,就是设定这个div的宽度。
<div class="RWDChart">
<svg>......</svg>
</div>
我们使用 css 把外容器的宽度设定成百分比,让外容器能随着画面变化而缩放
.RWDChart{
width: 80%
}
再来设定 svg 的宽高吧!之前我们的 svg 宽高都是直接写死
const width = 500,
height = 400;
const svg = d3.select('.simpleChart')
.append('svg')
.attr('width', width)
.attr('height', height)
现在我们要改变作法,用外容器RWD的宽度来设定 svg 的宽高。
svg 宽度
:用 d3.selection 抓到外容器的宽度,接着用 parseInt( )将这个宽度赋予给 rwdSvgWidth 变数,接着将这个变数设定成 svg 的宽度svg 高度
:用刚刚设定好的 rwdSvgWidth 来设定 rwdSvgHeight 变数,并将 rwdSvgHeight 设定成 svg 的高度const rwdSvgWidth = parseInt(d3.select('.RWDChart').style('width')),
rwdSvgHeight = rwdSvgWidth*0.8,
margin = 30,
bandWidth = 20
const svg = d3.select('.RWDChart')
.append('svg')
.attr('width', rwdSvgWidth)
.attr('height', rwdSvgHeight);
这样一来,我们的 svg 宽高就能够随着画面缩放而增减啦!
现在我们可以开始绘制RWD的图表啦!由於这边的重点是RWD,因此绘制图表的程序码就先不呈现,而是着重在要怎麽让图表RWD上
function RWDChart(){
const rwdSvgWidth = parseInt(d3.select('.RWDChart').style('width')),
rwdSvgHeight = rwdSvgWidth*0.8,
margin = 30,
bandWidth = 20
const svg = d3.select('.RWDChart')
.append('svg')
.attr('width', rwdSvgWidth)
.attr('height', rwdSvgHeight);
// 以下为绘制图表的程序码
// ......
// ......
}
RWDChart() // 一开始要先执行一次,才能在画面开始时建立图表
d3.select(window).on('resize', RWDChart); // 接着要在每次画面变化时都重新渲染图表
但这时候出现一个新的问题:每次画面变化重新渲染图表时,我们的图表就会一直不停重复增加!!
这是因为画面变化时会重新渲染图表,但原本的图表也都还存在,导致图表不停的往下增加。因此我们要加上一段程序,让每次图表绘制前,都会删除掉原本的图表
function RWDChart(){
**d3.select('.RWDChart svg').remove(); // 删除前一次建立的图表**
const rwdSvgWidth = parseInt(d3.select('.RWDChart').style('width')),
rwdSvgHeight = rwdSvgWidth*0.8,
margin = 30,
bandWidth = 20
const svg = d3.select('.RWDChart')
.append('svg')
.attr('width', rwdSvgWidth)
.attr('height', rwdSvgHeight);
// 以下为绘制图表的程序码
// ......
// ......
}
RWDChart() // 一开始要先执行一次,才能在画面开始时建立图表
d3.select(window).on('resize', RWDChart); // 接着要在每次画面变化时都重新渲染图表
这样一来,就可以解决图表重复出现的问题啦~
最後,我们要讲一个有趣的功能~当图表随画面缩小时, 有时候坐标轴的刻度会因为图表缩小而重叠在一起
为了不让刻度重叠,我们要在图表缩小时减少刻度的数量。这时候就要用到 window.innerWidth 跟 ticks 设定的方法啦!
先来设定一个 tickNumber 的变数,并且:
最後将 tickNumber 作为参数带给 .ticks( ) 这个方法。由於这边不是在讲解如何建立图表,因此就只把刻度RWD的程序码撷取出来。想看完整程序码的人请直接到下方的 Giithub 页面查看~
// rwd X轴的刻度
let tickNumber = window.innerWidth > 450 ? null : 5;
xAxis = d3.axisBottom(xScale)
.ticks(tickNumber)
.tickFormat(function (d) {
//调整标签样式
return `${d} 元`;
})
这样就完成罗!
今天的内容就到这边。这样一来,D3 绘图的重要知识都已经全部讲解完毕啦!接下来我们就要运用这几天学到的知识去绘图罗!一天一张图表,我来了!!
最後附上本章的程序码与图表 Github 、 Github Page,需要的人请自行取用~
>>: JavaScript学习日记 : Day19 - Class继承
前言 上一篇我们讨论DDD的战术设计,它建议引用各种设计模式,提高生产力,因此接下来,就来介绍各种设...
我自己是从RD出身的主管,我自己也想了很久,我到底做对了什麽,与可能做错了什麽,让我自己培养出这样的...
使用 docker compose 来串起一连串的 Container 服务前,这边先笔记下一些在过...
在拖延症的影响下,周日原本打算多备点稿的我又变成只有当日更新。 可能以後要强制自己每天多写一篇比较实...
GKE GKE是GOOGLE在GCP上面的k8s cluster服务,对於GCP使用者来说,GKE可...