前言: 我正式接触web前端时间很短,前先后后差很少3个月左右的时间。我是16年从事android开发的,在android里也常常会玩一下自定义控件。针对于以前移动端的折线图,我在利用了空闲时间,用vue也写了一个组件chart-view前端
代码不是很长,在代码里注释的很是详细,若有不懂,欢迎留言。vue
<template>
<div >
<canvas ref="canvas" width="500" height="500" ></canvas>
</div>
</template>
<script>
export default {
//部件
components: {},
//静态
//这里至关于自定义了3个属性
//lineCenterX: X轴在画布上Y方向的坐标点(这样设计的功能是由于公司业务,看明白了能够把他改掉)
//textFont: 文字大小
//value_50: 50μv在画布上的长度
props: ['lineCenterX', 'textFont','value_50'],
//对象内部的属性监听,也叫深度监听
watch: {
},
//属性的结果会被缓存,除非依赖的响应式属性变化才会从新计算。主要看成属性来使用;
computed: {},
//方法表示一个具体的操做,主要书写业务逻辑;
methods: {
initDataSon(valueList) {
//将画布设置满屏
this.$refs.canvas.width = window.innerWidth
this.$refs.canvas.height = window.innerHeight
var ctx = this.$refs.canvas.getContext('2d')
//当前控件的总长宽
var total_W = this.$refs.canvas.offsetWidth // 返回元素的总宽度
var total_H = this.$refs.canvas.offsetHeight // 返回元素的总高度
ctx.font = 'normal ' + this.textFont + 'px Verdana'
ctx.fillStyle = '#000000'
//在画布上肯定好+-50μv坐标,并渲染到画布上
ctx.fillText('-50μv', 14, this.lineCenterX + this.value_50)
ctx.fillText('+50μv', 14, this.lineCenterX - this.value_50 + this.textFont)
//横坐标 (先用红线画出X轴)
ctx.moveTo(0, this.lineCenterX)
ctx.lineTo(total_W, this.lineCenterX)
ctx.strokeStyle = '#ff0000'
ctx.lineWidth = 0.3
ctx.stroke()
//纵坐标
// ctx.moveTo(0, 0)
// ctx.lineTo(0, total_H)
//画笔改为黑色,准备画折线图
ctx.beginPath()
ctx.strokeStyle = '#000000'
ctx.lineWidth = 0.6
//填充数据是不断须要更新数据且须要渲染界面,因此这里用到了nextTick方法
this.$nextTick(() => {
//每段x轴每一个刻度值之间的距离(其实这里的ever_x,是根据你当前坐标轴要展现多长时间的数据算的,好比总共波长是200s,你当前
//只想展现10s,因此真的项目确定是肯定的,最好是把valueList.length也当成一个属性去传递,是个固定值)
var ever_x = total_W / (valueList.length - 1)
for (const key in valueList) {
//将数据放大1000倍(这里彻底是根据咱们项目走的,能够忽略这点)
let itemValue = valueList[key] * 1000
//知道了每一个x轴坐标点,那么再计算出每一个y轴的坐标点
let trueItemValue = itemValue/50*this.value_50 if (key === 0) {
//单独处理下x=0的点
ctx.moveTo(0, this.lineCenterX - trueItemValue)
} else {
//链接以后的全部点
ctx.lineTo(ever_x * key, this.lineCenterX - trueItemValue)
}
}
ctx.stroke()
})
},
},
//请求数据
created() {},
mounted() {},
}
</script>
<style scoped>
</style>
复制代码
<template>
<div>
<button class="buttonStyle" @click="test">{{ buttonText }}</button>
<div class="fatherCss" ref="fatherCss">
<canvas-item
:lineCenterX="50"
:value_50="50"
:textFont="14"
ref="mychild"
></canvas-item>
</div>
</div>
</template>
<script>
import ChartView from '@/components/ChartView.vue'
import axios from 'axios'
export default {
data() {
return {
//开始时间
start: 0,
//满屏展现的波,所占的时间
showTotalTime: 20,
//整个数据源的波长时间
dataTotalTime: 210,
//波的总数据源list
list: [],
//如下用于处理按钮点击
isScroll: false,
buttonText: '点击开始',
timer: null,
}
},
//部件
components: {
'canvas-item': ChartView,
},
//静态
props: {},
//对象内部的属性监听,也叫深度监听
watch: {},
//属性的结果会被缓存,除非依赖的响应式属性变化才会从新计算。主要看成属性来使用;
computed: {},
//方法表示一个具体的操做,主要书写业务逻辑;
methods: {
initData() {
//若是开始时间不得大于总时间
if (this.start >= this.dataTotalTime) {
return
}
//若是当前展现波的末尾时间大于总时间,那么末尾时间就等于总时间
var lastTime = this.start + this.showTotalTime if (lastTime >= this.dataTotalTime) {
lastTime = this.dataTotalTime
}
var dataList = []
//用开始时间和总时间算出数据源起始index,取整
let start = Math.floor(
(this.list.length * this.start) / this.dataTotalTime
)
//同理算出末尾index
let end = Math.floor((this.list.length * lastTime) / this.dataTotalTime)
//从总数据获取当前所展现的数据
dataList = Object.assign([], dataList, this.list.slice(start, end))
this.$refs.mychild.initDataSon(dataList)
//起始时间每次+20ms,由于下面开启了间隔20ms运行一次,模拟波的运动
this.start += 0.02
},
test() {
if (this.isScroll) {
//表明是滚动时候
this.isScroll = false
this.buttonText = '点击开始'
clearInterval(this.timer)
} else {
//未滚动时候
this.isScroll = true
this.buttonText = '点击暂停'
this.initData()
this.timer = setInterval(() => {
this.initData() //自定义函数
}, 20)
}
},
},
//请求数据
created() {
axios.get('/js/data.json').then(
(response) => {
this.list = Object.assign([], this.list, response.data.list)
this.initData()
},
(response) => {
console.log('error')
}
)
},
mounted() {},
beforeDestroy(){
//生命周期销毁时,清楚定时器timer
clearInterval(this.timer)
this.timer = null
}
}
</script>
<style scoped>
.buttonStyle {
display: block;
}
.fatherCss {
position: absolute;
}
</style>
复制代码
chart-viewjava