亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JavaScript獲取echart曲線上任意點位的值詳解

 更新時間:2022年09月30日 10:04:53   作者:石云升  
這篇文章主要為大家介紹了JavaScript獲取echart曲線上任意點位的值詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

需求背景

智慧農(nóng)業(yè)里有一個很重要的功能是控制溫室生長環(huán)境,讓農(nóng)作物生長的更好。于是,我們需要在曲線上根據(jù)不同農(nóng)作物設(shè)置不同的環(huán)境數(shù)據(jù)。為了方便用戶修改這些數(shù)據(jù),我們需要支持用戶在曲線上進行拖拽,并且拖拽后還需要把拖拽后的關(guān)鍵點位返回給后端。后面溫度傳感器收到溫度數(shù)據(jù)后,會發(fā)給后端和前端。兩端都需要判斷傳過來的溫度是否在曲線之間。如果超出或者下沉需要觸發(fā)相應(yīng)的事件。

需求調(diào)研

本來以為這個需求很簡單,導(dǎo)入echarts,設(shè)置兩條曲線,并支持拖動。拖動。這些都屬于echarts開放的功能,但等到要查詢某個時間點曲線上的值時,才發(fā)現(xiàn)echarts根本就沒開放這個功能,查看源碼發(fā)現(xiàn)他是用貝塞爾算法生成的曲線,好吧,既然你不支持,那就只能自己實現(xiàn)了。

后面找了下資料,發(fā)現(xiàn)一個貝塞爾的js開源庫,看了下它的說明,發(fā)現(xiàn)有g(shù)et(t)方法獲取到曲線上Y軸的值。參數(shù)t表示兩個關(guān)鍵點之間x軸值。由于我們傳入的x軸是時間,所以這個t就是x軸的時間。

所以,理論上,如果兩個使用的算法是一致的,那么從曲線上獲得的值就應(yīng)該是一樣的。

實現(xiàn)步驟

第一步,安裝bezier-js

npm install bezier-js

第二步,初始化貝塞爾對象

constructor(input = {points: [20, 30, 40], ts: [0, 60000 * 60 * 24]}) {
    this.line = null
    this.keyPoints = []//根據(jù)輸入input,生成關(guān)鍵的點坐標(biāo)數(shù)組    [   x1坐標(biāo),y1坐標(biāo),  x2坐標(biāo),y2坐標(biāo)     ]
    this.tsStart = 0
    this.tsEnd = 0
    this.init(input)
    this.input = input
}
init(input) {
    try {
        if (![input].$has('ts')) input.ts = [0, 60000 * 60 * 24]//如果沒有ts時間,默認(rèn)賦值為1天的時間周期
        if (![input].$has('points', 'ts') || input.points.length < 2 || input.ts.length !== 2) {
            console.log('【bezier】錯誤!實例化曲線時參數(shù)錯誤')
            return//最小2個點
        }
        this.tsStart = Number(input.ts[0])
        this.tsEnd = Number(input.ts[1])
        let tsLen = this.tsEnd - this.tsStart
        if (tsLen < 0) {
            console.log('【bezier】錯誤!實例化曲線時參數(shù)錯誤,時間長度錯誤')
            return
        }
        let stepLen = tsLen / (input.points.length - 1)
        let points = []
        let x = input.ts[0]
        input.points.forEach(y => {
            points.push({x: x})
            points.push({y: y})
            x += stepLen
        })
        points.splice(points.length - 2, 2)//刪除最后一組坐標(biāo)(2個元素)
        points.push({x: input.ts[1]})//再用input的值填充,避免因為平均值導(dǎo)致精度的問題
        points.push({y: input.points[input.points.length - 1]})
        this.keyPoints = points
        this.line = new Bezier(points)  // points =  [   x1坐標(biāo),y1坐標(biāo),  x2坐標(biāo),y2坐標(biāo)     ]
        console.log('生成貝塞爾曲線的數(shù)據(jù)', this.line, points)
    } catch (e) {
        console.log('【bezier】錯誤!在實例化對象時錯誤', e)
    }
}

第三步,我們曲線上看到的是時間是“時+分”格式,傳入的要轉(zhuǎn)化為時間戳

// 獲取指定時間戳的y值數(shù)據(jù)
// ts橫坐標(biāo),時間戳
// 輸出 {x,y} ,x就是 ts
get(ts = 0) {
    let duration
    if (ts <= this.tsStart) {
        duration = 0
    } else if (ts <= this.tsEnd) {
        duration = ts - this.tsStart
    } else {
        duration = this.tsEnd - this.tsStart
    }
    let b = duration / (this.tsEnd - this.tsStart)
    return this.line.get(b) // b取值0~1,小數(shù).0表示曲線第一個點,1表示最后1個點
}

第四步,服務(wù)端給我們的關(guān)鍵點位可能有幾十個,如果我通過幾十個點生成貝塞爾對象,在通過get值去查詢時候,由于它內(nèi)部的算法,除了收尾兩個關(guān)鍵點外,其他關(guān)鍵點位根據(jù)時間查詢出的Y值會有偏差。這跟我們在echarts曲線上看到的值并不一樣。我猜原因在于echarts的平滑曲線并不是由首尾兩個點生成的,而是由兩個兩個關(guān)鍵點生成一段一段平滑曲線組合而成的。

