当系列没有相同的时间值时,如何在工具提示中显示所有系列

2024-05-12

我有一个显示多个时间序列的图表。不同时间序列不会同时采样。有没有办法在工具提示中显示所有系列?在示例中,您可以看到所有系列都包含在前 2 个点的工具提示中,因为它们是同时采样的。其余点仅包含 1 个系列。

var myChart = echarts.init(document.getElementById('main'));

var series = [{
    "name": "sensor 1",
    "data": [{
        "value": [
          "2019-02-20T11:47:44.000Z",
          22.2
        ]
      },
      {
        "value": [
          "2019-02-20T12:03:02.000Z",
          22.1
        ]
      },
      {
        "value": [
          "2019-02-20T12:18:19.000Z",
          22.15
        ]
      },
      {
        "value": [
          "2019-02-20T12:33:36.000Z",
          22.2
        ]
      },
      {
        "value": [
          "2019-02-20T12:48:53.000Z",
          22.15
        ]
      }
    ],
    "type": "line"
  },
  {
    "name": "sensor 2",
    "data": [{
        "value": [
          "2019-02-20T11:47:44.000Z",
          23.2
        ]
      },
      {
        "value": [
          "2019-02-20T12:03:02.000Z",
          23.1
        ]
      },
      {
        "value": [
          "2019-02-20T12:22:19.000Z",
          24.15
        ]
      },
      {
        "value": [
          "2019-02-20T12:39:36.000Z",
          21.2
        ]
      },
      {
        "value": [
          "2019-02-20T12:52:53.000Z",
          20.15
        ]
      }
    ],
    "type": "line"
  }
]

var option = {
  legend: {},
  tooltip: {
    trigger: 'axis',
  },
  xAxis: {
    type: 'time'
  },
  yAxis: {
    scale: true
  },
  series: series,
};

myChart.setOption(option);
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.0.4/echarts.min.js"></script>

<div id="main" style="width: 500px;height:400px;"></div>

解决方案说明

如本文所述功能要求 https://github.com/apache/echarts/issues/15488在 echarts 的 github 上,他们计划将来添加你想要的内容。但目前来看,仍然不支持。

所以我找到了一个解决方法来显示工具提示all系列,即使它们没有精确的值xaxisPointer 所在的位置。为此,我使用了工具提示formatter https://echarts.apache.org/en/option.html#tooltip.formatter可以定义为回调函数,每次必须更改工具提示时(即每次 axisPointer 在新值上移动时)都会调用该函数,并且您可以在其中指定自己的工具提示格式。

在此函数内,您可以访问有关 axisPointer 处数据的每条信息(尤其是其xAxis value在我们的例子中)。给定 axisPointer 的 xAxis 值,我们可以通过我们的series并找到与该 xAxis 值最接近的值。

formatter : (params) => {
   //The datetime where the axisPointer is
   var xTime = new Date(params[0].axisValue)
      
   //Create our custom tooltip and add to its top the dateTime where the axisPointer is
   let tooltip = `<p>${xTime.toLocaleString()}</p> `;
      
   //Go through each serie
   series.forEach((serie, index) => {
     //Find the closest value
     value = serie.data.reduce((prev, curr) => Math.abs(new Date(curr.value[0]).valueOf() - xTime.valueOf()) < Math.abs(new Date(prev.value[0]).valueOf() - xTime.valueOf()) ? curr : prev).value[1]
        
     /* Add a line in our custom tooltip */
     // Add the colored circle at the begining of the line
     tooltip += `<p><span style="display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color: ${myChart.getVisual({ seriesIndex: index }, 'color')}"></span>`
     // Add the serie's name and its value
     tooltip += `${serie.name} &emsp;&emsp; <b>${value}</b></p>`;
   });
   return tooltip;
}

完整代码

这是使用您的示例的完整代码:

var myChart = echarts.init(document.getElementById('main'));

