echart在折线显示横纵(横纵线沿着折线展示)

2023-09-21 20:25:21

产品有个需求,需要在echart折线上展示横纵向坐标系,echart的axisPointer默认是展示在鼠标当前位置的,不符合需求,所以是使用markline实现的

在线例子和源码

先上效果图

在这里插入图片描述

实现思路

  1. 横纵线的x轴线是比较容易的,因为echart的axixPointer的位置是鼠标当前坐标作的,所以x轴线直接用toltip的axisPointer
tooltip: {
    trigger: "axis",
    triggerOn: "mousemove",
    backgroundColor: "#FFFFFF",
    formatter: function () {},
    axisPointer: {
      type: "line",
      label: {
        show: true,
        backgroundColor: "#FF7613",
        borderRadius: 4,
        fontSize: 11,
        padding: [4, 5]
      },
      lineStyle: {
        color: "#FF7613",
        type: "dotted",
        width: 3 // 正常时的折线宽度
      }
    }
  },
  1. y轴线则使用的series的markLine,只需要把默认的箭头去掉接口
series: [
    {
      type: "line",
      data: data, // Y 轴的数据
      symbol: "none",
      label: {
        show: false
      },
      markLine: {
        symbol: "none",
        animation: false,
        label: {
          normal: {
            show: true,
            position: "start",
            backgroundColor: "#FF7613",
            borderRadius: 4,
            fontSize: 12, // 修改字体大小
            padding: [4, 6], // 修改内边距
            color: "#FFFFFF"
          }
        },
        lineStyle: {
          normal: {
            color: "#FF7613",
            type: "dotted",
            width: 3 // 正常时的折线宽度
          }
        },
        emphasis: {
          label: {
            normal: {
              show: false
            }
          },
          lineStyle: {
            normal: {
              color: "#FF7613",
              type: "dotted",
              width: 1 // hover时的折线宽度
            }
          }
        },
        data: []
      }
    }
  ]
  1. 第二步的markLine的data是空数组,这样是不会展示的线的
    • 需要在鼠标移动过程中实时画线,所以需要监听echart的mousemove事件,获取当前鼠标位置再转换成对应的坐标,最终得到实际的x轴位置(也就是当前x轴的下标),然后读取series的data[x]即可
    • 在展示markLine时候,需要展示axisPopinter,通过echart的dispatchAction(showtip)展示
    • 下面代码有注释每一步的作用
myChart.getZr().on("mousemove", (params) => {
  // 获取点击位置的坐标
  let pointInPixel = [params.offsetX, params.offsetY];
  // convertFromPixel将鼠标位置坐标进行转化
  // 返回[x, y],x对应鼠标点击处数据的下标,y对应鼠标点击处的数值
  let x = myChart.convertFromPixel({ seriesIndex: 0 }, pointInPixel)[0];
  const xAxis = option.xAxis;
  const xData = xAxis.data;
  // 兼容超出x轴的最大最小值时候,axisPointer的展示位置
  if (x > xData.length - 1) {
    x = xData.length - 1;
  } else if (x < 0) {
    x = 0;
  }
  // series[0].data[x]折线上的数据
  const markLineValue = option.series[0].data[x];
  const { series } = option;
  // 修改markLine的值
  series[0].markLine.data = [
    {
      yAxis: markLineValue
    }
  ];
  // 触发展示tooltip的axisPointer
  myChart.dispatchAction({
    type: "showTip",
    seriesIndex: 0,
    dataIndex: x
  });
  myChart.setOption({ series }, { lazyUpdate: true });
});
  1. 还需要添加一下鼠标移出mouseout事件,把markLine和axisPointer隐藏
// 监听鼠标移出事件,隐藏markline
myChart.getZr().on("mouseout", () => {
  const { series } = option;
  // 修改markLine的值
  series[0].markLine.data = [];
  myChart.setOption({ series }, { lazyUpdate: true });
});

window.addEventListener("resize", myChart.resize);

解释一下为什么不用markline做x轴的线,因为markLine的label会被echart遮挡(并不像axisPointer的label会自适应位置),可以调整grid的right,使右边空出来地方来展示label,但是这样web端还好,对于移动端就有点尴尬,浪费空间,建议使用axisPointer

在这里插入图片描述

完整代码,在线例子和源码点我

const dom = document.getElementById("chart-container");
var myChart = echarts.init(dom, null, {
  renderer: "canvas",
  useDirtyRect: false
});

const data = [ 32, 30, 29, 28, 26, 20, 18, 17, 17, 18, 19, 20, 21, 20, 21, 18, 12, 25, 26, 25, 26, 25, 30, 25, 29, 27, 28, 22, 23, 30, 26, 25, 24, 23, 16, 14, 18, 12, 10, 6, 8, 9, 9, 8, 9, 10, 12, 10, 13, 16, 20, 22, 23, 26, 25, 28, 29, 32, 38, 41, 39, 40, 41, 38, 37, 36, 35, 32, 28, 32, 38, 39, 40, 39, 36, 35, 34, 32, 26, 27, 29, 29, 31, 32, 38, 26, 22, 16, 17, 19, 18, 20, 25, 29, 30, 28, 31, 33, 42, 38, 41, 45];

