学习笔记之数据可视化(二)—— 页面布局(下)
续上一章
- 2.7 地图区域(.map)
- 2.7.1 实现步骤:
- 2.8 用户统计模块
- 2.8.1 布局:
- 2.8.2 柱状图
- 2.9 订单模块
- 2.9.1 订单区域布局
- 2.9.2 订单区域(order)-交互效果(此部分后续补充)
- 3.0 销售统计( sales )
- 3.0.1 布局
- 3.1 渠道分布、季度进度模块
- 3.1.1渠道分布(channel)-雷达图
- 3.1.2 销售进度模块-饼形图
- 3.2 全国热榜模块制作(重要)
- 3.2.1 预备知识-ES6模板字符
- 3.2.2 开始实现
2.7 地图区域(.map)
HTML结构代码如下:
<!-- 地图 --><div class="map"><h3><span class="icon-cube"></span> 设备数据统计</h3><div class="chart"><div class="geo"></div></div></div>
CSS代码如下:
/* 地图 */
.map {height: 7.225rem;margin-bottom: 0.25rem;display: flex;flex-direction: column;
}
.map h3 {line-height: 1;padding: 0.2rem 0;margin: 0;font-size: 0.25rem;color: #fff;font-weight: 400;
}
.map .icon-cube {color: #68d8fe;
}
.map .chart {flex: 1;background-color: rgba(255, 255, 255, 0.05);
}
.map .geo {width: 100%;height: 100%;
}
此时实现如下效果:
可以看上图中的地图区域明显紧贴左边column。所以,第二列(column) 需添加外边距(上:32px ;左、右 20px;下 0)。
找回刚开始布局时的样式(.viewport .column:nth-child(2)),在原划分为3:4:3 (中间column 划分占总体4份)代码基础上,再添加margin值,具体写法如下:
.viewport .column:nth-child(2) {flex: 4; // 此处最开始已设置margin: .4rem .25rem 0; // 本次新添加
}
注:因本部分地图较特殊,故添加地图的代码放到最后来完成。
引入地图
2.7.1 实现步骤:
- 从echarts社区示例中找最接近项目需求的例子,适当修改后引入HTML页面;
本项目地图引用示例:https://gallery.echartsjs.com/editor.html?c=x0-ExSkZDM (模拟飞机航线) - 下载china.js提供中国地图的js文件
- 由于代码较多,需新建一个js文件 myMap.js 引入
- 使用社区提供的配置即可。
需要修改:
- 去掉图例组件和标题组件
- 去掉背景颜色
- 修改地图省份背景 #142957
- 地图放大通过 zoom 设置为1.2即可
1)新建myMap.js
(function() {// 1、实例化对象;var myChart = echarts.init(document.querySelector(".geo"));// 2、指定配置和数据;var geoCoordMap = {'上海': [121.4648, 31.2891],'东莞': [113.8953, 22.901],'东营': [118.7073, 37.5513],//~~ 此处省略,详见该官方社区示例~~};// 3、把配置和数据给实例对象。myChart.setOption(option)
})();
2)在HTML里引入 china.js和myMap.js
<script src="js/china.js"></script>
<script src="js/myMap.js"></script>
实现的效果如下:
2.8 用户统计模块
模块效果图
2.8.1 布局:
- :给大的盒子Panel 添加一个新的user类名;
- 在Panel盒子里面,包含inner盒子(分下、下两部分);
上部分:h3标题(”全国用户总量统计“)
下部分:Chart 图表部分(分左、右两部分,左边柱形图.bar
,右边数据信息.data
)
- HTML结构:
<!-- 用户 --><div class="users panel"><div class="inner"><h3>全国用户总量统计</h3><div class="chart"><div class="bar"></div><div class="data"><div class="item"><h4>120,899</h4><span><i class="icon-dot" style="color: #ed3f35"></i>用户总量</span></div><div class="item"><h4>248</h4><span><i class="icon-dot" style="color: #eacf19"></i>本月新增</span></div></div></div></div></div>
- CSS样式:
/* 用户模块 */
.users {height: 4.25rem;display: flex;
}
.users .chart {display: flex;margin-top: .3rem;
}
.users .bar {width: 7.35rem;height: 3rem;
}
.users .data {display: flex;flex-direction: column;justify-content: space-between;width: 2.1rem;padding: .45rem .375rem;box-sizing: border-box;background-image: url(../images/rect.png);background-size: cover;
}
.users h4 {margin-bottom: .15rem;font-size: .35rem;color: #fff;
}
.users span {display: block;color: #4c9bfd;font-size: 0.2rem;
}
- 运行结果:
2.8.2 柱状图
实现步骤:
- 从”官方示例“中找最接近项目需求的例子,适当修改后引入HTML页面;
eChart 图表官方网址:https://echarts.apache.org/examples/zh/index.html#chart-type-bar
- 根据需求,定制图表。
本(用户统计)模块以下代码,如无特别说明,均为JavaScript代码
1、添加引入
: 打开index.js,创建立即执行函数,添加引入,语法格式如下:
(function() {// 1、实例化对象var myChart = echarts.init(document.querySelector(".bar"));// 2、修改配置项和数据 var option = { //实例图表配置项和数据信息// color: ['#3398DB'], color: new echarts.graphic.LinearGradient(// (x1,y2) 点到点 (x2,y2) 之间进行渐变0, 0, 0, 1, [{ offset: 0, color: '#00fffb' }, // 0 起始颜色{ offset: 1, color: '#0061ce' } // 1 结束颜色]),tooltip: {trigger: 'item'},grid: {left............. //此处省略}]};// 3、把配置指定给实例myChart.setOption(option);
})();
注:多个模块的立即执行函数之间,有分号隔开。
第一步:参考官方示例 + 分析
第二步:修改柱子的颜色 —— 修改柱子的纯色为线性渐变
修改前:
【方法一】:
// 修改线性渐变色方式 1
color: new echarts.graphic.LinearGradient(// (x1,y2) 点到点 (x2,y2) 之间进行渐变0, 0, 0, 1,[{ offset: 0, color: '#00fffb' }, // 0 起始颜色{ offset: 1, color: '#0061ce' } // 1 结束颜色]),
【方法二】:
// 修改线性渐变色方式 2
color: {type: 'linear',x: 0,y: 0,x2: 0,y2: 1,colorStops: [{offset: 0, color: 'red' // 0% 处的颜色}, {offset: 1, color: 'blue' // 100% 处的颜色}],globalCoord: false // 缺省为 false
},
修改方法:直接替换原图代码中的
color: ['#3398DB'],
修改后:
第三步:修改提示框组件原触发方式trigger: 'axis'
(将axis
改为item
:鼠标放到柱子上才触发), 取消此官方实例的鼠标经过柱子出现阴影的效果。
第四步:调整柱形图大小
柱形图用 在grid里调整
top 、right、bottom、left、containLabel
值;饼形图在series里调整radius
值.
containLabel:true / false
:是否包含坐标轴的刻度标签
第五步:设置图表网格显示与否与边框线颜色
show. true
//grid 四条边框的颜色
borderColor: 'rgba(0, 240, 255, 0.3)'
第六步: X 轴调整
要求如下:
- 柱子在刻度之间(
alignWithLabel: false
); - 剔除刻度不显示(
show: false
); - 刻度标签文字颜色 #4c9bfd 通过 axisLabel 对象设置(
axisLabel: { color: '#4c9bfd' }
); - 修改x轴线的颜色 通过
axisLine
里面的lineStyle
。
// x坐标轴颜色设置
axisLine:{lineStyle:{color:'rgba(0, 240, 255, 0.3)',// width:8, x轴线的粗细// opcity: 0, 如果不想显示x轴线 则改为 0}
}
X轴样式调整完整JavaScript 代码:
xAxis: [{// 类目要有data属性type: 'category',// 为data 中的数据设置刻度文字data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],// 刻度设置axisTick: {// true:图形和刻度居中中间// false:图形在刻度之间alignWithLabel: false,// 不显示刻度show: false}, // x坐标轴文字标签样式设置axisLabel: {color: '#4c9bfd'},// x坐标轴颜色设置axisLine:{lineStyle:{color:'rgba(0, 240, 255, 0.3)',// width:8, x轴线的粗细// opcity: 0, 如果不想显示x轴线 则改为 0}}}
第七步: Y 轴调整
要求如下:
- 剔除刻度不显示(
show: false
); - Y轴文字颜色 #4c9bfd 通过 axisLabel 对象设置(
axisLabel: { color: '#4c9bfd' }
); - Y轴分割线颜色 splitLine 对象里面 lineStyle 对象设置,
Y轴调整和X轴前三项相同,直接复制X轴代码到Y轴代码段,剩下Y轴分割线去新增设置:
// y轴 分割线的样式
axisLine: {lineStyle: {color: 'rgba(0, 240, 255, 0.3)',}}
Y轴设置完整JavaScript 代码如下:
yAxis: [{type: 'value',axisTick: {alignWithLabel: false,// 隐藏X轴刻度show: false},axisLabel: {color: "#4c9bfd"},// y坐标轴颜色设置axisLine: {lineStyle: {color: 'rgba(0, 240, 255, 0.3)',}},// y轴 分割线的样式 splitLine: {lineStyle: {color: 'rgba(0, 240, 255, 0.3)',}}}]
至此,用户统计模块代码运行后的效果如下:
柱形图线条样式总结
1)网格边框颜色:
grid {:show: true,borderColor: "rgba(0, 240, 255, 0.3)"
}
2)X轴和Y轴线条颜色:
xAxis/yAxis :{axisLine: {lineStyle: {color: "green" }
}
3)坐标轴分割线颜色:
xAxis/yAxis :{splitLine: {lineStyle: {color: "red" }
}
参见如下示意图:
第八步:单独修改其中的柱形样式
series 对象里的data数组,里面的每一个数据都影响其对应的柱形(其中的每个数据是支持对象)。
即可直接把data里面对应的数据修改为需求配置的对象即可。
1)修改柱子的颜色
例如,将
data: [2100, 1900, 1700, 1560, 1400, 1200, 1200, 1200, 900, 750, 600, 480, 240]
中的第6个数据,替换为:
data: [2100, 1900, 1700, 1560, 1400, { name: '', value: 1200, itemStyle: { color: "#254065" } }, 1200, 1200, 900, 750, 600, 480, 240]
或,采用换行的写法:
data: [2100, 1900, 1700, 1560, 1400,{ name: '', value: 1200, itemStyle: { color: "#254065" } // 修改当前柱形的样式},1200, 1200, 900, 750, 600, 480, 240]
2)取消(鼠标移到柱子上的)高亮:emphasis
例如:
data: [2100, 1900, 1700, 1560, 1400,{ name: '', value: 1200, itemStyle: { color: "#254065" } , // 修改当前柱形的样式emphasis: { color: "#254065"} // 取消高亮(将'自适应'改为原先的颜色)},1200, 1200, 900, 750, 600, 480, 240]
3)鼠标经过时,不显示提示框组件(工具提示隐藏):tooltip.extraCssText:
data: [2100, 1900, 1700, 1560, 1400,{ name: '', value: 1200, itemStyle: { color: "#254065" } , // 修改当前柱形的颜色emphasis: { // 取消高亮(将'自适应'改为原先的颜色)itemStyle:{color: "#254065"}},tooltip: {extraCssText: 'opacity:0'} // opacity:透明度,设为0即隐藏},1200, 1200, 900, 750, 600, 480, 240]
实现效果如下:
根据项目要求,3个1200的柱子都应设为此样式。因此,声明一个变量,将以上定制样式赋给变量,
(function() {var item = { name: '', value: 1200, itemStyle: { color: "#254065" } , // 修改当前柱形的颜色emphasis: { // 取消高亮(将'自适应'改为原先的颜色)itemStyle:{color: "#254065"}},tooltip: {extraCssText: 'opacity:0'} // opacity:透明度,设为0即隐藏}//... 此处省略data: [2100, 1900, 1700, 1560, 1400, item, item, item, 900, 750, 600, 480, 240]
然后,将变量放到柱形图模块的立即执行函数的最开始位置(function() {
,再在data相应位置引用。
到处为止,整个用户统计模块完成。完成效果如下:
用户统计模块完整JavaScript代码:
// 用户统计柱形图模块
(function() {var item = {name: '',value: 1200,itemStyle: { color: "#254065" }, // 修改当前柱形的颜色emphasis: { // 取消高亮(将'自适应'改为原先的颜色)itemStyle: {color: "#254065"}},tooltip: { extraCssText: 'opacity:0' } // opacity:透明度,设为0即隐藏}// 1、实例化对象var myChart = echarts.init(document.querySelector(".bar"));// 2、修改配置项和数据var option = {color: new echarts.graphic.LinearGradient(// (x1,y2) 点到点 (x2,y2) 之间进行渐变0, 0, 0, 1, [{ offset: 0, color: '#00fffb' }, // 0 起始颜色{ offset: 1, color: '#0061ce' } // 1 结束颜色]),tooltip: {trigger: 'item'},grid: {top: "3%",left: '0%',right: '3%',bottom: '3%',containLabel: true,show: true,//grid 四条边框的颜色borderColor: 'rgba(0, 240, 255, 0.3)'},xAxis: [{type: 'category',data: ['上海', '广州', '北京', '深圳', '合肥', '', '......', '', '杭州', '厦门', '济南', '成都', '重庆'],axisTick: {alignWithLabel: false,// 隐藏X轴刻度show: false},axisLabel: {color: "#4c9bfd"},axisLine: {lineStyle: {color: 'rgba(0, 240, 255, 0.3)',}}}],yAxis: [{type: 'value',axisTick: {alignWithLabel: false,// 隐藏X轴刻度show: false},axisLabel: {color: "#4c9bfd"},// y坐标轴颜色设置axisLine: {lineStyle: {color: 'rgba(0, 240, 255, 0.3)',}},// y轴 分割线的样式 splitLine: {lineStyle: {color: 'rgba(0, 240, 255, 0.3)',}}}],series: [{name: '用户统计',type: 'bar',barWidth: '60%',data: [2100, 1900, 1700, 1560, 1400, item, item, item, 900, 750, 600, 480, 240]}]};// 3、把配置指定给实例myChart.setOption(option);// 4. 当浏览器缩放时,图表也等比例缩放window.addEventListener("resize", function() {// 图表调用 resize方法myChart.resize();});
})()
2.9 订单模块
2.9.1 订单区域布局
- HTML结构
<!-- 订单 --><div class="order panel"><div class="inner"><!-- 筛选 --><div class="filter"><a href="javascript:;" class="active">365天</a><a href="javascript:;" >90天</a><a href="javascript:;" >30天</a><a href="javascript:;" >24小时</a></div><!-- 数据 --><div class="data"><div class="item"><h4>20,301,987</h4><span><i class="icon-dot" style="color: #ed3f35;"></i>订单量</span></div><div class="item"><h4>99834</h4><span><i class="icon-dot" style="color: #eacf19;"></i>销售额(万元)</span></div></div></div></div>
- CSS样式代码
/* 订单 */
.order {height: 1.875rem;
}
.order .filter {display: flex;
}
.order .filter a {display: block;height: 0.225rem;line-height: 1;padding: 0 0.225rem;color: #1950c4;font-size: 0.225rem;border-right: 0.025rem solid #00f2f1;
}
.order .filter a:first-child {padding-left: 0;
}
.order .filter a:last-child {border-right: none;
}
.order .filter a.active {color: #fff;font-size: 0.25rem;
}
.order .data {display: flex;margin-top: 0.25rem;
}
.order .item {width: 50%;
}
.order h4 {font-size: 0.35rem;color: #fff;margin-bottom: 0.125rem;
}
.order span {display: block;color: #4c9bfd;font-size: 0.2rem;
}
运行结果:
2.9.2 订单区域(order)-交互效果(此部分后续补充)
实现步骤:
- 提前准备数据;
- 点击后切tab激活样式;
- 点击后切换数据内容;
- 开启定时器动态切换数据。
(占位)
3.0 销售统计( sales )
3.0.1 布局
核心原理:
- series 里面的data 数据决定折线的显示;
- 当点击不同的tab标签, 就让 series 里面的data调用不同的数据;
- 除了准备年的数据,还需要准备季度、月和周的数据 。
1)HTML结构
<!-- 销售额 --><div class="sales panel"><div class="inner"><div class="caption"><h3>销售额统计</h3><a href="javascript:;" class="active" >年</a><a href="javascript:;" >季</a><a href="javascript:;" >月</a><a href="javascript:;" >周</a></div><div class="chart"><div class="label">单位:万</div><div class="line"></div></div></div></div>
2)css样式
/* 销售区域 */
.sales {height: 3.1rem;
}
.sales .caption {display: flex;line-height: 1;
}
.sales h3 {height: 0.225rem;padding-right: 0.225rem;border-right: 0.025rem solid #00f2f1;
}
.sales a {padding: 0.05rem;font-size: 0.2rem;margin: -0.0375rem 0 0 0.2625rem;border-radius: 0.0375rem;color: #0bace6;
}
.sales a.active {background-color: #4c9bfd;color: #fff;
}
.sales .inner {display: flex;flex-direction: column;
}
.sales .chart {flex: 1;padding-top: 0.1875rem;position: relative;
}
.sales .label {position: absolute;left: 0.525rem;top: 0.225rem;color: #4996f5;font-size: 0.175rem;
}
.sales .line {width: 100%;height: 100%;
}
运行后,实现的页面布局如下:
3)销售统计( sales )-线形图引入
实现步骤:
- 在eCharts官网寻找类似示例,根据需求分析并适当修改后,,引入到HTML页面中;
- 再按照需求定制。
**第一步:**寻找官方类似示例,给予分析。
eCharts官方参考实例:https://www.echartsjs.com/examples/zh/editor.html?c=line-stack
option = {tooltip: {// 通过坐标轴触发trigger: "axis"},legend: { // 图例组件data: ["邮件营销", "联盟广告"]},grid: {left: "3%",right: "4%",bottom: "3%",containLabel: true},xAxis: {type: "category",boundaryGap: false,data: ["周一", "周二"]},yAxis: {type: "value"},series: [{name: "邮件营销",type: "line",stack: "总量",data: [120, 132, 101, 134, 90, 230, 210]},{name: "联盟广告",type: "line",stack: "总量",data: [220, 182, 191, 234, 290, 330, 310]}]};
第二步:拆线图配置定制
- 需求1: 修改折线图区域的大小(
grid
),显示边框设置颜色:#012f4a
,并且显示刻度标签。
JavaScript 代码如下:
// 设置网格样式grid: { top: '20%',left: '3%',right: '4%',bottom: '3%',show: true,// 显示边框borderColor: '#012f4a',// 边框颜色containLabel: true // 包含刻度文字在内},
- 需求2: 修改图例组件中的文字颜色
#4c9bfd
, 距离右侧right
为 10%
// 图例组件legend: {textStyle: {color: '#4c9bfd' // 图例文字颜色},right: '10%' // 距离右边10%},
需求3: x轴相关配置
- 去除刻度;
- x轴刻度标签字体颜色:
#4c9bfd
; - 剔除坐标轴线颜色(将来使用Y轴分割线);
- 轴两端是不需要内间距
boundaryGap
。
JavaScript 代码:
xAxis: {type: 'category',data: ["周一", "周二"],axisTick: {show: false // 去除刻度线},axisLabel: {color: '#4c9bfd' // 文本颜色},axisLine: {show: false // 去除轴线},boundaryGap: false // 去除轴内间距},
运行代码效果:
需求4: y轴的定制
- 去除刻度;
- 设置字体颜色:#4c9bfd;
- 设置分割线颜色:#012f4a。
JavaScript 代码
yAxis: {type: 'value',axisTick: {show: false // 去除刻度},axisLabel: {color: '#4c9bfd' // 文字颜色},splitLine: {lineStyle: {color: '#012f4a' // 分割线颜色}}},
运行代码效果:
需求5: 两条线形图定制
- 颜色分别:#00f2f1 #ed3f35;
- 把折线修饰为圆滑 series 数据中添加 smooth 为 true。
color: ['#00f2f1', '#ed3f35'],series: [{name:'预期销售额',data: [820, 932, 901, 934, 1290, 1330, 1320],type: 'line',// 折线修饰为圆滑smooth: true,},{name:'实际销售额',data: [100, 331, 200, 123, 233, 543, 400],type: 'line',smooth: true,}]
需求6: 配置数据
// 图标数据series: [{name:'预期销售额',data: [24, 40, 101, 134, 90, 230, 210, 230, 120, 230, 210, 120],type: 'line',smooth: true},{name:'实际销售额',data: [40, 64, 191, 324, 290, 330, 310, 213, 180, 200, 180, 79], type: 'line',smooth: true}}]
代码运行效果如下:
注:如果Series 设置了name值,则图例组件legend 下面的data可以省略不写,否则应与Series保持一致。
- 如果不一致,会导致图例不显示。
4)销售统计( sales )-Tab栏(年、季、月、周)切换效果的实现
a、实现步骤:
- 准备切换需要依赖的数据(有4组:年、季、月、周);
- 绑定点击事件;
- 当一点击,就切换激活 tab栏的样式;
- 激活tab栏的同时,切换图表依赖的数据(重新渲染图表);
- 开启定时器,自动定时切换, 并且当鼠标经过sales时停止定时器,离开后开启定时器。
b、切换原理:
- series 里面的data 数据决定了折线的显示;
- 当点击不同的tab栏标签, series 里面的data就调用不同的数据;
- 上面已准备了年的数据,还需要准备季度、月和周的数据 。
第一步:准备数据,使用数据
JavaScript 代码:
// Tab栏切换效果制作
var data = {year: [ // 年份数据[24, 40, 101, 134, 90, 230, 210, 230, 120, 230, 210, 120],[40, 64, 191, 324, 290, 330, 310, 213, 180, 200, 180, 79]],quarter: [ // 季度数据[23, 75, 12, 97, 21, 67, 98, 21, 43, 64, 76, 38],[43, 31, 65, 23, 78, 21, 82, 64, 43, 60, 19, 34]],month: [ // 月份数据[34, 87, 32, 76, 98, 12, 32, 87, 39, 36, 29, 36],[56, 43, 98, 21, 56, 87, 43, 12, 43, 54, 12, 98]],week: [ // 周数据[43, 73, 62, 54, 91, 54, 84, 43, 86, 43, 54, 53],[32, 54, 34, 87, 32, 45, 62, 68, 93, 54, 54, 24]]}
此时,将声明好的data对象中的4个属性(
year
、quarter
、month
、week
)中的数组,替换eCharts折线图配置数据中的data数据;
注意程序执行的先后顺序。即声明的4组数据,要放在即时执行函数内的顶部;
(如下所示):
series: [{name:'预期销售额',data: data.year[0],type: 'line',smooth: true,itemStyle: {color: '#00f2f1'}},{name:'实际销售额',data: data.year[1],type: 'line',smooth: true,itemStyle: {color: '#ed3f35'}}]
第二步:点击切换效果
// 2)点击切换效果
$('.sales .caption').on('click', 'a', function() {// 点击当前a,高亮显示,即调用active$(this).addClass('active').siblings('a').removeClass('active')
})
点击Tab栏切换,所点击的标签高亮显示:
上面只完成了切换时的高亮显示。接下来,将完成点击切换到对应数据的效果:
1)首先,分别给4个a标签
声明一个自定义属性data-type
,拿到字符串“year”、“quarter”、“month”或“week”;
<!-- 销售统计模块--><div class="sales panel"><div class="inner"><div class="caption"><h3>销售额统计</h3><a href="javascript:;" class="active" data-type="year">年</a><a href="javascript:;" data-type="quarterr">季</a><a href="javascript:;" data-type="month">月</a><a href="javascript:;" data-type="week">周</a></div><div class="chart"><div class="label">单位:万</div><div class="line"></div></div></div></div>
2)通过H5自定义属性的方法"dataset.定义类名
",拿到自定义属性的值;
用console.log(this.dataset.type)
调试输出:当前点击的是哪个按钮
// 拿到当前a 的自定义属性var arr = data[this.dataset.type];
3)将获取的配置好的新数据给实例对象:
$('.sales .caption').on('click', 'a', function() {// 点击当前a,高亮显示,即调用active$(this).addClass('active').siblings('a').removeClass('active');// 拿到当前a 的自定义属性var arr = data[this.dataset.type];// 根据拿到数据重新渲染series里面的data值option.series[0].data = arr[0];option.series[1].data = arr[1];// 把配置好的新数据给实例对象。myChart.setOption(option)})
运行代码,效果如下:
第4步:实现Tab栏自动切换
a、每隔多少秒,就让a自动添加一个点击事件;
b、鼠标经过salse关闭定时器setInterval(function(){},3000)
,离开开户定时器。
hover()
方法规定,当鼠标指针悬停在被选元素上时要运行的两个函数。方法触发 mouseenter 和 mouseleave 事件。
注意: 如果只指定一个函数,则 mouseenter 和 mouseleave 都执行它。
// 鼠标经过和离开,
$(".sales").hover(function() {clearInterval(timer); // 鼠标经过停止定时器},function() {clearInterval(timer);timer = setInterval(function() {index++ // 由于第1个已默认选中,所以从第二个开始if (index >= 4) index = 0;as.eq(index).click();}, 1000);});
最后一步,给图表添加自动缩放
// 4. 当浏览器缩放的时候,添加等比例缩放window.addEventListener("resize", function() {// 让图表调用 resize方法myChart.resize();});
“销售统计模块”完整代码(JavaScript部分):
// 销售统计模块
(function() {// Tab栏切换效果制作// 1)准备数据var data = {year: [[24, 40, 101, 134, 90, 230, 210, 230, 120, 230, 210, 120],[40, 64, 191, 324, 290, 330, 310, 213, 180, 200, 180, 79]],quarter: [[23, 75, 12, 97, 21, 67, 98, 21, 43, 64, 76, 38],[43, 31, 65, 23, 78, 21, 82, 64, 43, 60, 19, 34]],month: [[34, 87, 32, 76, 98, 12, 32, 87, 39, 36, 29, 36],[56, 43, 98, 21, 56, 87, 43, 12, 43, 54, 12, 98]],week: [[43, 73, 62, 54, 91, 54, 84, 43, 86, 43, 54, 53],[32, 54, 34, 87, 32, 45, 62, 68, 93, 54, 54, 24]]}// 1、实例化对象;var myChart = echarts.init(document.querySelector(".line"))// 2、指定配置和数据;var option = {tooltip: {trigger: "axis"},legend: {// 距离容器右边距10%textStyle: {color: "#4c9bfd"},right: "10%",data: ["预期销售额", "实际销售额"]},grid: {top: "20%",left: "3%",right: "4%",bottom: "3%",show: true, // 显示边框borderColor: "#012f4a",containLabel: true},xAxis: {type: "category",boundaryGap: false,data: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],axisTick: {show: false // 去除刻度},axisLabel: {color: "#4c9bfd" //修改X轴刻度标签文字颜色},// 去除X轴颜色axisLine: {show: false},boundaryGap: false // 去除轴内间距},yAxis: {type: "value",axisTick: {show: false // 去除刻度},axisLabel: {color: "#4c9bfd" //修改X轴刻度标签文字颜色},// 修改Y轴分割线的颜色splitLine: {lineStyle: {color: "#012f4a"}}},series: [{name: "预期销售额",type: "line",smooth: true,stack: "总量",data: data.year[0]},{name: "实际销售额",type: "line",smooth: true,stack: "总量",data: data.year[1]}]};// 3、把配置和数据给实例化对象。myChart.setOption(option)// Tab栏切换效果制作// 2)点击切换效果$('.sales .caption').on('click', 'a', function() {// 点击当前a,高亮显示,即调用active$(this).addClass('active').siblings('a').removeClass('active');index = $(this).index() - 1;// 拿到当前a 的自定义属性var arr = data[this.dataset.type];// 根据拿到数据重新渲染series里面的data值option.series[0].data = arr[0];option.series[1].data = arr[1];// 把配置好的新数据给实例对象。myChart.setOption(option);});// 3、Tab栏自动切换// 开启定时器,每隔3秒切换一次var as = $(".sales .caption a");var index = 0var timer = setInterval(function() {index++ // 因为第1个已默认处于选中状态if (index >= 4) index = 0;as.eq(index).click();}, 1000);$(".sales").hover(function() {clearInterval(timer); // 鼠标经过停止定时器},function() {clearInterval(timer);timer = setInterval(function() {index++ // 因为第1个已默认处于选中状态if (index >= 4) index = 0;as.eq(index).click();}, 1000);});// 4. 给图表添加自适应window.addEventListener("resize", function() {myChart.resize();});
})();
3.1 渠道分布、季度进度模块
- HTML结构:
<!-- 渠道 季度 --><div class="wrap"><div class="channel panel"><div class="inner"><h3>渠道分布</h3><div class="data"><div class="radar"></div></div></div></div><div class="quarter panel"><div class="inner"><h3>一季度销售进度</h3><div class="chart"><div class="box"><div class="gauge"></div><div class="label">75<small> %</small></div></div><div class="data"><div class="item"><h4>1,321</h4><span><i class="icon-dot" style="color: #6acca3"></i>销售额(万元)</span></div><div class="item"><h4>150%</h4><span><i class="icon-dot" style="color: #ed3f35"></i>同比增长</span></div></div></div></div></div></div>
- css样式:
/* 渠道区块 */
.wrap {display: flex;
}
.channel,
.quarter {flex: 1;height: 2.9rem;
}
.channel {margin-right: 0.25rem;
}
.channel .data {overflow: hidden;
}
.channel .data .radar {height: 2.1rem;width: 100%;background-color: pink;
}
.channel h4 {color: #fff;font-size: 0.4rem;margin-bottom: 0.0625rem;
}
.channel small {font-size: 50%;
}
.channel span {display: block;color: #4c9bfd;font-size: 0.175rem;
}
/* 季度区块 */
.quarter .inner {display: flex;flex-direction: column;margin: 0 -0.075rem;
}
.quarter .chart {flex: 1;padding-top: 0.225rem;
}
.quarter .box {position: relative;
}
.quarter .label {transform: translate(-50%, -30%);color: #fff;font-size: 0.375rem;position: absolute;left: 50%;top: 50%;
}
.quarter .label small {font-size: 50%;
}
.quarter .gauge {height: 1.05rem;
}
.quarter .data {display: flex;justify-content: space-between;
}
.quarter .item {width: 50%;
}
.quarter h4 {color: #fff;font-size: 0.3rem;margin-bottom: 0.125rem;
}
.quarter span {display: block;width: 100%;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;color: #4c9bfd;font-size: 0.175rem;
}
结构布局和样式处理后如下所示:
3.1.1渠道分布(channel)-雷达图
实现步骤:
- 找到eCharts官方类似图表示例,经过简单分析修改后,引入到HTML页面中;
- 按照项目需求定制图表配置和数据。
第一步:参考类似实例
eCharts官方参考示例:https://www.echartsjs.com/examples/zh/editor.html?c=radar-aqi
去掉多余的配置项和示例数据后,导入如下效果的图表
如上图,大概的外形已准备好,下面将剩下的配置项和数据代码引入页面当中:
(function() { // 准备立即执行函数// 1、实例化对象;var myChart = echarts.init(document.querySelector('.radar'));// 2、指定配置和数据;var dataBJ = [[55, 9, 56, 0.46, 18, 6, 1]];var lineStyle = {normal: {width: 1,opacity: 0.5}};var option = {radar: {indicator: [{ name: 'AQI', max: 300 },{ name: 'PM2.5', max: 250 },{ name: 'PM10', max: 300 },{ name: 'CO', max: 5 },{ name: 'NO2', max: 200 },{ name: 'SO2', max: 100 }],shape: 'circle',splitNumber: 5,name: {textStyle: {color: 'rgb(238, 197, 102)'}},splitLine: {lineStyle: {color: ['rgba(238, 197, 102, 0.1)', 'rgba(238, 197, 102, 0.2)','rgba(238, 197, 102, 0.4)', 'rgba(238, 197, 102, 0.6)','rgba(238, 197, 102, 0.8)', 'rgba(238, 197, 102, 1)'].reverse()}},splitArea: {show: false},axisLine: {lineStyle: {color: 'rgba(238, 197, 102, 0.5)'}}},series: [{name: '北京',type: 'radar',lineStyle: lineStyle,data: dataBJ,symbol: 'none',itemStyle: {color: '#F9713C'},areaStyle: {opacity: 0.1}}]};// 3、将配置和数据给实例对象。myChart.setOption(option);
})();
运行代码后,初步实现如下效果:
第二步: 渠道分布模块-雷达图定制
定制需求与实现过程
- 调整雷达图大小(雷达图的修饰较为特别,区别于其它图在series里设置);
- 指示器轴的分割段数为4条(由5个修改为4个圆圈);
- 雷达图分割线设为白色半透明 0.5;
- 雷达图 坐标轴轴线相关设置(竖线)
axisLine
; - 修饰雷达图文字颜色为 #4c9bfd;
- 修饰 区域填充样式 series 对象;
- 区域填充的线条颜色为白色;
- 标记的图形(拐点)设置 注意在 series 里面设置;
- 鼠标经过显示提示框组件;
- 更换数据;
- 整个代码。
雷达图配置项官方文档:https://echarts.apache.org/zh/option.html#radar.radius
1)修改雷达图大小:在引入的代码中的radar段中加入:
radar:{// 外半径占据容器大小radius: '65%',
}
2)修改雷达图分割段数:
radar:{// 外半径占据容器大小radius: '65%',spliteNumber: 4, //修改分割段数为4
}
3)修改分割线颜色为白色半透明:
// 坐标轴在 grid 区域中的分隔线(圆圈)splitLine: {lineStyle: {color: 'rgba(255, 255, 255, 0.5)',}},
4)修改雷达图文字的颜色:
name: {textStyle: {// 修饰雷达图文字的颜色color: '#4c9bfd'}
}
5)修改区域填充的背景颜色:
areaStyle: {color: 'rgba(238, 197, 102, 0.6)',}
6)修饰填充区域的线条颜色:
lineStyle: {// 修饰填充区域的线条normal: {color: '#fff',width: 1,opacity: 0.5}
},
7)数据标记样式设置:
// 设置图形标记为圆点
symbol: 'circle',// 设置小圆点大小
symbolSize: 5,// 设置小圆点颜色
itemStyle: {color: '#fff'
},// 显示数据标签
label: {show: true,fontSize: 10
},
8)控制数据提示框组件的显示位置(鼠标经过提示组件):
tooltip: {show: true,// 数据提示框组件的显示位置position: ['60%', '10%']
},
9)替换原示例雷达图中的数据:
// 雷达图的指示器 内部填充数据indicator: [{ name: '机场', max: 100 },{ name: '商场', max: 100 },{ name: '火车站', max: 100 },{ name: '汽车站', max: 100 },{ name: '地铁', max: 100 }],
data: [[90, 19, 56, 11, 34]],
10)添加浏览器缩放自适应:
window.addEventListener("resize", function() {myChart.resize();
});
至此,完成 渠道分布-雷达图 的制作
雷达图的修饰总结如下图:
渠道分布雷达图整个代码:
// 销售渠道模块-雷达图
(function() { // 准备立即执行函数// 1、实例化对象;var myChart = echarts.init(document.querySelector('.radar'));// 2、指定配置和数据;var option = {tooltip: {show: true,// 数据提示框组件的显示位置position: ['60%', '10%']},radar: {indicator: [{ name: '机场', max: 100 },{ name: '商场', max: 100 },{ name: '火车站', max: 100 },{ name: '汽车站', max: 100 },{ name: '地铁', max: 100 }],radius: "65%",shape: 'circle',// 分割的圆圈个数splitNumber: 4,name: {textStyle: {// 修饰雷达图文字的颜色color: '#4c9bfd'}},// 分割的圆圈线条颜色splitLine: {lineStyle: {color: 'rgba(255, 255, 255, 0.5)',}},splitArea: {show: false},// 将坐标轴的线修改为白色半透明axisLine: {lineStyle: {color: 'rgba(255, 255, 255, 0.5)'}}},series: [{name: '北京',type: 'radar',lineStyle: {normal: {// 修饰填充区域的线条颜色color: '#fff',width: 1,opacity: 0.5}},data: [[90, 19, 56, 11, 34]],// 设置图形标记为圆点symbol: 'circle',// 设置小圆点大小symbolSize: 5,// 设置小圆点颜色itemStyle: {color: '#fff'},// 显示数据标签label: {show: true,fontSize: 10},areaStyle: {// 修饰区域填充的背景颜色color: 'rgba(238, 197, 102, 0.6)',}}]};// 3、将配置和数据给实例对象。myChart.setOption(option);// 4. 给图表添加自适应window.addEventListener("resize", function() {myChart.resize();});
})();
3.1.2 销售进度模块-饼形图
实现步骤:
- 找到echarts官方的类似示例,简单分析修改后,引入到HTML页面中;
- 按照项目需求定制。
echarts官方示例:https://www.echartsjs.com/examples/zh/editor.html?c=pie-doughnut
第一步:参考官方示例
官方示例如图:
半圆形做法原理:
把一个饼形图分成三段,下面一段颜色设为透明即可
第一步:引入饼形图配置和数据
// 销售进度-饼形(半圆形图)
(function() {// 1、实例化对象;var myChart = echarts.init(document.querySelector('.gauge'));// 2、指定配置项和数据;var option = {series: [{name: '销售进度',type: 'pie',radius: ['50%', '70%'],labelLine: {show: false},data: [{ value: 100 },{ value: 100 },{ value: 200 }]}]};// 3、将配置项和数据给实例对象。myChart.setOption(option);
})();
第二步:饼形图定制
要求如下:
- 改成半圆,图表大一些,让
50%
文字在中心; - 鼠标经过不变大,修改第一段颜色渐变
#00c9e0
->#005fc1
,修改第二段颜色#12274d
;
将data对象中的第3数据后面,再加上itemStyle
属性,并将itemStyle
里面的color
属性设置为透明:
data: [{ value: 100 },{ value: 100 },{value: 200,itemStyle: {color: 'transparent'}}
]
这样,即实现了半圆的效果:
但此时的半圆是侧着的,需要旋转。在series
里有一个startAngle
参数可以帮我们实现旋转。
`startAngle:它设置的不是旋转角度,是起始角度,支持范围[0, 360],默认角度是90度。
书写以下代码,将起始角度由90设为180,即实现了需要的效果:
startAngle: 180,
第三步:修改饼形图的大小并调整图表到合适的位置
语法格式:
1)调整大小:radius: [数据1, 数据2]
radius
后面跟的是数组:数据1 为内圆半径,数据2为外圆半径
2)图表移动位置:center: [数据1 数据2]
代码及运行后的效果如下:
// 放大图形
radius: ['120%', '150%'],// 移动下位置 套住50%文字
center: ['48%', '80%']
第四步:取消默认的鼠标经过偏移放大图形、修改半圆形饼图的第一段为渐变色,第二段为半透明
// 鼠标经过不变大
hoverOffset:0
hoverOffset:高亮扇区的偏移距离(默认是10)。
data: [{value: 100,itemStyle: {// 颜色渐变#00c9e0->#005fc1color: new echarts.graphic.LinearGradient(// (x1,y2) 点到点 (x2,y2) 之间进行渐变0,0,0,1, [{ offset: 0, color: "#00c9e0" }, // 0% 处的颜色{ offset: 1, color: "#005fc1" } // 100% 处的颜色])}},{value: 100,itemStyle: {color: '#12274d'}},
{value: 200,itemStyle: {color: 'transparent'}}
]
饼形图模块完整代码:
// 销售进度-饼形(半圆形图)
(function() {// 1、实例化对象;var myChart = echarts.init(document.querySelector('.gauge'));// 2、指定配置项和数据;var option = {series: [{name: '销售进度',type: 'pie',// 放大图形radius: ['120%', '150%'],// 移动下位置 套住50%文字center: ['48%', '80%'],labelLine: {show: false},// 饼形图的起始角度startAngle: 180,// 取消鼠标经过扇区的偏移距离hoverOffset: 0,data: [{value: 100,itemStyle: {// 颜色渐变#00c9e0->#005fc1color: new echarts.graphic.LinearGradient(// (x1,y2) 点到点 (x2,y2) 之间进行渐变0,0,0,1, [{ offset: 0, color: "#00c9e0" }, // 0% 处的颜色{ offset: 1, color: "#005fc1" } // 100% 处的颜色])}},{value: 100,itemStyle: {color: '#12274d'}},{value: 200,itemStyle: {color: 'transparent'}}]}]};// 3、将配置项和数据给实例对象。myChart.setOption(option);// 4. 给图表添加自适应window.addEventListener("resize", function() {myChart.resize();});
})();
至此,整体效果完成如图:
3.2 全国热榜模块制作(重要)
通过本节学习,能达到的目的
- 实际开发中,后台返回的真实数据如何渲染到页面中;
- ES6模板字符相关知识 ;
ES6模板字符:可以极大的提高开发效率。
3.2.1 预备知识-ES6模板字符
1)ES6 语法规范:
$ { 表达式 }
// 模板字符串使用反钩号 ``, 而且允许自由换行。
2)ES6 模板字符语法示例
// 模版字符
var star = {name: "刘德华",age: 18};// 传统写法 拼接时引号易出问题console.log("我的名字是" + star.name + "我的年龄是" + star.age);// ES6 模板字符写法console.log(`我的名字是${star.name}我的年龄是${star.age}`);console.log(`<span>${star.name}</span><span>${star.age}</span>`);
3.2.2 开始实现
实现思路:
- 准备后台返回的真实数据;
- 利用数据渲染各省热销模块
sup
模块 (拼接html
格式字符串,进行渲染); - 当鼠标进入
tab
的时候- 激活当前的tab样式,删除其他
tab
的样式; - 渲染各省热销
sub
模块 (拼接html格式字符串,进行渲染)。
- 激活当前的tab样式,删除其他
- 默认激活第一个
tab
的效果; - 开启定时器,按依次切换;
html结构:
<!-- 排行榜 --><div class="top panel"><div class="inner"><div class="all"><h3>全国热榜</h3><ul><li><i class="icon-cup1" style="color: #d93f36;"></i>可爱多</li><li><i class="icon-cup2" style="color: #68d8fe;"></i>娃哈啥</li><li><i class="icon-cup3" style="color: #4c9bfd;"></i>喜之郎</li></ul></div><div class="province"><h3>各省热销 <i class="date">// 近30日 //</i></h3><div class="data"><ul class="sup"><li><span>北京</span><span>25,179 <s class="icon-up"></s></span></li><li><span>河北</span><span>23,252 <s class="icon-down"></s></span></li><li><span>上海</span><span>20,760 <s class="icon-up"></s></span></li><li><span>江苏</span><span>23,252 <s class="icon-down"></s></span></li><li><span>山东</span><span>20,760 <s class="icon-up"></s></span></li></ul><ul class="sub"><!-- <li><span></span><span> <s class="icon-up"></s></span></li> --></ul></div></div></div></div>
- css样式:
/* 排行榜 */
.top {height: 3.5rem;
}
.top .inner {display: flex;
}
.top .all {display: flex;flex-direction: column;width: 2.1rem;color: #4c9bfd;font-size: 0.175rem;vertical-align: middle;
}
.top .all ul {padding-left: 0.15rem;margin-top: 0.15rem;flex: 1;display: flex;flex-direction: column;justify-content: space-around;
}
.top .all li {overflow: hidden;
}
.top .all [class^="icon-"] {font-size: 0.45rem;vertical-align: middle;margin-right: 0.15rem;
}
.top .province {flex: 1;display: flex;flex-direction: column;color: #fff;
}
.top .province i {padding: 0 0.15rem;margin-top: 0.0625rem;float: right;font-style: normal;font-size: 0.175rem;color: #0bace6;
}
.top .province s {display: inline-block;transform: scale(0.8);text-decoration: none;
}
.top .province .icon-up {color: #dc3c33;
}
.top .province .icon-down {color: #36be90;
}
.top .province .data {flex: 1;display: flex;margin-top: 0.175rem;
}
.top .province ul {flex: 1;line-height: 1;margin-bottom: 0.175rem;
}
.top .province ul li {display: flex;justify-content: space-between;
}
.top .province ul span {display: block;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;
}
.top .province ul.sup {font-size: 0.175rem;
}
.top .province ul.sup li {color: #4995f4;padding: 0.15rem;
}
.top .province ul.sup li.active {color: #a3c6f2;background-color: rgba(10, 67, 188, 0.2);
}
.top .province ul.sub {display: flex;flex-direction: column;justify-content: space-around;font-size: 0.15rem;background-color: rgba(10, 67, 188, 0.2);
}
.top .province ul.sub li {color: #52ffff;padding: 0.125rem 0.175rem;
}
.clock {position: absolute;top: -0.45rem;right: 0.5rem;font-size: 0.25rem;color: #0bace6;
}
.clock i {margin-right: 5px;font-size: 0.25rem;
}
@media screen and (max-width: 1600px) {.top span {transform: scale(0.9);}.top .province ul.sup li {padding: 0.125rem 0.15rem;}.top .province ul.sub li {padding: 0.0625rem 0.15rem;}.quarter span {transform: scale(0.9);}
}
第一步: 得到后台数据(实际开发中,通过ajax请求在后台获得)
JavaScript 代码如下:
// 全国热榜模块
(function() {// 准备相关数据var hotData = [{city: '北京', // 城市sales: '25, 179', // 销售额flag: true, // 上升还是下降brands: [ // 品牌种类数据{ name: '可爱多', num: '9,086', flag: true },{ name: '娃哈哈', num: '8,341', flag: true },{ name: '喜之郎', num: '7,407', flag: false },{ name: '八喜', num: '6,080', flag: false },{ name: '小洋人', num: '6,724', flag: false },{ name: '好多鱼', num: '2,170', flag: true },]},{city: '河北',sales: '23,252',flag: false,brands: [{ name: '可爱多', num: '3,457', flag: false },{ name: '娃哈哈', num: '2,124', flag: true },{ name: '喜之郎', num: '8,907', flag: false },{ name: '八喜', num: '6,080', flag: true },{ name: '小洋人', num: '1,724', flag: false },{ name: '好多鱼', num: '1,170', flag: false },]},{city: '上海',sales: '20,760',flag: true,brands: [{ name: '可爱多', num: '2,345', flag: true },{ name: '娃哈哈', num: '7,109', flag: true },{ name: '喜之郎', num: '3,701', flag: false },{ name: '八喜', num: '6,080', flag: false },{ name: '小洋人', num: '2,724', flag: false },{ name: '好多鱼', num: '2,998', flag: true },]},{city: '江苏',sales: '23,252',flag: false,brands: [{ name: '可爱多', num: '2,156', flag: false },{ name: '娃哈哈', num: '2,456', flag: true },{ name: '喜之郎', num: '9,737', flag: true },{ name: '八喜', num: '2,080', flag: true },{ name: '小洋人', num: '8,724', flag: true },{ name: '好多鱼', num: '1,770', flag: false },]},{city: '山东',sales: '20,760',flag: true,brands: [{ name: '可爱多', num: '9,567', flag: true },{ name: '娃哈哈', num: '2,345', flag: false },{ name: '喜之郎', num: '9,037', flag: false },{ name: '八喜', num: '1,080', flag: true },{ name: '小洋人', num: '4,724', flag: false },{ name: '好多鱼', num: '9,999', flag: true },]}]
})();
第二步:根据数据渲染各省热销 sup 模块内容
- 删掉原先css 样式代码里自带的小
li
- 遍历数据
$.each()
- 拼接字符串把数据动态的渲染到
li
的span
里面 - 追加给
.sup
盒子
1)用$.each()
方法,遍历后台获取的数据对象 hotData
$.each(hotData, function(index, item) { // item 得到每个对象supHTML += `<li><span>北京</span><span>25,179 <s class="icon-up"></s></span></li>`;})
})();
2)拼接字符串并追加到.sup
盒子
var supHTML = "" // 声明一个拼接字符串变量,初始值为空$.each(hotData, function(index, item) { // item 得到每个对象// ES6 模板字符写法supHTML += `<li><span>${item.city}</span><span>${item.sales}<s class="icon-up"></s></span></li>`;$(".sup").html(supHTML); // 通过jQery的html方法,追加到sup盒子})
})();
实现效果如下:
接下来,需要根据flag
返回的值是true
还是false
,来判断上升和下降,去调用对应的icon-down
( ↓ 箭头)或icon-up
(↑ 箭头)。
代码如下:
var supHTML = "" // 声明一个拼接字符串变量,初始值为空$.each(hotData, function(index, item) { // item 得到每个对象supHTML += `<li><span>${item.city}</span><span>${item.sales}<s class=${item.flag? "icon-up":"icon-down"}></s></span></li>`;$(".sup").html(supHTML);})
})();
由于字符串里不支持
if...else...
,因此,这里使用了三元表达式
,对获取到的flag
的值(ture
、false
)进行判断
通过以上代码,实现了箭头图标的调用。运行结果如下:
3)鼠标经过.tab
时,当前小li
高亮显示(mouseinter)。
由于小li
是动态生成的,所以在jQuery里面要用事件委托。
// 3、鼠标经过`.tab`时,当前小`li`高亮显示$('.province .sup').on('mouseenter', 'li', function() {// $(this)的兄弟元素也是li,故siblings() 括号内省略$(this).addClass('active').siblings().removeClass();});
渲染省份相关数据
第三步:当数据进入 tab
时
- 激活当前的tab样式,删除其他tab的样式;
- 渲染各省热销
sub
模块 ;- 当鼠标进入
tab
时,注意:只遍历当前索引号对应的城市对象里面的brands
; - 拼接html格式字符串,进行渲染。
- 当鼠标进入
获取城市对象的品牌的过程
$('.province .sup').on('mouseenter', 'li', function() {$(this).addClass('active').siblings().removeClass();··拿到城市对象的品牌的过程··// 1、获取当前小li的索引号// console.log($(this).index());// 2、得到当前的城市// console.log(hotData[$(this).index()]);// 3、拿到城市对象的品牌各类console.log(hotData[$(this).index()].brands);});
第三步完整代码:
// 3、鼠标经过`.tab`时,当前小`li`高亮显示$('.province .sup').on('mouseenter', 'li', function() {$(this).addClass('active').siblings().removeClass();// 拿到当前城市的品牌对象// console.log($(this).index());// 得到当前的城市// console.log(hotData[$(this).index()]);// 拿到城市对象的品牌各类// console.log(hotData[$(this).index()].brands);// 遍历品牌数组var subHTML = "" // 声明一个拼接字符串变量,初始值为空$.each(hotData[$(this).index()].brands, function(index, item) {// 得到每一个城市的品牌对象// console.log(item);// 模板字符串形式连接字符串subHTML += `<li><span>${item.name}</span><span> ${item.num}<s class=${item.flag ? "icon-up":"icon-down"}></s></span></li>`;});// 把生成的小li 字符串给sub 的dom盒子$(".sub").html(subHTML);});
第四步:默认激活第一个tab
// 所有的LIvar $lis = $('.province .sup li')// 第一个默认激活$lis.eq(0).mouseenter()
第五步:开启定时切换
定时器里面 mouseenter 冲突问题的解决方案
定时器里面不加mousenter 事件,而是直接重新渲染数据就可以(执行鼠标经过事件里面的代码)
var lis = $(".province .sup li");lis.eq(0).mouseenter();// 开启定时器var index = 0;var timer = setInterval(function() {index++;if (index >= 5) index = 0;lis.eq(index).mouseenter();}, 1000);
这里的
lis.eq(index).mouseenter()
;替换为以下代码
// lis.eq(index).mouseenter(); 用下面的代码替换
lis.eq(index).addClass('active').siblings().removeClass();var subHTML = "" // 声明一个拼接字符串变量,初始值为空$.each(hotData[index].brands, function(index, item) {subHTML += `<li><span>${item.name}</span><span> ${item.num}<s class=${item.flag ? "icon-up":"icon-down"}></s></span></li>`;});$(".sub").html(subHTML);
把渲染的代码封装为自定义函数render
// 声明一个自定义函数:设置当前sup当前小li高亮、对应的品牌对象渲染function render(that) {that.addClass('active').siblings().removeClass();var subHTML = "" // 声明一个拼接字符串变量,初始值为空$.each(hotData[that.index()].brands, function(index, item) {// 得到每一个城市的品牌对象// console.log(item);// 模板字符串形式连接字符串subHTML += `<li><span>${item.name}</span><span> ${item.num}<s class=${item.flag ? "icon-up":"icon-down"}></s></span></li>`;});// 把生成的小li 字符串给sub 的dom盒子$(".sub").html(subHTML);}
至此,热销排行榜完成,完整JavaScript代码如下
// 全国热榜模块
(function() {// 准备相关数据var hotData = [{city: '北京', // 城市sales: '25, 179', // 销售额flag: true, // 上升还是下降brands: [ // 品牌种类数据{ name: '可爱多', num: '9,086', flag: true },{ name: '娃哈哈', num: '8,341', flag: true },{ name: '喜之郎', num: '7,407', flag: false },{ name: '八喜', num: '6,080', flag: false },{ name: '小洋人', num: '6,724', flag: false },{ name: '好多鱼', num: '2,170', flag: true },]},{city: '河北',sales: '23,252',flag: false,brands: [{ name: '可爱多', num: '3,457', flag: false },{ name: '娃哈哈', num: '2,124', flag: true },{ name: '喜之郎', num: '8,907', flag: false },{ name: '八喜', num: '6,080', flag: true },{ name: '小洋人', num: '1,724', flag: false },{ name: '好多鱼', num: '1,170', flag: false },]},{city: '上海',sales: '20,760',flag: true,brands: [{ name: '可爱多', num: '2,345', flag: true },{ name: '娃哈哈', num: '7,109', flag: true },{ name: '喜之郎', num: '3,701', flag: false },{ name: '八喜', num: '6,080', flag: false },{ name: '小洋人', num: '2,724', flag: false },{ name: '好多鱼', num: '2,998', flag: true },]},{city: '江苏',sales: '23,252',flag: false,brands: [{ name: '可爱多', num: '2,156', flag: false },{ name: '娃哈哈', num: '2,456', flag: true },{ name: '喜之郎', num: '9,737', flag: true },{ name: '八喜', num: '2,080', flag: true },{ name: '小洋人', num: '8,724', flag: true },{ name: '好多鱼', num: '1,770', flag: false },]},{city: '山东',sales: '20,760',flag: true,brands: [{ name: '可爱多', num: '9,567', flag: true },{ name: '娃哈哈', num: '2,345', flag: false },{ name: '喜之郎', num: '9,037', flag: false },{ name: '八喜', num: '1,080', flag: true },{ name: '小洋人', num: '4,724', flag: false },{ name: '好多鱼', num: '9,999', flag: true },]}]// 2、根据数据渲染各省热销sub模块内容// (1)、用$.each()方法遍历hotData对象var supHTML = "" // 声明一个拼接字符串变量,初始值为空$.each(hotData, function(index, item) { // item 得到每个对象supHTML += `<li><span>${item.city}</span><span>${item.sales}<s class=${item.flag? "icon-up":"icon-down"}></s></span></li>`;$(".sup").html(supHTML);});// 3、鼠标经过`.tab`时,当前小`li`高亮显示$('.province .sup').on('mouseenter', 'li', function() {index = $(this).index();render($(this));});// 声明一个自定义函数:设置当前sup当前小li高亮、对应的品牌对象渲染function render(that) {that.addClass('active').siblings().removeClass();var subHTML = "" // 声明一个拼接字符串变量,初始值为空$.each(hotData[that.index()].brands, function(index, item) {// 得到每一个城市的品牌对象// console.log(item);// 模板字符串形式连接字符串subHTML += `<li><span>${item.name}</span><span> ${item.num}<s class=${item.flag ? "icon-up":"icon-down"}></s></span></li>`;});// 把生成的小li 字符串给sub 的dom盒子$(".sub").html(subHTML);}// 4、默认把第1个小li处于鼠标经过状态var lis = $(".province .sup li");lis.eq(0).mouseenter();// 开启定时器var index = 0;var timer = setInterval(function() {index++;if (index >= 5) index = 0;// lis.eq(index).mouseenter();render(lis.eq(index));}, 1000);$(".province .sup").hover(function() {clearInterval(timer);}, function() {clearInterval(timer);timer = setInterval(function() {index++;if (index >= 5) index = 0;// lis.eq(index).mouseenter();render(lis.eq(index));}, 1000);});
})();
已完成的效果如下:
第一章:学习笔记之数据可视化(一)——项目适配方案
上一章:学习笔记之数据可视化(二)——页面布局(中)
学习笔记之数据可视化(二)—— 页面布局(下)相关推荐
- 学习笔记之数据可视化(二)——页面布局(中)
续上一章 2.6 监控区域布局 2.6.1 布局结构解析: 2.6.2 样式描述: 2.6.3 HTML结构及CSS样式代码 2.6.3 ### 监控区域-效果 2.6.7 点位区域(point) 2 ...
- 学习笔记之数据可视化(二)——页面布局(上)
~续上一章 2. 项目页面布局 2.1 基础布局 2.1.1 PC端屏幕宽度适配设置 2.1.2 主体容器viewport背景图片 2.1.3 HTML结构 2.1.4 css样式代码 2.2 边框图 ...
- 学习笔记之数据可视化(一)——项目适配方案
目录 最终效果展示 1. 数据可视化适配方案 1.1 项目需求 1.2 PC端适配方案 1.3 使用到的技术 2. 数据可视化项目开发 项目准备 1.1 文件准备 1.2 引入js和css文件 1.3 ...
- Slicer学习笔记(六十二)slicer下导出模块接口
Slicer学习笔记(六十二)slicer下导出模块接口 1. 参考文件实现 1. 参考文件实现 通过配置config_file为每一个生成类添加 Export,并为每个Module生成 Export ...
- Python学习笔记:数据可视化(一)
python相关 基础概念 数据:离散的,客观事实的数字表示 信息:处理后的数据,为实际问题提供答案 - 为数据提供一种关系或一个关联后,数据就成了信息,这种关联通过提供数据背景来完成 知识: 是数据 ...
- OpenCV学习笔记(四十一)——再看基础数据结构core OpenCV学习笔记(四十二)——Mat数据操作之普通青年、文艺青年、暴力青年 OpenCV学习笔记(四十三)——存取像素值操作汇总co
OpenCV学习笔记(四十一)--再看基础数据结构core 记得我在OpenCV学习笔记(四)--新版本的数据结构core里面讲过新版本的数据结构了,可是我再看这部分的时候,我发现我当时实在是看得太马 ...
- OpenCV学习笔记(五十一)——imge stitching图像拼接stitching OpenCV学习笔记(五十二)——号外:OpenCV 2.4.1 又出来了。。。。。 OpenCV学习笔记(五
OpenCV学习笔记(五十一)--imge stitching图像拼接stitching stitching是OpenCV2.4.0一个新模块,功能是实现图像拼接,所有的相关函数都被封装在Stitch ...
- OpenCV学习笔记(三十一)——让demo在他人电脑跑起来 OpenCV学习笔记(三十二)——制作静态库的demo,没有dll也能hold住 OpenCV学习笔记(三十三)——用haar特征训练自己
OpenCV学习笔记(三十一)--让demo在他人电脑跑起来 这一节的内容感觉比较土鳖.这从来就是一个老生常谈的问题.学MFC的时候就知道这个事情了,那时候记得老师强调多次,如果写的demo想在人家那 ...
- 【AI白身境】深度学习中的数据可视化
文章首发于微信公众号<有三AI> [AI白身境]深度学习中的数据可视化 今天是新专栏<AI白身境>的第八篇,所谓白身,就是什么都不会,还没有进入角色. 上一节我们已经讲述了如何 ...
最新文章
- 用c语言 编写桌面应用程序,谁能帮我用C语言编写“动态桌面啊”!!!急呀!!!...
- 题目1170:找最小数
- on java8学习笔记2022.2.19-2022.2.20
- C语言指针:从底层原理到花式技巧,用图文和代码帮你讲解透彻
- 文本预处理跑得慢?抱抱脸团队又放福利,1GB文本语料分词只需20s!
- Bailian4040 买书问题【Ad Hoc】
- java access数据库连接_Java Access数据库连接
- 最近在写一个IE9的插件
- 基于pytorch的GAN网络搭建
- 用苹果手机做c语言作业,c for ios好用吗,就是苹果手机上的一个C语言编程APP
- 漫威电影宇宙观影指南,口碑票房最佳都是谁
- windows PE结构解析
- 全国大学生数学建模竞赛、美赛研究生数学建模优秀论文分享
- 树莓派3b no wireless interfaces found 的解决办法 360wifi和树莓派结合
- 如何对互联网上产生的舆情传播动态进行分析的方法
- 西瓜视频解析原理及源码,使用CRC32的签名算法,获得视频源地址
- 【EE308FZ Lab2-1】Android App for Bobing (Prototype)
- [1609.04802] SRGAN中的那些loss
- 持续交付之三——持续集成
- 外汇平台哪个比较好 2017年排行总结 Flyerinternational稳居前五
热门文章
- php html转换数组,将html标签转换为php数组
- sparksql一些指标
- Unity3d(UE4)动态加载osgb倾斜摄影数据
- Behavior Designer
- Impala-shell 查询异常 - ERROR: AnalysisException: Failed to evaluate expr: 1
- SSD( Single Shot MultiBox Detector)关键源码解析
- 深度解析PolarDB数据库并行查询技术
- Spring boot 2.3优雅下线,距离生产还有多远?
- 云原生时代业务架构的变革:从单体迈向Serverless
- Flink 新场景:OLAP 引擎性能优化及应用案例