echarts設定多條折線不是你想的那樣簡單

南風晚來晚相識發表於2023-12-14

簡單的多條折線圖

小夥伴寫過多條折線圖的都知道,
常見的折線圖是  xAxis 配置項下的 data屬性上設定時間或者日期。
series配置項下是對應的 legend中的資料以及該條折線的資料。
<!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.staticfile.org/echarts/4.3.0/echarts.min.js"></script>
</head>

<body>
  <div style="width: 900px;height: 400px;"></div>
</body>
<script>
  let myChart = echarts.init(document.querySelector('div'))
  // 設定X軸的時間
  let dataXTime = [
    '2023-12-04 09:45:07', '2023-12-04 09:50:07','2023-12-04 09:55:07', '2023-12-04 10:00:07', '2023-12-04 10:05:07',
    '2023-12-04 11:05:07','2023-12-04 12:05:07','2023-12-04 13:05:07','2023-12-04 14:05:07','2023-12-04 15:05:07',
  ]
  let option = {
    // 設定的是標題
    title: {
      text: '折線圖'
    },
    tooltip: {
      trigger: 'axis'
    },
    legend: {
      data: ['Email', 'Union Ads']
    },
    // 網格間距設定
    grid: {
      left: '30px',
      right: '60px',
      bottom: '3%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: dataXTime,
    },
    yAxis: {
      type: 'value'
    },
    // 資料
    series: [
      {
        name: 'Email',
        type: 'line',
        data: [120, 132, 101, 134, 90, 230, 210,90, 230, 210]
      },
      {
        name: 'Union Ads',
        type: 'line',
    
        data: [220, 182, 191, 234, 290, 330, 310,9, 30, 110]
      }
    ]
  };
  myChart.setOption(option);
</script>
</html>

發現多條折線共享一個時間

透過上面的小例子,我們發現一個問題:
多條折線共享的是一個時間(時間與資料是1對多的關係)
第一個時間匹配第一個資料,第2個時間匹配第2個資料。
也就是第n個時間匹配第n個資料。
我們不僅會提出這樣一個問題:
有沒有可能讓每一條折線擁有自己的時間呢?
時間不同,也可以顯示在一個例項上。

多條折線擁有資料自己的時間

<!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.staticfile.org/echarts/4.3.0/echarts.min.js"></script>
</head>

<body>
  <div style="width: 900px;height: 400px;"></div>
</body>
<script>
  let myChart = echarts.init(document.querySelector('div'))
  let option = {
    // 設定的是標題
    title: {
      text: '折線圖'
    },
    tooltip: {
      trigger: 'axis'
    },
    legend: {
      data: ['郵件', '簡訊']
    },
    // 網格間距設定
    grid: {
      left: '30px',
      right: '60px',
      bottom: '3%',
      containLabel: true
    },
    xAxis: {
      // xAxis的下不在設定data屬性共享時間
      type: 'category',
      splitLine: { show: false },
      lineStyle: {
        width: 2
      },
      axisTick: {
        show: false
      },
      axisLabel:{
        // 更改x軸文字顏色的配置
        textStyle: {
          color: '#717782'
        },
        showMaxLabel: true // 固定顯示X軸的最後一條資料
      },
      // 更改x軸線的顏色
      axisLine: {
        lineStyle: {
          color: '#D2DBE6;',
          width: 1 // x軸線的寬度
        }
      },
    },
    yAxis: {
      type: 'value'
    },
    // 資料
    series: [
      { 
        "name": "郵件", 
        "type": "line", 
        "symbol": "rect",
        "connectNulls": true,
        "showAllSymbol": true, 
        // 讓每一條折線擁有資料自己的時間
        "data": [ 
          [ "2023-12-04 09:50:07", "0.137"],
          [ "2023-12-04 09:55:07", "0.147"],
          [ "2023-12-04 10:00:07", "0.137"],
          [ "2023-12-04 10:05:07", "0.163"],
          [ "2023-12-04 10:10:07", "0.150"], 
          [ "2023-12-04 10:15:07", "0.143"], 
          [ "2023-12-04 10:20:07", "0.133"],
          [ "2023-12-04 10:25:07", "0.147"], 
          [ "2023-12-04 10:30:07", "0.147"],
          [ "2023-12-04 10:35:07", "0.143"],
          [ "2023-12-04 10:40:07", "0.140"], 
          [ "2023-12-04 10:45:07", "0.150"], 
          [ "2023-12-04 10:50:07", "0.143"],
        ], 
        "unit": "%", 
        "markPoint": { 
          "symbol": "rect",
          "symbolSize": "12",
          "label": { "show": false },
          "tooltip": { "triggerOn": "click", "trigger": "item" }, 
        }
      },
      { 
        "name": "簡訊", 
        "type": "line", 
        "symbol": "rect", 
        "connectNulls": true, 
        "showAllSymbol": true, 
          "data": [ 
            [ "2023-12-04 10:35:07", "0.123"],
            [ "2023-12-04 10:40:07", "0.140"], 
            [ "2023-12-04 10:45:07", "0.150"], 
            [ "2023-12-04 10:50:07", "0.143"],
          ], 
          "unit": "%", 
          "markPoint": { 
            "symbol": "circle",
            "symbolSize": "12", 
            "label": { "show": false } 
          } 
      } 
    ]
  };
  myChart.setOption(option);