const xData = [ "2023-09-21", "2023-09-22", "2023-09-23", "2023-09-24", "2023-09-25", "2023-09-26", "2023-09-27", "2023-09-28", "2023-09-29", "2023-09-30", "2023-10-01", "2023-10-02", "2023-10-03", "2023-10-04", "2023-10-05", "2023-10-06", "2023-10-07", "2023-10-08", "2023-10-09", "2023-10-10", "2023-10-11", "2023-10-12", "2023-10-13", "2023-10-14", "2023-10-15", "2023-10-16", "2023-10-17", "2023-10-18", "2023-10-19", "2023-10-20", "2023-10-21", "2023-10-22", "2023-10-23", "2023-10-24", "2023-10-25", "2023-10-26", "2023-10-27", "2023-10-28", "2023-10-29", "2023-10-30", "2023-10-31", "2023-11-01", "2023-11-02", "2023-11-03", "2023-11-04", "2023-11-05", "2023-11-06", "2023-11-07", "2023-11-08", "2023-11-09", "2023-11-10", "2023-11-11", "2023-11-12", "2023-11-13", "2023-11-14", "2023-11-15", "2023-11-16", "2023-11-17", "2023-11-18", "2023-11-19", "2023-11-20", "2023-11-21", "2023-11-22", "2023-11-23", "2023-11-24", "2023-11-25", "2023-11-26", "2023-11-27", "2023-11-28", "2023-11-29", "2023-11-30", "2023-12-01", "2023-12-02", "2023-12-03", "2023-12-04", "2023-12-05", "2023-12-06", "2023-12-07", "2023-12-08", "2023-12-09", "2023-12-10", "2023-12-11", "2023-12-12", "2023-12-13", "2023-12-14", "2023-12-15", "2023-12-16", "2023-12-17", "2023-12-18", "2023-12-19", "2023-12-20", "2023-12-21", "2023-12-22", "2023-12-23", "2023-12-24", "2023-12-25", "2023-12-26", "2023-12-27", "2023-12-28", "2023-12-29", "2023-12-30", "2023-12-31"];

const option = {
  tooltip: {
    trigger: "axis",
    triggerOn: "mousemove",
    backgroundColor: "#FFFFFF",
    formatter: function () {},
    axisPointer: {
      type: "line",
      label: {
        show: true,
        backgroundColor: "#FF7613",
        borderRadius: 4,
        fontSize: 11,
        padding: [4, 5]
      },
      lineStyle: {
        color: "#FF7613",
        type: "dotted",
        width: 3 // 正常时的折线宽度
      }
    }
  },
  grid: {
    left: "10%",
    right: "10%",
    bottom: "10%",
    top: "10%",
    containLabel: true
  },
  xAxis: {
    type: "category",
    data: xData
  },
  yAxis: {
    type: "value"
  },
  series: [
    {
      type: "line",
      data: data, // Y 轴的数据
      symbol: "none",
      label: {
        show: false
      },
      markLine: {
        symbol: "none",
        animation: false,
        label: {
          normal: {
            show: true,
            position: "start",
            backgroundColor: "#FF7613",
            borderRadius: 4,
            fontSize: 12, // 修改字体大小
            padding: [4, 6], // 修改内边距
            color: "#FFFFFF"
          }
        },
        lineStyle: {
          normal: {
            color: "#FF7613",
            type: "dotted",
            width: 3 // 正常时的折线宽度
          }
        },
        emphasis: {
          label: {
            normal: {
              show: false
            }
          },
          lineStyle: {
            normal: {
              color: "#FF7613",
              type: "dotted",
              width: 1 // hover时的折线宽度
            }
          }
        },
        data: []
      }
    }
  ]
};

myChart.setOption(option);

// 监听鼠标移进事件,展示markline和tooltip的axisPointer
myChart.getZr().on("mousemove", (params) => {
  // 获取点击位置的坐标
  let pointInPixel = [params.offsetX, params.offsetY];
  // convertFromPixel将鼠标位置坐标进行转化
  // 返回[x, y],x对应鼠标点击处数据的下标,y对应鼠标点击处的数值
  let x = myChart.convertFromPixel({ seriesIndex: 0 }, pointInPixel)[0];
  const xAxis = option.xAxis;
  const xData = xAxis.data;
  // 兼容超出x轴的最大最小值时候,axisPointer的展示位置
  if (x > xData.length - 1) {
    x = xData.length - 1;
  } else if (x < 0) {
    x = 0;
  }
  // series[0].data[x]折线上的数据
  const markLineValue = option.series[0].data[x];
  const { series } = option;
  // 修改markLine的值
  series[0].markLine.data = [
    {
      yAxis: markLineValue
    }
  ];
  // 触发展示tooltip的axisPointer
  myChart.dispatchAction({
    type: "showTip",
    seriesIndex: 0,
    dataIndex: x
  });
  myChart.setOption({ series }, { lazyUpdate: true });
});

