前言: 我正式接觸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