echarts自适应、响应式(适配rem)
响应式:能够适配不同的设备,比如:PC、平板、手机。
自适应:能够适配不同分辨率的界面,比如1920像素,500像素。
echarts自适应:拖动窗口时候,图表和图表内字体适配窗口大小。
接下来介绍两种方法,大家自行选择。
1.方法一:配合媒体查询
- 样式
- tip: 媒体查询的顺序必须从大的像素写到小的像素,因为他们的优先级是一样的,后面的代码覆盖前面的代码。如果反过来写,就达不到效果了。
css
<style>
#main {
width: 800px;
height: 400px;
}
/* 这里的意思是当屏幕宽度最大为750px的时候,触发这个样式 */
@media screen and (max-width: 750px) {
#main {
width: 400px;
height: 400px;
}
}
/* 这里的意思是当屏幕宽度最大为550px的时候,触发这个样式 */
@media screen and (max-width: 550px) {
#main {
width: 200px;
height: 400px;
}
}
</style>
- HTML和JS代码,下面使用的是饼图的option配置,去官网随便复制一个也可以。
js
<div id="main" class="header">header</div>
<script type="text/javascript">
var myChart = echarts.init(document.getElementById('main'));
var option = {
tooltip: {
trigger: 'item'
},
legend: {
top: '5%',
left: 'center',
textStyle: {
fontSize: 15
}
},
series: [
{
top: '20rem',
name: 'Access From',
type: 'pie',
radius: ['50%', '70%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2
},
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: 40,
fontWeight: 'bold'
}
},
labelLine: {
show: false
},
data: [
{value: 1048, name: 'Search Engine'},
{value: 735, name: 'Direct'},
{value: 580, name: 'Email'},
{value: 484, name: 'Union Ads'},
{value: 300, name: 'Video Ads'}
]
}
]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
// 关键代码
let timer;
function debounce(fn, delay) {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn()
}, delay)
}
window.addEventListener('resize', function () {
debounce(myChart.resize, 300)
})
</script>
- 下面对关键代码进行解释,第一个是简介版本:如果没有学习过防抖函数,可以使用第一个。第二个是优化后的代码,因为窗口变化会一直触发resize函数,所以使用防抖函数可以优化性能。
- echart自带resize函数。作用 : 重新刷新画布的函数,改变图表尺寸,在容器大小发生改变时需要手动调用。
- 简洁版:
js
//简洁版
window.addEventListener('resize', function () {
myChart.resize()
})
- 优化版
js
// 关键代码
let timer;
function debounce(fn, delay) {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn()
}, delay)
}
window.addEventListener('resize', function () {
debounce(myChart.resize, 300)
})
- 1400px下的图
- 700px下的图
- 500px下的图
方法二: 手动更改不同的样式(rem)
- 样式
css
html {
font-size: 10px;
}
#box {
font-size: 10px;
display: flex;
border: 1px solid black;
height: 8rem;
width: 8rem;
flex-direction: column;
overflow: hidden;
margin: 50px auto;
}
.header {
font-size: 2rem;
width: 100%;
height: 100%;
margin: 0 auto;
}
- html和js
- tip : 需要导入flexible.js包
js
<div id="box">
<div id="main" class="header">header</div>
</div>
// 导入flexible.js的代码
<script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/??flexible_css.js,flexible.js"></script>
<script type="text/javascript">
/* 这个函数作用:默认我们在1920px像素下的设计图,然后传入你想要的像素(res参数)。*/
/* 比如我们在1920px下的设计图需要12px的字体,那么我们调用这个参数传入12即可。*/
/* 如果我们在3840px下,需要展示出以上1920px下12px的字体,那么clientWidth就获取到当前屏幕大小,*/
/* 比如是clientWidth = 3840px,然后res * fontSize = 12 * 2 = 24,我们看到的大小就会等倍数放大。 */
/* 就能够达到不同分辨率下,相同的视觉效果 */
function fontSizeFn(res) {
const clientWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
if (!clientWidth) return;
let fontSize = clientWidth / 1920;
return res * fontSize;
}
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
// 指定图表的配置项和数据
// 这里对某些需要有变化的数据进行适配,调用fontSizeFn方法。
var option = {
tooltip: {
trigger: 'item'
},
legend: {
top: '5%',
left: 'center',
itemWidth: fontSizeFn(32),
itemHeight: fontSizeFn(32),
itemGap: fontSizeFn(30),
},
series: [
{
name: 'Access From',
type: 'pie',
radius: [fontSizeFn(70), fontSizeFn(180)],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2
},
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: 40,
fontWeight: 'bold'
}
},
labelLine: {
show: false
},
data: [
{value: 1048, name: 'Search Engine'},
{value: 735, name: 'Direct'},
{value: 580, name: 'Email'},
{value: 484, name: 'Union Ads'},
{value: 300, name: 'Video Ads'}
]
}
]
};
myChart.setOption(option);
// 关键代码
window.addEventListener('resize', function () {
refreshChart(myChart)
},false)
// 这里必须clear一下,然后再resize,然后再setOption,不然图不会发生变化。
// 这里为什么需要重新为某些参数赋值?
// 因为如果直接setOption的话,不把option.series[0].radius这些参数进行重新赋值的话,图表就不会发生变化。
// 当我们的屏幕尺寸发生变化的时候,需要重新调用fontSizeFn方法去计算当前的大小。
// 如果不重新设置,那么参数就是屏幕变化前的大小
function refreshChart(chart) {
chart.clear()
chart.resize()
option.series[0].radius = [fontSizeFn(70), fontSizeFn(180)]
option.legend.itemWidth = fontSizeFn(32)
option.legend.itemHeight = fontSizeFn(32)
option.legend.itemGap = fontSizeFn(30)
chart.setOption(option)
}
</script>
- 效果展示
缺点:
- 分辨率太大的话,图会和上面的legend重叠
- 分辨率太小的话,图会变小
总结: 第一个方法比较合适一点,第二个方法感觉比较难选择一个合适的参数。