1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        動(dòng)態(tài)刻度可視化組件實(shí)現(xiàn)

        共 3317字,需瀏覽 7分鐘

         ·

        2021-09-30 09:29

        前言

        之前有個(gè)網(wǎng)友問我了一個(gè)很有價(jià)值的問題, 有關(guān)實(shí)現(xiàn)數(shù)據(jù)可視化的問題, 但是這個(gè)可視化問題不是一般的柱狀圖, 折現(xiàn)圖之類的,而是不規(guī)則刻度的數(shù)據(jù)可視化.所以筆者思考了一下決定自己實(shí)現(xiàn)一個(gè)動(dòng)態(tài)刻度可視化組件的方案, 來解決這一類的需求.

        正文

        最初的需求是這樣的:

        我們只需要輸入文字, 數(shù)值比例, 就能生成如上圖所示的刻度圖.但是作為一名有追求的程序員, 需要對(duì)問題抽象化, 形成通用的解決方案,所以我們開始重組需求:

        由上圖我們可以拆解為一下幾個(gè)需求點(diǎn):
        • 支持?jǐn)?shù)值自定義
        • 數(shù)值單位自定義
        • 支持刻度組件寬度自定義
        • 支持刻度線數(shù)量自定義
        • 支持刻度變化幅度自定義
        • 傳入已有進(jìn)度比例,即激活區(qū)范圍
        • 支持刻度樣式自定義
        • 支持?jǐn)?shù)值樣式自定義
        • 支持自定義說明文本以及說明文本自定義
        以上就是筆者挖掘的通用需求,當(dāng)然有其他需求也可以漸進(jìn)的增加.

        確認(rèn)了以上需求之后,我們開始選擇技術(shù)選型, 筆者之前常用的技術(shù)棧是vuereact,所以接下來我們初步確認(rèn)該組件采用如下技術(shù)方案:

        • react + typescript + umi-library

        如果大家擅長使用vue, 也可以, 筆者之前也寫過如何搭建vue組件庫相關(guān)的文章,感興趣可以學(xué)習(xí)了解一下, 其本質(zhì)思想是一致的.

        接下來我們開始實(shí)現(xiàn)動(dòng)態(tài)刻度可視化組件. 如果對(duì)umi不熟悉的,可以參考筆者之前寫的文章從0到1教你搭建前端團(tuán)隊(duì)的組件系統(tǒng)(高級(jí)進(jìn)階必備).

        1. 定義基本屬性類型

        由以上需求分析我們可以定義如下的屬性類型:
        export interface TickerProps {
        width: number;
        maxHeight: number;
        percent: number;
        text: string;
        value: number;
        showValue: boolean;
        unit: string;
        lineNum: number;
        defaultColor: string;
        activeColor: string;
        textStyle: object;
        valueStyle: object;
        }

        復(fù)制代碼

        2. 組件整體結(jié)構(gòu)

        const Ticker: React.FC<TickerProps> = function(props:TickerProps) {
        const {
        width = 100,
        maxHeight = 10,
        percent = 50,
        value,
        text = '瞬時(shí)能見度',
        showValue = true,
        unit = 'M',
        lineNum = 12,
        defaultColor = '#06c',
        activeColor = 'red',
        valueStyle,
        textStyle
        } = props
        return (
        <div className="ticker">
        {
        showValue &&
        <div className="value" style={valueStyle}>
        { value || 0 } <span className="unit">{ unit }</span>
        </div>
        }
        <div className="tickerGraph">
        <div className="tickerLine">

        </div>
        <div className="tickerBar"></div>
        </div>
        {
        !!text && <div className="text">{ text }</div>
        }
        </div>
        );
        };

        export default Ticker;

        復(fù)制代碼

        3. 視圖搭建

        有關(guān)刻度可視化我們完全采用dom實(shí)現(xiàn), 所以這里筆者具體分析一下如何實(shí)現(xiàn)刻度視圖:

        上圖的思路就是用一個(gè)個(gè)dom來組裝成隨機(jī)刻度圖形,所以我們只要利用css實(shí)現(xiàn)這個(gè)形狀, 也就成功了一半.至于激活狀態(tài),我們會(huì)根據(jù)傳入的數(shù)據(jù)量來決定激活范圍,接下來會(huì)介紹如何渲染激活的刻度,也就是上圖的紅色區(qū)域.

        4.特殊功能實(shí)現(xiàn)

        因?yàn)樵摻M件很多功能在搭建結(jié)構(gòu)之后已經(jīng)實(shí)現(xiàn)了, 這里我們唯一關(guān)注的就是cssjs長度計(jì)算的問題, css實(shí)現(xiàn)方案有很多, 這里就不具體介紹了, 筆者這里重點(diǎn)介紹一下如何實(shí)現(xiàn)指定范圍的隨機(jī)高度:

        // 生成指定范圍的隨機(jī)高度
        const random = (min:number, max:number):number => {
        return min + Math.random() * (max - min)
        }

        復(fù)制代碼

        動(dòng)態(tài)刻度條的隨機(jī)高度我們就是利用以上函數(shù)實(shí)現(xiàn)的, 刻度條內(nèi)部實(shí)現(xiàn)如下:

        <div className="tickerLine" style={{borderBottomColor: defaultColor}}>
        {
        new Array(lineNum).fill(0).map((item:number, i: number) => {
        let isActive = (i + 1) <= Math.floor(lineNum * percent / 100)
        return <span
        className="tick"
        style={{
        height: random(3, maxHeight) + 'px', left: (gap + 2) * i + 'px',
        backgroundColor: isActive ? activeColor : defaultColor
        }}>
        </span>
        })
        }
        </div>
        復(fù)制代碼

        gap為刻度之間的間距, 由于計(jì)算刻度的位置需要一點(diǎn)幾何知識(shí), 公式如下:

        W = Lw * lineNum + gap * ( lineNum - 1)
        復(fù)制代碼
        其中W表示刻度總寬度, Lw為刻度線寬度, lineNum為刻度線數(shù)量.

        還有一個(gè)注意點(diǎn)就是激活態(tài), 筆者使用如下函數(shù)來判斷刻度是否具有激活狀態(tài):

        let isActive = (i + 1) <= Math.floor(lineNum * percent / 100)
        復(fù)制代碼

        這塊也非常好理解, 也就是我們傳入的比率乘以線的總數(shù)量,即可求出哪些刻度線是需要激活的.

        以上細(xì)節(jié)實(shí)現(xiàn)完成之后,我們就可以來實(shí)現(xiàn)有點(diǎn)意思的刻度可視化方案啦, 如下展示的demo:


          1. 可見度測量


          1. 正態(tài)分布模型


          1. 標(biāo)尺


          1. 光柵


          1. 自定義文本樣式

        github地址

        https://github.com/MrXujiang/ticker

        最后

        如果想學(xué)習(xí)更多H5游戲webpacknode,gulp,css3,javascriptnodeJS,canvas數(shù)據(jù)可視化等前端知識(shí)和實(shí)戰(zhàn),歡迎在公號(hào)《趣談前端》加入我們的技術(shù)群一起學(xué)習(xí)討論,共同探索前端的邊界。

        瀏覽 38
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            免费看欧美成人A片无码 | 成 人 黄 色 免费 观 看下载 | 极品操逼网站 | 成人亚洲AV无码专区在线电影 | 韩国大尺度情事 | 亚洲国产女同久久 | 色色亚洲天堂 | 淫色淫香视频 | 一本一道A片无码视频下载 | xxxxx网 |