ECharts實現動態曲線(上)

間接用過ECharts
之所以說“間接”,是因爲內部組件庫實際是將ECharts再封裝一次,然後拿出來給大家使用。然而,經此番“封裝”,這個內部組件庫好像不怎麼友好。

“想要實現XXX功能,有這樣的一個接口麼?”
“呃,目前沒有提供此類接口”

“報告,組件裏有個bug”

不僅功能接口“缺斤少兩”,還得幫忙找bug。苦,但不哭不鬧,習慣就好。

ECharts官網瞧瞧,不論是文檔還是實例,保你滿意。

上手ECharts

方法

  • echarts.init(dom)
    script標籤引入echarts.min.js,即可獲取全局對象echarts。調用該對象的init方法,返回一個echartsInstance,之後我們所有的工作都是圍繞着這個實例。
  • echartsInstance.setOption(option)
    設置初始化|修改 實例的各項參數
echartsInstance.setOption(option1);
echartsInstance.setOption(option2);

option2option1會合並,且option2優先,“有則改,無則加”。

參數

grid組件(網格組件)
  • grid
    • show
      是否顯示網格。true則顯示,false則不顯示。默認爲false
    • borderWidth
      設置網格邊框的寬度。
    • left|right|top|bottom
      grid組件離容器左、右、上、下側的距離

在這裏插入圖片描述
在這裏插入圖片描述

X軸
  • xAxis
    • data
      顯示在軸上的數據
    • axisLabel
      • rotate
        數據的旋轉角度
    • axisTick
      • alignWithLabel
        true時,保證刻度線和數據對齊

在這裏插入圖片描述
在這裏插入圖片描述

Y軸
  • yAxis
    • min
      軸上的最小刻度
    • max
      軸上的最大刻度

在這裏插入圖片描述

tooltip組件(提示框組件)
  • tooltip
    • axisPointer
      座標指示器,用來顯示點的座標值。座標指示器就是一個tooltip組件。
      • type
        指示器類型,有四種,line|shadow|cross|none
    • trigger
      每個軸上都有個座標指示器,且默認不顯示。
      trigger設置爲"axis"可以讓它們顯示出來。而至於顯示哪個軸的座標指示器,座標系會自動選擇。

在這裏插入圖片描述

這次就用ECharts來實現一個動態曲線,嚐個鮮。

效果圖

在這裏插入圖片描述

實現

邏輯挺簡單的。
MyChart.js封裝了數據生成器,其中createTimes用來生成X軸的時間數據,createValues用來生成Y軸的帶寬利用率數據。
一旦點擊“開始”,將啓動一個定時器。每隔1秒,數據生成器會生產出新的的X軸、Y軸數據,隨後這些新數據將被更新在圖表中,從而實現動態曲線。
點擊“結束”,定時器停止,停止生產新數據,圖表也停止刷新。

代碼結構

在這裏插入圖片描述

詳細代碼

//index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>動態曲線</title>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/echarts.min.js"></script>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <div id="myChart"></div>
    <div class="container">
        <div class="buttons">
            <div class="button" id="start">開始</div>
            <div class="button" id="end"> 結束</div>
        </div>
    </div>
<script src="./MyButton.js"></script>
<script src="./MyChart.js"></script>
<script src="./index.js"></script>
</body>
</html>
//index.js
initButtons();
const myChart = new MyChart(document.getElementById("myChart"));
myChart.init();

function initButtons(){
    var timer;
    const startBtn = new MyButton(document.querySelector("#start"));
    startBtn.addEventListener("click",function(){
        timer = startTimer();
        startBtn.disable();
    });
    
    const endBtn = new MyButton(document.querySelector("#end"));
    endBtn.addEventListener("click",function(){
        closeTimer(timer);
        startBtn.enable();
    });
}
function startTimer(){
    return timer = setInterval(function(){
        myChart.update();
    },1000,myChart);
}
function closeTimer(timer){
    clearInterval(timer)
}