// 监听鼠标移出事件,隐藏markline
myChart.getZr().on("mouseout", () => {
  const { series } = option;
  // 修改markLine的值
  series[0].markLine.data = [];
  myChart.setOption({ series }, { lazyUpdate: true });
});

window.addEventListener("resize", myChart.resize);

更多推荐

竞赛 基于深度学习的人脸表情识别

文章目录0前言1技术介绍1.1技术概括1.2目前表情识别实现技术2实现效果3深度学习表情识别实现过程3.1网络架构3.2数据3.3实现流程3.4部分实现代码4最后0前言🔥优质竞赛项目系列,今天要分享的是基于深度学习的人脸表情识别该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!🧿更多资料,项目分享:https:/

Learn Prompt-Prompt 高级技巧:API-Bank & AgentBench

模型评估是Agent学习过程中至关重要的一环。通过分析数据来评估Agent的能力,可以客观地衡量它在特定任务或领域中的表现。数据评估是不断迭代和改进的基础。通过反复评估和分析数据,Agent可以逐步改进自身,并不断优化其能力。数据评估还可以将Agent与其他Agent或标准进行比较,从而了解其在同一任务或领域中的相对能

Learn Prompt-GPT-4:综述

简介"GPT-4,这是OpenAI在扩大深度学习方面的最新里程碑。GPT-4是一个大型的多模态模型(接受图像和文本输入,发出文本输出),虽然在许多现实世界的场景中能力不如人类,但在各种专业和学术基准上表现出人类水平的性能。"--OpenAIGPT-4,顾名思义是GPT-3和GPT-3.5的下一代模型。相比前面的模型,G

汽车行业新闻稿怎么写?怎么写关于汽车的新闻稿?

撰写汽车行业新闻稿需要遵循一定的结构和要点,以确保内容准确、清晰,并能吸引读者的兴趣。以下是关于汽车的新闻稿的一些写作要点和建议,接下来伯乐网络传媒就来给大家分享一下:标题醒目:新闻稿的标题应该简洁明了,能够吸引读者的眼球并概括新闻的要点。可以使用一些字眼来突显重点,例如“首次亮相”、“全新发布”等。新闻价值:新闻稿应

Python Quine 介绍

一个Quine是一个产生其源代码作为输出的计算机程序。该程序不需要输入,并输出其源代码的副本。Quine很有趣,因为它们似乎违背了编程的目的,即根据输入生成输出。在某些情况下,Quine可能是有帮助的,例如当您需要生成程序源代码的副本时。运行PythonQuine创建一个Quine并不特别困难,但需要一些思考。基本思想

Python 基于PyCharm断点调试

视频版教程Python3零基础7天入门实战视频教程PyCharmDebug(断点调试)可以帮助开发者在代码运行时进行实时的调试和错误排查,提高代码开发效率和代码质量。准备一段代码defadd(num1,num2):returnnum1+num2if__name__=='__main__':fornuminrange(1

Linux Day18 TCP_UDP协议及相关知识

一、网络基础概念1.1网络网络是由若干结点和连接这些结点的链路组成,网络中的结点可以是计算机,交换机、路由器等设备。1.2互联网把多个网络连接起来就构成了互联网。目前最大的互联网就是因特网。网络设备有:交换机、路由器、集线器传输介质有:双绞线、同轴电缆、光纤,无线1.3IP地址IP地址就是给因特网上的每一个主机(或路由

【工作记录】springboot集成aop实现日志@20230918

springboot集成aop实现日志1.添加依赖<!--aop依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>2.定义注解@

使用Postman如何在接口测试前将请求的参数进行自定义处理

1、前言当我们使用Postman进行接口测试时,对于简单的不需要处理的接口,直接请求即可,但是对于需要处理的接口,如需要转码、替换值等,则就麻烦一些,一般我们都是先手动把修改好的值拷贝到请求里再进行请求接口,这也是大多数测试人员进行接口测试时这么做的。其实Postman有一个Pre-requestScript功能,即在

Ampere ARM Server 内核版本更新

本篇记录AmpereARMServer服务器上,升级内核版本或部分驱动的方法。安装编译依赖库sudoapt-getinstallbuild-essentialkernel-packagelibncurses5-devlibncurses-devsudoapt-getinstallgccmakebisonflexlibs

(高阶)Redis 7 第13讲 数据双写一致性 canal篇

面试题问题答案如何保证mysql改动后,立即同步到Rediscanal简介https://github.com/alibaba/canal/wikihttps://github.com/alibaba/canal/wiki基于MySQL数据库增量日志解析,提供增量数据订阅和消费业务数据库镜像数据库实时备份多级索引(卖家

热文推荐