使用jq+layui-tab+echarts+swiper
实现选项卡轮播联动图表展示功能
✨一、实现功能
- 🌟技术框架
- 使用
layui-tab
实现tabs
切换 - 使用
swiper.js
实现轮播效果 - 使用
echarts.js
实现图表展示
- 🌟功能详情
- 布局为上中下:
tab
选项上,内容区为中,轮播分页为下 tab
选项卡内容区为echarts
图表统计图tab
选项卡与轮播分页(就是轮播底部的点点)对应,(数量与索引对应)- 当点击第
n
个tab
选项卡的时候,对应内容部分切换至第n
个内容区,swiper
轮播也对应播放至第n
个选项 - 当滑动轮播时,滑动到第
n
个选项时,想对选中第n
个tab
选项卡 - 轮播可以无限循环,当向右滑动超过最大
tab
数量,自动回滚至第一个重新滑动,反之当第一个向左滑动时,自动回滚至最后一个n
值所对应内容继续滑动
✨二、百句描述不如一眼官图:效果图如图展示:
✨三、代码
- 🍀
html
文件🍀
- 🌟 引入
css
layui.css
:swiper.min.css
index.css
:页面css样式
- 🌟 引入
js
jquery.min.js
layui.js
swiper.min.js
echarts.js
remcalc.js
:计算rem
index.js
:页面内部js
逻辑,必须放在layui.js
之后
- 🌟 注意事项:
- 💖如果
swiper
设置loop
循环播放:💖
- 💖
echarts
容器需使用class
命名:如<div class='echarts-container' ></div>
💖 - 💖并注意
index
索引值的不同💖
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>swiper+tabs</title>
<link rel="stylesheet" href="./css/layui.css">
<link rel="stylesheet" href="./css/swiper.min.css">
<link rel="stylesheet" href="./css/index.css">
<script src="./js/jquery.min.js"></script>
<script src="./js/layui.js"></script>
<script src="./js/swiper.min.js"></script>
<script src="./js/echarts.js"></script>
<script src="./js/remcalc.js"></script>
<script src="./js/index.js"></script>
</head>
<body>
<div class="container">
<div class="echarts-box">
<div class="layui-tab layui-tab-brief" lay-filter="tabsType">
<ul class="layui-tab-title">
<li class="layui-this" lay-id="1">tab1</li>
<li lay-id="2">tab2</li>
<li lay-id="3">tab3</li>
<li lay-id="4">tab4</li>
</ul>
</div>
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide">
<div class="echarts-container"></div>
</div>
<div class="swiper-slide">
<div class="echarts-container"></div>
</div>
<div class="swiper-slide">
<div class="echarts-container"></div>
</div>
<div class="swiper-slide">
<div class="echarts-container"></div>
</div>
</div>
<div class="swiper-pagination"></div>
</div>
</div>
</div>
</body>
</html>
- 🍗
css
文件🍗
.echarts-box {
padding: 0 .3rem;
box-sizing: border-box;
background: #FFFFFF;
}
.layui-tab{
margin: 0;
padding: 0;
}
.layui-tab-title {
font-weight: 400;
font-size: .26rem;
color: #636363;
text-align: center;
display: flex;
justify-content: space-between;
align-items: center;
}
.layui-tab-title li {
min-width: 1.04rem!important;
padding: 0;
}
.layui-tab-title .layui-this {
width: 1.44rem;
height: .42rem;
font-weight: 500!important;
font-size: .3rem!important;
color: #333333!important;
line-height: .42rem!important;
}
.layui-tab-title .layui-this:after {
width: .3rem!important;
top: -0.18rem!important;
left: calc(50% - .3rem)!important;
border-bottom: .09rem solid #1C71F1!important;
border-radius: .1rem;
}
.layui-tab-bar{
display: none;
}
.swiper-container {
height: 7.6rem;
}
.swiper-pagination{
margin-top: .4rem;
}
.echarts-container{
width: 100%;
height: 7.2rem;
}
- 🌼
index.js
文件🌼
layui.use(['element'], function () {
var element = layui.element;
var tabIdxObj = {
'0': {
value: 'tab1Data',
title: 'tab1分析'
},
'1': {
value: 'tab2Data',
title: 'tab2分析'
},
'2': {
value: 'tab3Data',
title: 'tab3分析'
},
'3': {
value: 'tab4Data',
title: 'tab4分享'
},
}
var tabIdx = '0'
var mySwiper = null
var taskCenterEcharts = {}
var infoParams = {}
function init(){
getInfoRequest()
}
init()
function getInfoRequest(){
taskCenterEcharts = {
tab1Data: [
{name: 'item1', value: 12},
{name: 'item2', value: 23},
{name: 'item3', value: 33},
{name: 'item4', value: 6}
],
tab2Data: [
{name: 'tab2item1', value: 9},
{name: 'tab2item2', value: 3},
{name: 'tab2item3', value: 8},
{name: 'tab2item4', value: 6}
],
tab3Data: [
{name: 'tab3item1', value: 12},
{name: 'tab3item2', value: 116}
],
tab4Data: [
{name: 'tab4item1', value: 122},
{name: 'tab4item2', value: 123},
{name: 'tab4item3', value: 63}
]
}
renderSwiper()
}
element.on('tab(tabsType)', function(data){
tabIdx = data.index + ''
if(mySwiper){
mySwiper.slideTo(data.index + 1, 1000, true);
}
});
function renderSwiper (){
mySwiper = new Swiper('.swiper-container', {
loop: true,
slidesPerView: 1,
autoplay: false,
pagination: '.swiper-pagination',
onSlideChangeEnd: function(swiper){
console.log(swiper.activeIndex)
if(swiper.activeIndex === 0) {
element.tabChange('tabsType', '4');
} else if(swiper.activeIndex === 5 ) {
element.tabChange('tabsType', '1');
} else {
element.tabChange('tabsType', swiper.activeIndex + '');
}
renderPieECharts(taskCenterEcharts[tabIdxObj[tabIdx]['value']], tabIdxObj[tabIdx]['title'])
},
})
}
function renderPieECharts(data, title){
var chartClass =document.getElementsByClassName('echarts-container');
const option = echartsOption(data, title)
for (let i = 0; i < chartClass .length; i++) {
const ele = chartClass [i];
window.addEventListener('resize', function () {
ele.resize();
});
echarts.init(ele).setOption(option)
}
}
function echartsOption(data, title) {
const option = {
title: {
text: title,
left: 'center',
textStyle: {
fontSize: 14,
fontWeight: 500,
lineHeight: 20
},
top: 20
},
color: ['#EF6667', '#73BFDE', '#1C71F1', '#FAC958'],
tooltip: {
show: true
},
legend:{
data: data.map(item => item.name),
bottom: 20,
left: 'center',
itemStyle: {
borderWidth: 2
}
},
series: [
{
type: 'pie',
radius: ['20%', '50%'],
data: data,
itemStyle: {
normal: {
label: {
show: true,
textStyle: {
color: "#333",
fontSize: "18",
fontWeight: 900
},
formatter: function(val) {
return val.value;
},
},
labelLine: {
show: true,
length: 15
},
},
},
}
]
};
return option
}
})
- 🌿
remcalc.js
🌿
document.documentElement.style.fontSize = '16px';
function setRemSize() {
var viewportWidth = window.innerWidth || document.documentElement.clientWidth;
var designWidth = 750;
var remSize = 100;
var fontSize = (viewportWidth / designWidth) * remSize;
fontSize = Math.round(fontSize * 100) / 100;
document.documentElement.style.fontSize = fontSize + 'px';
}
setRemSize();
window.addEventListener('resize', setRemSize);
🌴四、可以更完善🌴
- 案例中的
tabs
和swiper-item
是固定的4个,完全可以根据接口返回的数据长度,生成动态数量的tabs
和swiper-item
- 渲染
echarts
图的option
写成的使一个函数,因为目前只是假设内容是统一的pie
,可以设置更多类型,封装更加健全的方法