var series = [{
    "name": "sensor 1",
    //step: "end",
    "data": [{
        "value": [
          "2019-02-20T11:47:44.000Z",
          22.2
        ]
      },
      {
        "value": [
          "2019-02-20T12:03:02.000Z",
          22.1
        ]
      },
      {
        "value": [
          "2019-02-20T12:18:19.000Z",
          22.15
        ]
      },
      {
        "value": [
          "2019-02-20T12:33:36.000Z",
          22.2
        ]
      },
      {
        "value": [
          "2019-02-20T12:48:53.000Z",
          22.15
        ]
      }
    ],
    "type": "line"
  },
  {
    "name": "sensor 2",
    //step: 'end',
    "data": [{
        "value": [
          "2019-02-20T11:47:44.000Z",
          23.2
        ]
      },
      {
        "value": [
          "2019-02-20T12:03:02.000Z",
          23.1
        ]
      },
      {
        "value": [
          "2019-02-20T12:22:19.000Z",
          24.15
        ]
      },
      {
        "value": [
          "2019-02-20T12:39:36.000Z",
          21.2
        ]
      },
      {
        "value": [
          "2019-02-20T12:52:53.000Z",
          20.15
        ]
      }
    ],
    "type": "line"
  }
]

option = {
  legend: {},
  tooltip: {
    trigger: 'axis',
    formatter : (params) => {
      //The datetime where the axisPointer is
      var xTime = new Date(params[0].axisValue)
      
      //Create our custom tooltip and add to its top the dateTime where the axisPointer is
      let tooltip = `<p>${xTime.toLocaleString()}</p> `;
      
      //Go through each serie
      series.forEach((serie, index) => {
        //Find the closest value
        value = serie.data.reduce((prev, curr) => Math.abs(new Date(curr.value[0]).valueOf() - xTime.valueOf()) < Math.abs(new Date(prev.value[0]).valueOf() - xTime.valueOf()) ? curr : prev).value[1]
        
        /* Add a line in our custom tooltip */
        // Add the colored circle at the begining of the line
        tooltip += `<p><span style="display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color: ${myChart.getVisual({ seriesIndex: index }, 'color')}"></span>`
        // Add the serie's name and its value
        tooltip += `${serie.name} &emsp;&emsp; <b>${value}</b></p>`;
      });
      return tooltip;
    }
  },
  xAxis: {
    type: 'time'
  },
  yAxis: {
    scale: true
  },
  series: series,
};

myChart .setOption(option)
<html>
  <body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.3.2/echarts.min.js"></script>
    <div id="main" style="width: 600px; height:400px;"></div>
  </body>
</html>

进一步的想法

  • 线性插值

而不是显示最接近的值real点,我们还可以通过简单的线性插值来计算该值。

Linear interpolation
Here is the formatter function with linear interpolation (not the most preformant, but working)

formatter : (params) => {
   var xTime = new Date(params[0].axisValue)
   let tooltip = `<p>${xTime.toLocaleString()}</p> `;
   series.forEach((serie, index) => {
     //Only works if series is chronologically sorted
     prev_point = serie.data.reduce((prev, curr) => new Date(curr.value[0]).valueOf() <= xTime.valueOf() ? curr : prev)
     next_point = serie.data.slice(0).reduce((prev, curr, i, arr) => {
       if(new Date(curr.value[0]).valueOf() >= xTime.valueOf()) {
         arr.splice(1);
       }
       return curr
     })
     var value = 0
     if(next_point.value[1] == prev_point.value[1]){
       value = next_point.value[1]
     }
     else {
       //Linear interpolation
       value = Math.round((prev_point.value[1] + (xTime.valueOf()/1000 - new Date(prev_point.value[0]).valueOf()/1000) * ((next_point.value[1] - prev_point.value[1]) / (new Date(next_point.value[0]).valueOf()/1000 - new Date(prev_point.value[0]).valueOf()/1000)))*10)/10
     }
     tooltip += `<p><span style="display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color: ${myChart.getVisual({ seriesIndex: index }, 'color')}"></span> ${serie.name} &emsp;&emsp; <b>${value}</b></p>`;
   });
   return tooltip;
}
  • 将系列显示为步骤

为了使其在视觉上更加准确,您可以将系列显示为step: 'end'并获取最接近的前一个值,而不仅仅是 最接近的值,使用:

