echarts设置多条折线-不是你想的那样简单

简单的多条折线图

css 复制代码
小伙伴写过多条折线图的都知道,
常见的折线图是  xAxis 配置项下的 data属性上设置时间或者日期。
series配置项下是对应的 legend中的数据以及该条折线的数据。
xml 复制代码
<!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>

发现多条折线共享一个时间

scss 复制代码
通过上面的小例子,我们发现一个问题:
多条折线共享的是一个时间(时间与数据是1对多的关系)
第一个时间匹配第一个数据,第2个时间匹配第2个数据。
也就是第n个时间匹配第n个数据。
我们不仅会提出这样一个问题:
有没有可能让每一条折线拥有自己的时间呢?
时间不同,也可以显示在一个实例上。

多条折线拥有数据自己的时间

xml 复制代码
<!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在渲染的时候就不会出现上面这样的情况。
需要有相同的起始点和结束点
感觉有点道理,我们尝试一下
css 复制代码
 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)。

如果每条折线的时间都没有交集会怎么样?

less 复制代码
我们发现只要有相同的起始点和结束点;
就会可以达到我们的预期效果。
此时,有的小伙伴说:
"如果他们的时间如果没有交集会怎么样(有相同的起始点和结束点)"
"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

lua 复制代码
时间绘制的折线图不对,怎么会有返回去的折线?
怎么去解决这个问题呢?
有些小伙伴又提出了。我们可以将 xAxis 的 type值设置time。
就可以解决这个问题。

在 ECharts 中,type的值是 time 和 category 的区别

css 复制代码
1.数据类型:'time' 表示时间类型的数据,适用于连续的时序数据。
通常返回的是时间戳。我们为了方便这里写的是yyyy-mm-dd hh:mm:ss
而 'category' 表示类目类型的数据,适用于离散的类目数据。

2.显示方式:在 'time' 类型下,
ECharts 会根据时间跨度自动切换显示的时间粒度,例如从月、星期、日到小时等。
而在 'category' 类型下,坐标轴只会显示类目列表,并且坐标轴内仅包含这些指定类目的坐标。

时间格式又不对

css 复制代码
有眼尖的小伙伴发现了一个小问题。
我们给的时间是 yyyy-mm-dd hh:mm:ss的格式
但是刚刚发现展示的是 hh:ss mm-dd
格式和我们预期的不符合

xAxis 配置项 axisLabel下的formatter 转换时间格式

typescript 复制代码
通过查询echarts的文档。
我们发现 xAxis.axisLabel.formatter 可以做到对格式进行转换。
formatter:刻度标签的内容格式器,支持字符串模板和回调函数两种形式。 

对于时间轴(type: 'time'),formatter 的字符串模板支持3种形式:
1.字符串模板:简单快速实现常用日期时间模板,string 类型
2.回调函数:自定义 formatter,可以用来实现复杂高级的格式,Function 类型
3.分级模板:为不同时间粒度的标签使用不同的 formatter,object 类型
我发现使用 字符串模板 模板是不行的。分级模板没有试过。
官网推荐使用字符串模板,如果可以使用成功。
我们就不需要在写一个方法进行转化了。
但是很遗憾,失败了。可能是用的方式错误吧

字符串模板是失败的

字符串模板是失败的原因

bash 复制代码
本来我已经失望了。
结果小脑袋灵光一闪,猜测有没有可能是版本的原因。
我果断去切换到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

字符串模板转化时间格式【推荐】

css 复制代码
 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轴线的宽度
    }
  },
},

使用回调函数转化时间格式

javascript 复制代码
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轴线的宽度
    }
  },
},
lua 复制代码
特别提醒: type: 'time'的时候,
formatter : function (value) { }
中的value是一个时间戳

更改tooltip的时间格式

javascript 复制代码
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
  },
},

完整代码

xml 复制代码
<!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>
相关推荐
忆琳6 分钟前
Vue3 全局自动大写转换:一个配置,全站生效
javascript·element
喵个咪9 分钟前
Headless 架构优势:内容与展示解耦,一套 API 打通全端生态
前端·后端·cms
小江的记录本13 分钟前
【JEECG Boot】 JEECG Boot——数据字典管理 系统性知识体系全解析
java·前端·spring boot·后端·spring·spring cloud·mybatis
喵个咪16 分钟前
传统 CMS 太笨重?试试 Headless 架构的 GoWind,轻量又强大
前端·后端·cms
chenjingming66617 分钟前
jmeter导入浏览器上按F12抓的数据包
前端·chrome·jmeter
张元清17 分钟前
不用 Server Components 也能做 React 流式 SSR —— 实战指南
前端·javascript·面试
前端技术19 分钟前
ArkTS第三章:声明式UI开发实战
java·前端·人工智能·python·华为·鸿蒙
码小瑞24 分钟前
画布文字在不同缩放屏幕上的归一化
前端
神の愛24 分钟前
java日志功能
java·开发语言·前端