使用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命名:如💖
- 💖并注意index索引值的不同💖
- 💖如果swiper设置loop循环播放:💖
- 🌟 引入css
swiper+tabs
- tab1
- tab2
- tab3
- tab4
- 🍗css文件🍗
/** * echarts分析 start */ .echarts-box { /*height: 9.14rem;*/ padding: 0 .3rem; box-sizing: border-box; background: #FFFFFF; } /*🌹 这里会修改lay-tab默认样式 */ .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轮播 */ .swiper-container { height: 7.6rem; } .swiper-pagination{ margin-top: .4rem; } /* echarts容器 */ .echarts-container{ width: 100%; height: 7.2rem; } /** * echarts分析 end */
- 🌼index.js文件🌼
layui.use(['element'], function () { var element = layui.element; /** * 设置参数 */ // echarts tabs选中项 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(){ // $.ajax({ // type: 'POST', // contentType: 'application/json', // url: '', // data: infoParams, // dataType: 'json', // success: function (res) { // TODO假设数据接口一次性返回,结构如下: // 外部变量存储echarts数据 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} ] } // 渲染swiper renderSwiper() // }, // error: function(err) { // console.log(err) // } // }); } /** * echarts统计 */ // tabs切换 element.on('tab(tabsType)', function(data){ tabIdx = data.index + '' if(mySwiper){ mySwiper.slideTo(data.index + 1, 1000, true); } }); /** * swiper */ function renderSwiper (){ mySwiper = new Swiper('.swiper-container', { loop: true, // 🌹这里要是开启,echarts容器必须使用class命名; 为false则无所谓 slidesPerView: 1, autoplay: false, pagination: '.swiper-pagination', onSlideChangeEnd: function(swiper){ console.log(swiper.activeIndex) // 🌹如果loop设置为false,则需要注意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 + ''); } // 渲染echarts renderPieECharts(taskCenterEcharts[tabIdxObj[tabIdx]['value']], tabIdxObj[tabIdx]['title']) }, }) } /** * 渲染echarts饼图 */ function renderPieECharts(data, title){ // 基于准备好的dom,初始化echarts实例 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🌿
// 假设你希望将根元素的font-size设置为16px(这相当于1rem = 16px) document.documentElement.style.fontSize = '16px'; // 或者,如果你想根据视口宽度动态设置font-size function setRemSize() { // 获取视口宽度 var viewportWidth = window.innerWidth || document.documentElement.clientWidth; // 假设设计稿宽度为750px,并且设计稿上1rem = 100px // 那么当视口宽度为750px时,font-size应该为100px // 我们可以根据这个比例来设置不同视口宽度下的font-size var designWidth = 750; var remSize = 100; // 设计稿上1rem的大小 var fontSize = (viewportWidth / designWidth) * remSize; // 设置font-size,但通常不会设置到小数像素,所以可能需要四舍五入或者使用Math.floor/Math.ceil fontSize = Math.round(fontSize * 100) / 100; // 四舍五入到小数点后两位 // 应用到根元素上 document.documentElement.style.fontSize = fontSize + 'px'; } // 调用函数来设置初始的font-size setRemSize(); // 并且监听窗口大小变化事件,以便在窗口大小改变时更新font-size window.addEventListener('resize', setRemSize);
🌴四、可以更完善🌴
- 案例中的tabs和swiper-item是固定的4个,完全可以根据接口返回的数据长度,生成动态数量的tabs和swiper-item
- 渲染echarts图的option写成的使一个函数,因为目前只是假设内容是统一的pie,可以设置更多类型,封装更加健全的方法
还没有评论,来说两句吧...