為了驗證我的猜想,我寫了個demo,通過6個關(guān)鍵點在echarts上生成了二條曲線。同時,我通過bezier-js的get(t)方法獲取更多點位,然后放到echars上,看兩者的曲線是否重合。

事實證明,我的猜想是對的。兩者曲線是重合的。

echarts 根據(jù)六個點生成的曲線

下圖是根據(jù)兩個關(guān)鍵點之間計算多個節(jié)點組合成的曲線

所以,我們在計算某個時間軸的Y軸時,要先判斷查詢的X軸時間屬于哪兩個點之間,然后再用get(t)方法查Y值

/**
 * 查詢曲線上某個時間點曲線上具體的值,這里查詢的是上限。
 */
getPointValueByTime() {
    // 把時間轉(zhuǎn)換成毫秒
    let time = this.timeToSec(this.defaultTime)
    // 判斷這個時間在哪兩個關(guān)鍵點之間
    // 先獲取曲線上所有時間點的數(shù)組
    let preData = []
    for (var i = 0; i < upperLimit.length; i++) {
        let itemTime = this.timeToSec(upperLimit[i][0])
        // 如果查詢的時間小于當(dāng)前的item,這表示在這個item和上一個item之間。則通過這兩個item生成貝塞爾對象,然后用get方法查詢time值
        if (time <= itemTime && i != 0) {
            // 查詢的點就是preData 和item的數(shù)組
            let pointArray = []
            pointArray.push(preData[1])
            pointArray.push(upperLimit[i][1])
            const bezier = new BezierLine({points: pointArray, ts: [preData[0], itemTime]})
            let data = bezier.get(time)
            console.log('查詢到當(dāng)前時間' + time + '的值為', data)
            this.searchValueByTime = parseFloat(data.y).toFixed(2)
            break
        } else {
            // 上一個不符合的對象
            preData = [itemTime, upperLimit[i][1]]
        }
    }
},

到此,我們就可以通過任意一個X軸時間來獲得對應(yīng)的Y軸value值了。當(dāng)然,文章里只是把實現(xiàn)思路講了,貼出來的代碼不是全部,只是供大家理解。完整版代碼我已經(jīng)上傳到碼云,如果有什么bug,大家可以留言告知一下。 下載地址:GetEchartsCurveData

以上就是JavaScript獲取echart曲線上任意點位的值詳解的詳細內(nèi)容,更多關(guān)于JavaScript echart曲線任意點位值的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vue解決跨域問題(推薦)

    vue解決跨域問題(推薦)

    這篇文章主要介紹了vue解決跨域問題,本文通過實例圖文相結(jié)合給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • vue中v-model的應(yīng)用及使用詳解

    vue中v-model的應(yīng)用及使用詳解

    v-model用于表單數(shù)據(jù)的雙向綁定,其實它就是一個語法糖。這篇文章主要介紹了vue中v-model的應(yīng)用,需要的朋友可以參考下
    2018-06-06
  • 基于vue的換膚功能的示例代碼

    基于vue的換膚功能的示例代碼

    本篇文章主要介紹了基于vue的換膚功能的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • vue-pdf打包后無法預(yù)覽問題及修復(fù)方式

    vue-pdf打包后無法預(yù)覽問題及修復(fù)方式

    這篇文章主要介紹了vue-pdf打包后無法預(yù)覽問題及修復(fù)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • vue loadmore 組件滑動加載更多源碼解析

    vue loadmore 組件滑動加載更多源碼解析

    這篇文章主要介紹了vue loadmore 組件滑動加載更多源碼解析,需要的朋友可以參考下
    2017-07-07
  • vue使用pinia實現(xiàn)全局無縫通信

    vue使用pinia實現(xiàn)全局無縫通信

    這篇文章主要為大家詳細介紹了vue如何使用pinia實現(xiàn)全局無縫通信,文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以參考一下
    2023-11-11
  • vue.js中methods watch和computed的區(qū)別示例詳解

    vue.js中methods watch和computed的區(qū)別示例詳解

    methods,watch和computed都是以函數(shù)為基礎(chǔ)的,但各自卻都不同,這篇文章主要給大家介紹了關(guān)于vue.js中methods watch和computed區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • Vue路由history模式解決404問題的幾種方法

    Vue路由history模式解決404問題的幾種方法

    這篇文章主要介紹了Vue路由history模式解決404問題的幾種方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • 淺談Vue.js中的v-on(事件處理)

    淺談Vue.js中的v-on(事件處理)

    本篇文章主要介紹了Vue.js中的v-on(事件處理),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • 使用vant-picker實現(xiàn)自定義內(nèi)容,根據(jù)內(nèi)容添加圖標(biāo)

    使用vant-picker實現(xiàn)自定義內(nèi)容,根據(jù)內(nèi)容添加圖標(biāo)

    這篇文章主要介紹了使用vant-picker實現(xiàn)自定義內(nèi)容,根據(jù)內(nèi)容添加圖標(biāo),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12

最新評論