内容简介:要用到柱状图,第一时间想到去echart看看示例扒一套代码下来。看了官方教程后感觉不太适合本项目,考虑后觉得自己动手写个图标比较省事而且不用引包。那就开始吧!滚动图表首先得有一些柱子呀,那我们就来早柱子,这些都是个宽度相等,高度给父级设置flex,设置交叉轴的对其方式为flex-end就可以把柱子都立起来了。但是可以看到日期和柱子是同时滚动的,它们应该同级的标签。
要用到柱状图,第一时间想到去echart看看示例扒一套代码下来。看了官方教程后感觉不太适合本项目,考虑后觉得自己动手写个图标比较省事而且不用引包。那就开始吧!
柱状图
滚动图表首先得有一些柱子呀,那我们就来早柱子,这些都是个宽度相等,高度 按比例*设定好的最高高度
的柱子。通过flex布局就可以实现这些。
<div class="move__wrap"> <div class="move__item" v-for="member in list" :key="member.id"></div> </div> // style <style lang='scss' scoped> .move { &__wrap { display: flex; align-items: flex-end; height: 100%; } } </style> 复制代码
给父级设置flex,设置交叉轴的对其方式为flex-end就可以把柱子都立起来了。但是可以看到日期和柱子是同时滚动的,它们应该同级的标签。
<div class="move__wrap"> <div class="move__item" v-for="member in list" :key="member.id"> // 柱子 <div class="child__chart"></div> // 日期 <div></div> </div> </div> // style <style lang='scss' scoped> .move { &__wrap { display: flex; align-items: flex-end; height: 100%; } &__item{ display: flex; flex-wrap: wrap; width: 38px; } } </style> 复制代码
设置两个弹性盒子之后柱状图和日期都已经出来了。需要注意的一点是每个柱状图之间是有间隙的,但是日期是没有间隙的。 我们不能直接给move__item设置左外边距,将 child__chart设置宽度为37并且设置margin-left:1就有了如下图表
这里还需要定一个图标的最高的高度。比如想定最高的高度为180,我这里的做法是找出list中最大的一个值,其他项以它为标准做百分百比运算。
// @param {Array} list 数组项为数字即步数 <div class="move__item" v-for="member in list" :key="member.id"> <div class="child__chart" :style="{height:member/maxStep*180+'px'}"></div> </div> // js computed:{ // 找出最大值参考 maxStep() { let max = 0 this.seriesDataList.forEach(number => { max = number > max ? number : max }) return max }, } 复制代码
动起来
到此柱状图我们已经完成了,现在的目标就是让这个图表滑动起来。 这里我们需要了解一些css属性。
overflow-x : 当一个块级元素的内容在水平方向发生溢出时,应该截断溢出内容,或者显示滚动条,或者直接显示溢出内容。 visible | hidden | clip | scroll | auto 。
overflow-y : 同上。
-webkit-scrollbar : CSS伪类选择器影响了一个元素的滚动条的样式 可以设置css属性,这里使用none值隐藏滚动条
以上属性设置了是否滚动及滚动条的样式,我们还需要知道形成滚动的条件。
- 有父子两个元素
- 子元素的高/宽 > 父元素的高/宽
你也可以点击这里查看更多
光有滚动还不行,我们还需要监听滚动到哪里了获取到信息。用到了target.addEventListener(type, listener[, options])
EventTarget.addEventListener() 方法 : 将指定的监听器注册到 EventTarget 上,当该对象触发指定的事件时,指定的回调函数就会被执行。
- type 表示监听事件类型的字符串这里我们用到的是scroll
- listener 需要执行的函数,考虑到之后要根据条件去removeEventListener移除事件监听,我们可以在data函数中定义一个有名的listener
- options 表示是在冒泡阶段或者捕获阶段会触发listener,默认为false即在冒泡阶段触发。
- eventTarget 事件目标可以是一个文档上的元素我们在
mounted钩子中
通过ref获取到我们目标值上,需要注意的滚动监听事件要绑定在滚动元素父级的DOM
data(){ return { scrollListenHandle: () => { console.log(this.$refs.scroll.scrollLeft) this.scrollLength = this.$refs.scroll.scrollLeft } } }, mounted() { this.$refs.scroll.addEventListener('scroll', this.scrollListenHandle) } 复制代码
现在我们已经设置好x轴方向的滚动效果和了滚动事件来看看效果吧
高亮
我们已经将图表滚起来了,我们需要将当前选中的日期高亮起来。这里涉及到一个参考,默认让图标可视区域的中心点的柱子高亮。
怎么拿到这个中心点呢?假设我们一页可以显示九根柱子,每根柱子的宽度是38px,当我们向右移动38px时,则第六根柱子会亮起来。计算公式可以是`(移动的距离+半个屏幕宽度)/38`就是当前移动时需要高亮的柱子的序号
data(){ // 滚动时不断更新scrollLength滚动距离 scrollListenHandle: () => { this.scrollLength = this.$refs.scroll.scrollLeft }, }, mounted() { // 获取当前屏幕的宽度 this.screenWidth = screen.width }, computed:{ // 获取到当前高亮的目标值的序号 selectIndex() { return parseInt( (this.scrollLength + this.screenWidth / 2) / singleWidth ) }, } 复制代码
通过滚动事件将滚动的距离更新,通过计算属性得到当前选中柱子的序号,有了这个序号我们可以通过vue的动态绑定class设定高亮的样式。html代码如下:
<div ref="scroll" class="chart__move" @touchmove="onTouchMove"> <div ref="child" class="move__child" :style="{width:AllLength + 'px'}"> <div v-for="(item,index) in chartList" :key="index" class="child__wrap"> <div class="child__chart" :class="{'child__chart--white':selectIndex === index}" :style="{height:item/maxStep*180+'px'}"></div> <div class="child__date" :class="{'child__date--blue':selectIndex === index}">{{dateList[index]}}</div> </div> </div> </div> 复制代码按照我们的做法高亮的柱子
范围限定在 this.screenWidth / 2 ~ 总长度 - this.screenWidth / 2
在除了这个返回之外的柱子我们只能通过点击让它高亮,
毕竟已经到头了或者到尾了没办法移动了
。这里又涉及到一个问题,当我们点击柱子时,如果还在
范围限定在 this.screenWidth / 2 ~ 总长度 - this.screenWidth / 2
中的柱子,当我们点击它时,应该将它移动到中间的位置上来。
这里我们需要通过this.$refs.scroll.scrollLeft赋值来达到效果
。
页面一共九根柱子时,点击第6根柱子时,将序号传给 onSelectDateClick事件,我们要做的两件事,让第6根柱子亮起来。这很简单,使用:class动态绑定即可。还需要做的是将滚动元素的scrollLeft值增加38px(一个柱子的宽度)。这样做效果是达到了,但是我们需要点击的时候需要有一个过渡的效果,也就是慢慢移过去。可以设置一个过渡时间。好的下面就开始干吧!
// 定义数字的含义避免魔法数 而且方便统一修改 const singleWidth = 38 // 单个柱子的宽度 const duration = 100 // 过渡时间 export default { methods:{ onSelectDateClick(index) { // 获取到高亮的index this.clickIndex = index // 目标的scroolLeft const targetLeft = index * singleWidth - this.screenWidth / 2 // 当前的scrollLeft this.currentLeft = this.$refs.scroll.scrollLeft // 每秒的速度 this.speed = (targetLeft - this.currentLeft) / duration // 记下开始的时间 this.startTime = new Date() // 开始过渡函数 this.update() }, update() { // 定时更新 this.$refs.scroll.scrollLeft this.rAF = setInterval(() => { const time = new Date() - this.startTime this.$refs.scroll.scrollLeft = time * this.speed + this.currentLeft // 如果时间超过我们预定的过渡时间就停止更新 if (time > duration) { clearInterval(this.rAF) } }) }, } } 复制代码
为了避免干扰html 动态绑定class设置为
:class="{'child__chart--white':clickIndex===index}" 复制代码
来看下效果
看起来不错,我们继续把selectIndex加上,现在类名高亮受两个index决定
:class="{'child__chart--white':selectIndex === index||clickIndex===index}" 复制代码
当我通过点击改变 scrollLeft的值时会也会触发滚动事件,当selectIndex和clickIndex不同时会出现两个高亮的柱子。我们需要一个值来区分现在是现在是滚动还是点击事件。
// 给滚动区域的父级加一个touchMove事件 onTouchMove() { this.isCenter = true this.clickIndex = -1 } 复制代码
通过touchMove事件通过isCenter来判断是否在滚动,如果在滚动将clickIndex置为-1,这样滚动的时候clickIndex为-1
// 判断isCenter是否在滚动否则返回-1 selectIndex() { if (this.isCenter) { return parseInt( (this.scrollLength + this.screenWidth / 2) / singleWidth ) } else { return -1 } }, 复制代码
经过上面的判断处理,clickIndex和scrollIndex就不会重复,不会出现两条高亮线的问题。
移除滚动事件
当数据列表宽度小于一个屏幕时或卸载页面的时候,我们需要移除监听事件,优化性能。
watch:{ 'chartList.length'(newLength) { if(newLength*singleWidth < this.screenWidth){ this.$refs.scroll.removeEventListener('scroll', this.scrollListenHandle) } } }, destroyed() { this.$refs.scroll.removeEventListener('scroll', this.scrollListenHandle) } 复制代码
小结
使用scroll-x:scroll实现滚动效果,通过this.$refs.scroll.removeEventListener('scroll',this.scrollListenHandle)来监听滚动的距离,通过计算得出高亮的柱子是哪条。通过点击事件改变this.$refs.scroll.scrollLeft的来实现动画的效果。
以上所述就是小编给大家介绍的《炫酷的运动柱状图统计动效》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- CVPR 2019 | 条件运动传播:从运动中学习物体性质
- 敏捷运动发起人马丁·福勒认为当前敏捷运动是一场悲剧
- 运动模糊滤镜
- 原生JavaScript之完美运动框架
- 运动App 自定义LocationMarker
- RMS 称开源运动是非道德的
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Domain-Driven Design Distilled
Vaughn Vernon / Addison-Wesley Professional / 2016-6-2 / USD 36.99
Domain-Driven Design (DDD) software modeling delivers powerful results in practice, not just in theory, which is why developers worldwide are rapidly moving to adopt it. Now, for the first time, there......一起来看看 《Domain-Driven Design Distilled》 这本书的介绍吧!