value = serie.data.reduce((prev, curr) => new Date(curr.value[0]).valueOf() <= xTime.valueOf() ? curr : prev).value[1]

这样做,工具提示中显示的值将与您在图表上看到的完全相同。

  • 表现

The reduce()方法在处理整个系列时在大型数据集上速度很慢。例如,将其替换为二分搜索(二分搜索)将大大提高性能。

如果有人有使其性能更高的想法,我会很感兴趣。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当系列没有相同的时间值时,如何在工具提示中显示所有系列 的相关文章

  • javascript中如何无限循环

    我尝试使用 0 到 100 和 100 到 0 之间的 while 进行无限循环 但浏览器崩溃了 有没有办法清除浏览器内存 这是我的代码 var a 0 var flag true while true if a lt 100 flag t
  • 使用 AJAX 来回发送信息

    使用 post 你可以向服务器发送信息 但是当你需要从服务器接收信息时怎么办呢 信息如何从可以由 php 变量保存的方式变为可以由 javascript 变量保存的方式 反之亦然 这与您的问题更相关 http docs jquery com
  • Jest 中从未调用图像 onLoad 处理程序

    我正在尝试使用 Jest 测试将 dataUrl 加载到图像中 我正在使用 JSDOM 并按照说明添加resources usable 作为一个选项 如果我直接从 Node 运行该代码 则该代码可以工作 但是当我尝试在 Jest 中运行它时
  • 如何使用nodeJS SFTP客户端列出所有子目录?

    有趣的节点 JS ssh2 sftp client 我想列出给定路径中的所有目录及其子目录 let sftp new ssh2SftpClient console log sftp sftp connect host xx xxx xxx
  • Jqplot 中两个系列数据的不同颜色条

    我想知道如何在 Jqplot 中为两个系列制作不同的颜色条 如果我只有一个系列数据 它的工作原理如下图所示 红色和绿色基于其值 但是 如果我有两个系列数据 我无法为每个系列数据配置两个系列颜色 目前我只能做这个图 我希望两个系列图可以根据其
  • 如何监控浏览器中发出的所有自定义事件?

    我想监视网络浏览器中触发的所有自定义事件 任何标准浏览器都可以 需要明确的是 我知道您可以附加事件处理程序来查看何时触发 通常 事件 但如何可靠地检测嵌入对象或 jQuery 脚本是否触发自定义事件 我可以重构浏览器源代码来挂钩事件循环 但
  • Object.assign() - 奇怪的行为需要解释

    我有这个代码 function margeOptions options passedOptions options Object assign options passedOptions let passedOpts a true let
  • 使用shinyjs通过javascript在闪亮的应用程序中操作现有的Leaflet地图

    我有一个闪亮的应用程序 其中包含现有的传单地图 我希望能够在渲染后使用自定义 javascript 通过shinyjs包裹 一个最小的例子如下 app R packages library dplyr library leaflet lib
  • RequireJS 不遵循设置了 baseUrl 的 data-main 的相对路径

    使用 requireJS 我尝试为我的数据主指定一个与 baseUrl 不同的路径 看来 requireJS 会忽略我在文件名之前输入的任何内容 并始终在 baseUrl 文件夹中查找该文件 我有以下文件夹结构 index html scr
  • TypeScript 中类和命名空间的区别

    到底有什么区别classes and namespaces在打字稿中 我知道 如果您创建一个带有静态方法的类 您可以在不实例化该类的情况下访问它们 这正是我猜想的命名空间的要点之一 我还知道你可以创建多个同名的命名空间 并且它们的方法在编译
  • 向下滚动时如何使图像移动?

    这是我想要实现的目标的示例 https www flambette com en https www flambette com en 我尝试过更改图像的 css 属性 但效果不能满足我的需求 我尝试过以下代码 mydocument on
  • 如何在 Jest 测试中模拟 StatusBarManager.getHeight?

    我正在使用 expo 34 并且反应本机用户界面库 https www npmjs com package react native ui lib来自 wix 并且在为我的组件设置笑话测试时遇到问题 问题看起来出现在link https g
  • Javascript 根据字段值任意排序数组

    所以我有一个对象数组 如下所示 var myArray priority low priority critical priority high 我需要以这种方式排序 1 关键 2 高和3 低 如何才能做到这一点 我建议使用一个对象来存储排
  • 如何混淆或使 JavaScript 文件不可读?

    我的应用程序中有 JavaScript 脚本 其中包含 JavaScript 和 jQuery 函数 所有用户与我的应用程序的交互都是动态的 并且通过 jQuery 传递到应用程序 我意识到 当我在客户端运行我的应用程序时 客户端可以通过查
  • 传单 - 导入 Geojson - Angular 6

    我尝试将 GeoJson 文件导入到 Angular 的应用程序 6 中的传单中 通过这个解决方案 我的 geojson 是在 leafletmap 中绘制的 但我有这个错误 我无法构建我的应用程序 有人知道一种解决方案吗 错误 TS234
  • 自动调整元素 (div) 大小以适合水平内容

    我尝试谷歌搜索 但没有得到太多结果 我正在构建一个水平轮播 它在浮动的 LI 中显示图像 我想解决的问题是 每次我向轮播添加缩略图 我是延迟加载 时 我都需要重新计算轮播的宽度 以便所有浮动缩略图很好地并排排列 其一 我宁愿不必在 JS 中
  • 如何从普通 JavaScript 中的输入获取对象

    例如 我有 3 个输入
  • Niceedit本地上传图片失败

    我是这样称呼编辑的 new nicEditor buttonList bold italic underline upload iconsPath img nicedit png uploadURI http server com inte
  • Firestore != 查询错误:“”!=”类型的参数无法分配给“WhereFilterOp”类型的参数。ts(2345)

    我的打字稿编译器有问题 此查询出现错误 const xxx admin firestore collection xxx where end timestampDate where end lt timestampDate get 错误 类
  • 使用重复模式捕获正则表达式

    我试图捕获字符串的所有部分 但我似乎无法正确处理 该字符串具有以下结构 1 22 33 中间有运算符的数字 可以有任意数量的术语 我想要的是 1 22 33 1 22 33 但我得到 1 22 33 22 33 我尝试过各种正则表达式 这是