</script>
</html>

成功了嗎?多條折線擁有資料自己的時間

根據上面的圖片,我們發現。
好像確實是每一條折線都擁有資料自己的時間了。
但是如果你只細看的話。你就會發現端倪
結束時間都是一樣的,但是折線卻是在不同的時間上結束的。
很明顯不正確的。

多條折線他們必須有一樣的開始時間和結束時間?

上面我們發現了問題:結束時間都是一樣的,但是折線卻是在不同的時間上結束的。
有的機智的小夥伴可能會說:
是因為:多條折線他們必須有一樣的開始時間和結束時間。
這樣echarts在渲染的時候就不會出現上面這樣的情況。
需要有相同的起始點和結束點
感覺有點道理,我們嘗試一下
 series: [
  { 
    "name": "郵件", 
    "data": [ 
      [ "2023-12-04 09:50:07", "0.137"],
      [ "2023-12-04 09:55:07", "0.147"],
      [ "2023-12-04 10:00:07", "0.137"],
      [ "2023-12-04 10:05:07", "0.163"],
      [ "2023-12-04 10:10:07", "0.150"], 
      [ "2023-12-04 10:15:07", "0.143"], 
      [ "2023-12-04 10:20:07", "0.133"],
      [ "2023-12-04 10:25:07", "0.147"], 
      [ "2023-12-04 10:30:07", "0.147"],
      [ "2023-12-04 10:35:07", "0.143"],
      [ "2023-12-04 10:40:07", "0.140"], 
      [ "2023-12-04 10:45:07", "0.150"], 
      [ "2023-12-04 10:50:07", "0.143"],
    ], 
  },
  { 
    "name": "簡訊", 
    "data": [ 
      [ "2023-12-04 09:50:07", "0.8"],
      [ "2023-12-04 10:40:07", "0.140"], 
      [ "2023-12-04 10:45:07", "0.150"], 
      [ "2023-12-04 10:50:07", "0.143"],
    ], 
  } 
]
現在都有相同的起始點(2023-12-04 09:50:07)和結束點(2023-12-04 10:50:07)。

如果每條折線的時間都沒有交集會怎麼樣?