//MyChart.js
(function(win){
    function MyChart(elm){
        this.dotNum = 10;
        this.interval = 1000;
        this.lastStartTime = undefined;
        this.lastValues = [];

        this.elm = elm;
        this.chart = echarts.init(elm); 
        this.chart.gap = 40;
    }
    MyChart.prototype.init = function(){
        const times = createTimes(this).map(t => formatTime(t));
        const values = [];
        const gap = this.chart.gap;
        const option = {
            grid:{
                bottom:50,
                top:gap,
                left:gap,
                right:gap
            },
            xAxis: {
                type: 'category',
                data:times,
                axisLabel:{
                    rotate:45
                },
                axisTick: {
                    alignWithLabel: true
                },
                name:"時間"
                
            },
            yAxis: {
                type: 'value',
                min:0,
                max:1,
                name:"帶寬利用率"
            },
            series: [{
                data:values,
                type: 'line',
                smooth: true
            }],
            tooltip: {
                trigger: 'axis',
                axisPointer: {
                    type:'line'
                }
            }
        };
        this.chart.setOption(option);
    }
    MyChart.prototype.update = function(){
        const times = createTimes(this);
        const values = createValues(this);
        const formatedTimes = times.map(t => formatTime(new Date(t)));
        console.log(formatedTimes);
        this.chart.setOption({
            xAxis:{
                data:formatedTimes
            },
            series:[{
                data:values
            }]
        });  
    }

    function createTimes(myChart){
        let {dotNum,interval,lastStartTime} = myChart;
        let startTime = lastStartTime?lastStartTime:new Date().getTime();
        lastStartTime = startTime + interval;

        let times = [];        
        for(var i=0;i<dotNum;++i){
            var time = new Date(startTime+i*interval);
            times.push(time);
        }
        return times;
    } 
    function createValues(myChart){
        let {dotNum,lastValues} = myChart;
        let values;
        if(lastValues.length === 0){
            values = [];
            for(var i=0;i<dotNum;++i){
                var value = parseFloat(Math.random().toFixed(2));
                values.push(value);
            }
        }else {
            values = lastValues.slice(1);
            values.push(parseFloat(Math.random().toFixed(2)));
        }
        myChart.lastValues = values.slice();
        return values;
    }  

    function formatTime(time){
        const hour = time.getHours();
        const min = time.getMinutes();
        const sec = time.getSeconds();
        const h = hour<10 ? "0"+hour : hour;
        const m = min<10  ? "0"+min : min;
        const s = sec<10 ? "0"+sec : sec;
        return h+":"+m+":"+s;
    }

    win.MyChart = MyChart;
}(window))
//MyButton.js
(function(win){
    function MyButton(elm){
        this.elm = elm; 
    }
    MyButton.prototype.addEventListener = function(type,handler){
        if(this.elm.addEventListener){
            this.elm.addEventListener(type,handler,false);
        }else {
            this.elm["on"+type] = handler;
        }
    }
    MyButton.prototype.disable = function(){
        this.elm.classList.add("disabled");
    }
    MyButton.prototype.enable = function(){
        this.elm.classList.remove("disabled");
    }
    win.MyButton = MyButton;
}(window));
//index.css
#myChart{
    display:inline-block;
    width:400px;height:200px;
    border:1px solid lightgray;
    border-right:none;
    vertical-align:middle;
}
.container{
    display:inline-block;
    width:80px;height:200px;
    border:1px solid lightgray;
    border-left:none;
    margin:-5px;
    vertical-align:middle;

}
.buttons{
    display:table-cell;
    width:inherit;height: inherit;
    vertical-align: middle;
}
.button{
    font-size:0.75em;
    padding:.3em;
    background-color:rgba(0,0,255,.5);
    border:1px solid transparent;
    border-radius:.5em;
    box-shadow:1px 1px 1px black;
    text-align:center;
    margin:1em;
}
.button:hover{
    cursor:pointer;
    background-color:rgba(0,0,255,1);
    color:white;
}
.disabled{
    background-color:lightgray;
    color:lavender;
    box-shadow:1px 1px 1px lightslategray;
}
.disabled:hover{
    cursor:not-allowed;
    background-color:lightgray;
    color:lavender;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章