随机推荐

  • es6-module 默认导出导入为未定义

    我不确定我在这里缺少什么 我正在使用 jspm 和 es6 module loader 开发一个项目 我有一个模块定义如下 import hooks from hooks import api from api import tools f
  • 在 Elasticsearch 中删除文件后回收磁盘空间

    当我从 Elasticsearch 中删除文档时 为什么我的 总大小 保持不变 尽管由于没有以前存储的数据而明显小得多 我读过有关索引优化的内容 但我不确定这是什么或如何做到这一点 Thanks 我确信 SO 和 Google 上都有大量与
  • 命令式代码与声明式代码[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我试图理解命令式范例和声明式范例之间的区别 因为我必须对 Visual Basic 进行分类 NET 在不同的范式中 除了面向对象之外
  • 如何使用格式保存 Tkinter 文本小部件的内容

    我在 python 中使用 Tkinter 在文本窗口中显示输出 我发现使用 get 功能我可以从此窗口检索文本内容 但我有用不同背景颜色标记的文本部分 是否可以将内容与这些颜色一起复制到文件 例如 html 或 doc 中 没有对你想要的
  • 使用 scipy、python、numpy 进行非线性 e^(-x) 回归

    下面的代码为我提供了一条最佳拟合线的平坦线 而不是沿着 e x 模型的一条适合数据的漂亮曲线 谁能告诉我如何修复下面的代码以使其适合我的数据 import numpy as np import matplotlib pyplot as pl
  • 使用 Python 打开新窗口时,selenium window_handles 不正确

    我想使用 selenium 和 Python 在一个浏览器中打开多个选项卡 并通过多个选项卡同时抓取实时投注赔率 网站主页生成游戏列表 但是 除非您找到游戏元素并使用 click 该网站是 ajax 密集型 否则无法获取游戏链接 这会在同一
  • Bootstrap Glyphicons 在 IE10 或 FF 中不显示

    我无法在 IE10 或 FF 中显示引导字形图标 我正在使用最新的 bootstrap 3 代码 并以标准方式包含字形 span class glyphicon glyphicon edit span 它们在 Chrome 中工作正常 但在
  • Flash 照片上传 - 从网络摄像头拍摄照片 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Node.js 7 如何将sequelize事务与async/await一起使用?

    Node js 7 及更高版本已经支持 async await 语法 我应该如何在后续事务中使用 async await let transaction try get transaction transaction await seque
  • JSF EL:instanceof 已保留但尚未实现?

    我在 JSF EL 中找到了 instanceof 运算符 但在使用时它会抛出异常 明明是保留了却没有执行 如果还没有比我当前使用的 JSF 1 2 更新的版本 那么它 可能 什么时候可用 关键词instanceof确实在 EL 中保留 参
  • 为什么反编译swf文件时jpexs工具不起作用?

    有人知道如何反编译 SWF 文件吗 我尝试过 JPEXS 和 Sothink SWF Decompiler 但不起作用 我把这个 swf在这个link https drive google com file d 1ehHprPOqR0QnR
  • 在 Python 中倾斜数组

    我有一个 2D 数组 我将使用它保存为灰度图像scipy misc toimage 在此之前 我想将图像倾斜给定角度 像这样进行插值scipy ndimage interpolation rotate 上图只是为了说明倾斜过程 我知道我必须
  • 如何“杀死”Pthread?

    我正在学习 Pthreads 并且想知道杀死这样一个对象的最佳方法是什么 在寻找类似的问题后 我无法找到 明确 的答案 但请随时向我指出任何相关问题 我正在使用一个小型客户端服务器应用程序 其中服务器主线程正在侦听套接字上的客户端连接 每次
  • 减少/折叠幺半群列表,但减少器返回任一

    我发现自己遇到过几次这样的情况 我有一个减速器 组合 fn 如下所示 def combiner a String b String Either String String a b asRight String 它是一个虚拟实现 但 fn
  • WordPress 管理栏未显示在网站前端

    请问有人可以帮我解决这个问题吗 WordPress 管理栏未显示在我网站的前端 公共可见页面 上 它显示我何时在后端登录 即仪表板 用户设置正常 设置为在查看站点时显示管理栏 我尝试停用 然后重新激活 已安装的插件 但仍然没有显示 只是背景
  • 更改 RowLayout SWT Java 中元素的顺序

    有没有办法更改在行布局中创建的元素的顺序 我想将其显示在元素中 首先显示 例如 如果我创建 element1 则 element2 element3 element4 我想看到的布局为 元素4 元素3 元素2 元素1 这意味着最后创建的元素
  • 在桌面应用程序中,类库的连接字符串存储在哪里?我可以在app.config中使用吗?

    我是桌面应用程序开发的新手 目前正在使用分层架构 用户界面 DAL BLL 构建桌面应用程序 在 Web 开发中 我曾经将连接字符串存储在 web config 中 我的类库从那里访问它 请指导我在桌面应用程序中如何以及在何处存储 DAL
  • gdb 不会从外部架构读取核心文件

    我正在尝试在 Linux 桌面上读取 ARM 核心文件 但似乎无法找出我的核心文件 有什么方法可以指示 gdb 我的核心文件是什么类型吗 file daemon daemon ELF 32 bit LSB executable ARM ve
  • Slack Webhook - 获取 Invalid_Payload

    我正在尝试设置 Slack 的 Webhook 但收到 Invalid Payload 错误消息 我浏览过 Stack Slack 和 Github 但找不到我想要的答案 为了保护隐私 其中的 自定义链接 正在使用实际链接 CODE var
  • 当系列没有相同的时间值时,如何在工具提示中显示所有系列

    我有一个显示多个时间序列的图表 不同时间序列不会同时采样 有没有办法在工具提示中显示所有系列 在示例中 您可以看到所有系列都包含在前 2 个点的工具提示中 因为它们是同时采样的 其余点仅包含 1 个系列 var myChart echart