我們發現只要有相同的起始點和結束點;
就會可以達到我們的預期效果。
此時,有的小夥伴說:
"如果他們的時間如果沒有交集會怎麼樣(有相同的起始點和結束點)"
"data": [ 
  [ "2023-12-04 09:50:07", "0.137"],
  [ "2023-12-04 09:55:07", "0.147"],
  [ "2023-12-04 10:00:07", "0.137"],
  [ "2023-12-04 10:05:07", "0.163"],
  [ "2023-12-04 10:10:07", "0.150"], 
  [ "2023-12-04 10:15:07", "0.143"], 
  [ "2023-12-04 10:20:07", "0.133"],
  [ "2023-12-04 10:25:07", "0.147"], 
  [ "2023-12-04 10:30:07", "0.147"],
  [ "2023-12-04 10:35:07", "0.143"],
  [ "2023-12-04 10:40:07", "0.140"], 
  [ "2023-12-04 10:45:07", "0.150"], 
  [ "2023-12-04 10:50:07", "0.143"],
], 

"data": [ 
  [ "2023-12-04 09:50:07", "0.8"],
  [ "2023-12-04 09:52:07", "1.23"],
  [ "2023-12-04 10:41:07", "0.140"], 
  [ "2023-12-04 10:49:07", "0.150"], 
  [ "2023-12-04 10:50:07", "0.143"],
], 

xAxis 的 type值設定time

時間繪製的折線圖不對,怎麼會有返回去的折線?
怎麼去解決這個問題呢?
有些小夥伴又提出了。我們可以將 xAxis 的 type值設定time。
就可以解決這個問題。

在 ECharts 中,type的值是 time 和 category 的區別

1.資料型別:'time' 表示時間型別的資料,適用於連續的時序資料。
通常返回的是時間戳。我們為了方便這裡寫的是yyyy-mm-dd hh:mm:ss
而 'category' 表示類目型別的資料,適用於離散的類目資料。

2.顯示方式:在 'time' 型別下,
ECharts 會根據時間跨度自動切換顯示的時間粒度,例如從月、星期、日到小時等。
而在 'category' 型別下,座標軸只會顯示類目列表,並且座標軸內僅包含這些指定類目的座標。

時間格式又不對

有眼尖的小夥伴發現了一個小問題。
我們給的時間是 yyyy-mm-dd hh:mm:ss的格式
但是剛剛發現展示的是 hh:ss mm-dd
格式和我們預期的不符合

xAxis 配置項 axisLabel下的formatter 轉換時間格式

透過查詢echarts的文件。
我們發現 xAxis.axisLabel.formatter 可以做到對格式進行轉換。
formatter:刻度標籤的內容格式器,支援字串模板和回撥函式兩種形式。 

對於時間軸(type: 'time'),formatter 的字串模板支援3種形式:
1.字串模板:簡單快速實現常用日期時間模板,string 型別
2.回撥函式:自定義 formatter,可以用來實現複雜高階的格式,Function 型別
3.分級模板:為不同時間粒度的標籤使用不同的 formatter,object 型別
我發現使用 字串模板 模板是不行的。分級模板沒有試過。
官網推薦使用字串模板,如果可以使用成功。
我們就不需要在寫一個方法進行轉化了。
但是很遺憾,失敗了。可能是用的方式錯誤吧

字串模板是失敗的

字串模板是失敗的原因

本來我已經失望了。
結果小腦袋靈光一閃,猜測有沒有可能是版本的原因。
我果斷去切換到5的版本
<script src="https://cdn.staticfile.org/echarts/5.3.0/echarts.min.js"></script>
果然字串模板顯示正常了
模板字串的詳細使用地址是:https://echarts.apache.org/zh/option.html#xAxis.axisLabel.formatter

字串模板轉化時間格式【推薦】

 xAxis: {
  // xAxis的下不在設定data屬性共享時間`
  type: 'time',
  splitLine: { show: false },
  lineStyle: {
    width: 2
  },
  axisTick: {
    show: false
  },
  axisLabel:{
    // 更改x軸文字顏色的配置
    textStyle: {
      color: '#717782'
    },
    // 設定座標軸上的時間格式 --使用的是模板字串
    // formatter: "{yyyy}-{MM}-{dd}", 得到的 label 形如:'2020-12-02'
    formatter: '{yyyy}-{MM}-{dd} \n{HH}:{mm}:{ss}',

    showMinLabel: true,
    showMaxLabel: true // 固定顯示X軸的最後一條資料
  },
  // 更改x軸線的顏色
  axisLine: {
    lineStyle: {
      color: '#D2DBE6;',
      width: 1 // x軸線的寬度
    }
  },
},

使用回撥函式轉化時間格式

function backTime(value){
  let date = new Date(value);  
  // 獲取年份、月份和日期  
  let year = date.getFullYear();  
  let month = date.getMonth() + 1; // 月份從 0 開始,需要加 1  
  let day = date.getDate();  

  let hours = date.getHours();  
  let minutes = date.getMinutes();  
  let seconds = date.getSeconds(); 
    
  // 格式化月份和日期為兩位數(不足兩位時補零)  
  month = month < 10 ? '0' + month : month;  
  day = day < 10 ? '0' + day : day;  

  hours = hours < 10 ? '0' + hours : hours;  
  minutes = minutes < 10 ? '0' + minutes : minutes;  
  seconds = seconds < 10 ? '0' + seconds : seconds;  
  
  // 返回格式化後的字串  
  return year + '-' + month + '-' + day + ' ' +
         hours + ':' + minutes + ':' + seconds;
}

xAxis: {
  // xAxis的下不在設定data屬性共享時間
  type: 'time',
  splitLine: { show: false },
  lineStyle: {
    width: 2
  },
  axisTick: {
    show: false
  },
  axisLabel:{
    // 更改x軸文字顏色的配置
    textStyle: {
      color: '#717782'
    },
    // 設定座標軸上的時間格式
    formatter: function (value) {  
      console.log('時間戳',value )
      // 將時間轉換為 我們需要的格式 ,這裡的value是一個時間戳
      return backTime(value)
    },
    showMinLabel: true,
    showMaxLabel: true // 固定顯示X軸的最後一條資料
  },
  // 更改x軸線的顏色
  axisLine: {
    lineStyle: {
      color: '#D2DBE6;',
      width: 1 // x軸線的寬度
    }
  },
},
特別提醒: type: 'time'的時候,
formatter : function (value) { }
中的value是一個時間戳

更改tooltip的時間格式

tooltip: {
  trigger: 'axis',
  formatter: (c) => {
    let str = ''
    let temp = {
      showTime: '', // 時間
      marker: '', // 顏色
      seriesName: '', // legend名稱
      valueData: '', // 數值
      setWidthSpan: '',
    }
    c.forEach((item) => {
      temp.showTime = item.data[0]
      temp.marker = item.marker
      temp.seriesName = item.seriesName 
      temp.valueData = item.value[1] 
      temp.setWidthSpan = '<span style="display:inline-block;width:10px;height:10px;"></span>'
      str += temp.marker + temp.seriesName + temp.setWidthSpan + temp.valueData + '<br />'
    })
    return temp.showTime + '<br />' + str
  },
},

完整程式碼

<!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.staticfile.org/echarts/4.3.0/echarts.min.js"></script>
</head>

<body>
  <div style="width: 900px;height: 400px;"></div>
</body>
<script>

  function backTime(value){
    let date = new Date(value);  
    // 獲取年份、月份和日期  
    let year = date.getFullYear();  
    let month = date.getMonth() + 1; // 月份從 0 開始,需要加 1  
    let day = date.getDate();  

    let hours = date.getHours();  
    let minutes = date.getMinutes();  
    let seconds = date.getSeconds(); 
      
    // 格式化月份和日期為兩位數(不足兩位時補零)  
    month = month < 10 ? '0' + month : month;  
    day = day < 10 ? '0' + day : day;  

    hours = hours < 10 ? '0' + hours : hours;  
    minutes = minutes < 10 ? '0' + minutes : minutes;  
    seconds = seconds < 10 ? '0' + seconds : seconds;  
    
    // 返回格式化後的字串  
    return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
  }
  let myChart = echarts.init(document.querySelector('div'))
  let option = {
    // 設定的是標題
    title: {
      text: '折線圖'
    },
    tooltip: {
      trigger: 'axis',
      formatter: (c) => {
        let str = ''
        let temp = {
          showTime: '', // 時間
          marker: '', // 顏色
          seriesName: '', // legend名稱
          valueData: '', // 數值
          setWidthSpan: '',
        }
        c.forEach((item) => {
          temp.showTime = item.data[0]
          temp.marker = item.marker
          temp.seriesName = item.seriesName 
          temp.valueData = item.value[1] 
          temp.setWidthSpan = '<span style="display:inline-block;width:10px;height:10px;"></span>'
          str += temp.marker + temp.seriesName + temp.setWidthSpan + temp.valueData + '<br />'
        })
        return temp.showTime + '<br />' + str
      },
    },
    legend: {
      data: ['郵件', '簡訊']
    },
    // 網格間距設定
    grid: {
      left: '30px',
      right: '60px',
      bottom: '3%',
      containLabel: true
    },
    xAxis: {
      // xAxis的下不在設定data屬性共享時間`
      type: 'time',
      splitLine: { show: false },
      lineStyle: {
        width: 2
      },
      axisTick: {
        show: false
      },
      axisLabel:{
        // 更改x軸文字顏色的配置
        textStyle: {
          color: '#717782'
        },
        // 設定座標軸上的時間格式
        formatter: function (value) {  
          console.log('時間戳',value )
          // 將時間轉換為 JavaScript 日期物件  
          return backTime(value)
        },
        showMinLabel: true,
        showMaxLabel: true // 固定顯示X軸的最後一條資料
      },
      // 更改x軸線的顏色
      axisLine: {
        lineStyle: {
          color: '#D2DBE6;',
          width: 1 // x軸線的寬度
        }
      },
    },
    yAxis: {
      type: 'value'
    },
    // 資料
    series: [
      { 
        "name": "郵件", 
        "type": "line", 
        "symbol": "rect",
        "connectNulls": true,
        "showAllSymbol": true, 
        // 讓每一條折線擁有資料自己的時間
        "data": [ 
          [ "2023-12-04 09:50:07", "0.137"],
          [ "2023-12-04 09:55:07", "0.147"],
          [ "2023-12-04 10:00:07", "0.137"],
          [ "2023-12-04 10:05:07", "0.163"],
          [ "2023-12-04 10:10:07", "0.150"], 
          [ "2023-12-04 10:15:07", "0.143"], 
          [ "2023-12-04 10:20:07", "0.133"],
          [ "2023-12-04 10:25:07", "0.147"], 
          [ "2023-12-04 10:30:07", "0.147"],
          [ "2023-12-04 10:35:07", "0.143"],
          [ "2023-12-04 10:40:07", "0.140"], 
          [ "2023-12-04 10:45:07", "0.150"], 
          [ "2023-12-04 10:50:07", "0.143"],
        ], 
        "unit": "%", 
        "markPoint": { 
          "symbol": "rect",
          "symbolSize": "12",
          "label": { "show": false },
          "tooltip": { "triggerOn": "click", "trigger": "item" }, 
        }
      },
      { 
        "name": "簡訊", 
        "type": "line", 
        "symbol": "rect", 
        "connectNulls": true, 
        "showAllSymbol": true, 
          "data": [ 
            [ "2023-12-04 09:50:07", "0.8"],
            [ "2023-12-04 09:52:07", "1.23"],
            [ "2023-12-04 10:41:07", "0.140"], 
            [ "2023-12-04 10:42:07", "0.140"], 
            [ "2023-12-04 10:45:07", "0.140"], 
            [ "2023-12-04 10:49:07", "0.150"], 
            [ "2023-12-04 10:50:07", "0.143"],
          ], 
          "unit": "%", 
          "markPoint": { 
            "symbol": "circle",
            "symbolSize": "12", 
            "label": { "show": false } 
          } 
      } 
    ]
  };
  myChart.setOption(option);
</script>
</html>

相關文章