D3.js:折线图 - 工具提示和悬停垂直线

2024-02-20

我一直在研究使用 D3.js 构建的交互式折线图。一次悬停时,我希望工具提示以垂直线显示。垂直线效果很好,但是,我遇到了与工具提示相关的问题。工具提示位置不在图表上,我只获取第一个数据元素。

这是我的代码:

 margin = {
                    top: 20,
                    right: 20,
                    bottom: 20,
                    left: 50
                };
        var width = Math.max(250, Math.min(700, d3.select("#content").width- margin.left - margin.right)),
                    height = 500;

        var vis = d3.select("#line_chart").append("svg")
                            .attr("width", width + margin.left + margin.right)
                            .attr("height", height + margin.top + margin.bottom);

        max_x = 0, max_y = 0, min = 100;

        d3.csv("line.csv", function(error, data) {


                for(i=0; i < data.length; i++){
                    max_y = Math.max(max_y, data[i].number);
                    max_x = Math.max(max_x, data[i].class);
                    min = Math.min(min, data[i].class);
                }


                    xScale = d3.scale.linear().range([margin.left, width - margin.right]).domain([min, max_x]),

                    yScale = d3.scale.linear().range([height - margin.top, margin.bottom]).domain([0, max_y]),

                    xAxis = d3.svg.axis()
                    .scale(xScale),

                    yAxis = d3.svg.axis()
                    .scale(yScale)
                    .orient("left");

                vis.append("svg:g")
                    .attr("class", "x axis")
                    .attr("transform", "translate(0," + (height - margin.bottom) + ")")
                    .call(xAxis);

                vis.append("svg:g")
                    .attr("class", "y axis")
                    .attr("transform", "translate(" + (margin.left) + ",0)")
                    .call(yAxis);

                var lineGen = d3.svg.line()
                    .x(function(d) {
                        return xScale(d.class);
                    })
                    .y(function(d) {
                        return yScale(d.number);
                    })
                    .interpolate("basis");

                var pth = vis.append('svg:path')
                    .attr('d', lineGen(data))
                    .attr('stroke', '#000')
                    .attr('stroke-width', 3.5)
                    .attr('fill', 'none');

                var totalLength = pth.node().getTotalLength();

                pth
                  .attr("stroke-dasharray", totalLength + " " + totalLength)
                  .attr("stroke-dashoffset", totalLength)
                  .transition()
                    .duration(2400)
                    .ease("linear")
                    .attr("stroke-dashoffset", 0);

                //Line chart mouse over 
                var hoverLineGroup = vis.append("g")
                                    .attr("class", "hover-line");

                var hoverLine = hoverLineGroup
                    .append("line")
                        .attr("stroke", "#000")
                        .attr("x1", 10).attr("x2", 10) 
                        .attr("y1", 0).attr("y2", height); 

                var hoverTT = hoverLineGroup.append('text')
                   .attr("class", "hover-tex capo")
                   .attr('dy', "0.35em");

                var cle = hoverLineGroup.append("circle")
                    .attr("r", 4.5);

                var hoverTT2 = hoverLineGroup.append('text')

                   .attr("class", "hover-text capo")
                   .attr('dy', "0.35em");

                hoverLineGroup.style("opacity", 1e-6);

                var rectHover = vis.append("rect")
                  .data(data)
                  .attr("class", "overlay")
                  .attr("width", width)
                  .attr("height", height);

                rectHover  
                    .on("mouseout", hoverMouseOff)
                    .on("mousemove", hoverMouseOn);

                function hoverMouseOn(d) {

                      var mouse_x = d3.mouse(this)[0];
                      var mouse_y = d3.mouse(this)[1];
                      var graph_y = yScale.invert(mouse_y);
                      var graph_x = xScale.invert(mouse_x);

                      hoverTT.text("Marks: " + Math.round(graph_x * 100)/100); 
                      hoverTT.attr('x', mouse_x + 10);
                      hoverTT.attr('y', yScale(d.class));


                      hoverTT2.text("Frequency: " + Math.round(d.number * 100)/100)
                        .attr('x', mouse_x + 10)
                        .attr('y', yScale(d.class) +15);

                      cle
                        .attr('x', mouse_x)
                        .attr('y', mouse_y);


                      hoverLine.attr("x1", mouse_x).attr("x2", mouse_x)
                      hoverLineGroup.style("opacity", 1);

                }

                function hoverMouseOff() {
                        hoverLineGroup.style("opacity", 1e-6);
                };

            });
        }

数据:

class,number
25,1
30,7
35,11
45,13
50,21
55,23
60,30
65,41
75,39
80,24
85,14
90,4
95,8
100,2

我无法弄清楚问题是什么。

我该如何解决这个问题?

提前致谢。

编辑:这是工作代码:https://jsfiddle.net/kan83q0m/1/ https://jsfiddle.net/kan83q0m/1/


在您的hoverMouseOn方法中,变量d未定义。您需要使用 d3.bisector 来查找最近的数据点,如下所示:

var bisectDate = d3.bisector(function(d) { return d.class; }).left;

var mouseDate = xScale.invert(mouse_x);
var i = bisectDate(data, mouseDate);

var d0 = data[i - 1]
var d1 = data[i];
var d = mouseDate - d0[0] > d1[0] - mouseDate ? d1 : d0;

另外,我将 mousemove 侦听器放在“vis”而不是“rectHover”上:

        vis  
            .on("mouseout", hoverMouseOff)
            .on("mousemove", hoverMouseOn);

并使用 d.number 而不是 d.class 作为 y 值。如果你希望工具提示始终在线变得有点复杂 https://stackoverflow.com/questions/11503151/in-d3-how-to-get-the-interpolated-line-data-from-a-svg-line/39442651#39442651. 这是一个工作小提琴。 https://jsfiddle.net/ringstaff/unyd6q29/2/

将工具提示放在鼠标坐标上可能会更容易就像这个小提琴一样。 https://jsfiddle.net/ringstaff/dL1qp1t6/

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

D3.js:折线图 - 工具提示和悬停垂直线 的相关文章

  • 使用 AJAX 来回发送信息

    使用 post 你可以向服务器发送信息 但是当你需要从服务器接收信息时怎么办呢 信息如何从可以由 php 变量保存的方式变为可以由 javascript 变量保存的方式 反之亦然 这与您的问题更相关 http docs jquery com
  • javascript switch/case :比较类型吗? [复制]

    这个问题在这里已经有答案了 可能的重复 在 Javascript switch 语句中进行严格比较是否安全 https stackoverflow com questions 6989902 is it safe to assume str
  • 如何监控浏览器中发出的所有自定义事件?

    我想监视网络浏览器中触发的所有自定义事件 任何标准浏览器都可以 需要明确的是 我知道您可以附加事件处理程序来查看何时触发 通常 事件 但如何可靠地检测嵌入对象或 jQuery 脚本是否触发自定义事件 我可以重构浏览器源代码来挂钩事件循环 但
  • 使用shinyjs通过javascript在闪亮的应用程序中操作现有的Leaflet地图

    我有一个闪亮的应用程序 其中包含现有的传单地图 我希望能够在渲染后使用自定义 javascript 通过shinyjs包裹 一个最小的例子如下 app R packages library dplyr library leaflet lib
  • 从 Angular 6 服务中绑定图像

    我有一个端点 它根据某些参数为我提供图像 这不是一个图像网址 而是一个普通图像 因此 当我到达邮递员中的端点时 作为响应 我收到一张图像 JPG 我是否可以在变量中接收该图像并将其绑定到 HTML 标签中 所有问题都有将图像 url 映射到
  • 将参数传递给 jquery 单击事件中的回调函数[重复]

    这个问题在这里已经有答案了 直接进入正题 我有一个 jquery 事件监听器 如下所示 number click printNumber 和一个回调函数 function printNumber number console log num
  • 使用 JavaScript 填写 PDF 表单

    这就是我所拥有的 用户填写很长的 html 表单 用户获取下载不同 pdf 的链接 这是可填写的表格 链接是使用 javascript 生成的 用户单击链接 生成 url 使用用户之前提交的数据 在表单中处理数据并完成字段 这是在表单内使用
  • 如何在 Jest 测试中模拟 StatusBarManager.getHeight?

    我正在使用 expo 34 并且反应本机用户界面库 https www npmjs com package react native ui lib来自 wix 并且在为我的组件设置笑话测试时遇到问题 问题看起来出现在link https g
  • 在 Javascript 中,使用 var foo = function foo(i) { ... } 的动机或优点是什么?

    我在答案中看到 在Javascript中 为什么要写 var QueryStringToHash function QueryStringToHash query https stackoverflow com questions 3233
  • 为什么 JSON.stringify() 接受 Date 对象?

    至少在 Firefox 中 您可以对 Date 对象进行字符串化 gt gt gt JSON stringify now new Date now 2012 04 23T18 44 05 600Z 这是有效的 因为 在 Firefox 中
  • jQuery UI 对话框使用 setTimeout 自动关闭

    我试图让对话框在打开后三秒自动关闭 我尝试过以下方法 setTimeout mydialog dialog close 3000 这是在上下文中 acknowledged dialog dialog height 140 modal tru
  • contenteditable 在 safari 中不起作用,但在 chrome 中起作用

    我有一个奇怪的问题 这在 chrome 中按预期工作 但在 safari 中它只会发光 但不会对按键输入做出反应 这是触发文本版本的方法 var namebloc event currentTarget find column filena
  • 如何正确关闭 Node.js Express 服务器?

    我需要在收到回调后关闭服务器 auth github callback网址 与平常一样HTTP API http nodejs org docs latest api http html关闭 服务器目前支持server close call
  • Django 模板变量从 {% for %} 循环到 Javascript

    这是一个迭代记录的 Django 模板 每条记录都包含一个由 JS 函数填充的 div 为了让 JS 知道要做什么 它需要从每次 for 循环迭代中获取一个变量并使用它 我不知道具体如何实现这一目标或是否可能 我不知道 也许记录在单独的 J
  • 检测 JavaScript 中的焦点丢失

    我希望能够检测 JavaScript 中任意元素何时失去焦点 因此我可以构建一个类似于 jEdit 的内联编辑工具 我不能依赖 jQuery 来实现这个库 所以我需要一个本机方法来完成它 我查看了 onblur 这似乎是正确的事情 但 MD
  • 自动调整元素 (div) 大小以适合水平内容

    我尝试谷歌搜索 但没有得到太多结果 我正在构建一个水平轮播 它在浮动的 LI 中显示图像 我想解决的问题是 每次我向轮播添加缩略图 我是延迟加载 时 我都需要重新计算轮播的宽度 以便所有浮动缩略图很好地并排排列 其一 我宁愿不必在 JS 中
  • 是否可以从 webpack 中的文件名中删除特殊字符?

    长话短说 我的资产文件名中不能包含某些字符 例如连字符 我没有运气通过解析 webpack 文档来弄清楚是否可以使用正则表达式或类似的东西重命名文件 这样我就可以从我无法控制源文件名的 3rd 方包中删除任何连字符 我的超级天真的例子是这样
  • router.navigate 使用查询参数 Angular 5

    我在使用查询参数路由到路由时遇到问题我有一个像这样的函数 goToLink link this router navigate link split 0 queryParams this sortParams link 和这个功能 sort
  • Javascript 替换为正则表达式无法正常工作

    我正在尝试使用正则表达式验证名称 正则表达式阻止用户连续输入 2 个空格或点 这是我的代码 function test input var regex A Za z 0 1 s 0 1 input value input value rep
  • 网页执行回发时如何停止在注册表单上?

    我正在做我的最后一年的项目 其中 我在一页上有登录和注册表单 WebForm 当用户点击锚点时Sign Up下拉菜单ddlType 隐藏 和文本框 txtCustName txtEmail and txtConfirmPassword 显示

随机推荐

  • 如何使用 VBA 将 & 符号从 Excel 文件写入 XML 文件?

    首先 对于 VBA 来说 我是一个完全的新手 但不幸的是我被抛弃了这段代码 我必须处理它 该应用程序的作用是复制 Excel xlsm 文件中的信息并将其粘贴到 XML 文件中以供进一步处理 问题是 一切都进行得很顺利 直到我在 Excel
  • 关于 Angular 中的位置更改

    有没有办法检测 AngularJS 中的全局位置变化 而不仅仅是单个控制器 我的目标是检测每个位置变化 或者有什么有效的方法来观察 window location href 的变化 routeChangeSuccess 据我了解仅适用于单个
  • ByteBuffer.wrap(byte[]) 会导致长时间运行的应用程序内存泄漏吗?

    我试图在网上搜索 但没有找到答案 基于java doc http docs oracle com javase 7 docs api java nio ByteBuffer html wrap byte 5B 5D ByteBuffer w
  • HasResolution 类型类

    我刚刚查了一下HasResolution 类型类 https hackage haskell org package base 4 10 1 0 docs Data Fixed html t HasResolution它有一个单一的方法 r
  • 为什么 .NET 中的多维数组比普通数组慢?

    Edit 我向大家道歉 当我实际上想说 多维数组 时 我使用了术语 锯齿状数组 如下面的示例所示 对于使用了错误的名字 我深表歉意 我实际上发现锯齿状数组比多维数组更快 我已经添加了锯齿状阵列的测量值 I was trying to use
  • 带棱镜的 AutoWirePartialView 不起作用或使用不当?

    我正在尝试使用棱镜7 1AutoWirePartialView绑定一个PartialView到它的 viewModel 但是 绑定不起作用 或者至少将 viewModel 设置为PartialView似乎不起作用 它仍然具有页面的 Bind
  • 当用户编辑字段中的值时,自定义 DatePicker 作为首选项不会保留值

    我创建了一个 DatePickerPreference 即我扩展了 DialogPreference 并在内部创建了一个 DatePicker 对象 并且让它几乎完美地工作 当您单击向上和向下箭头时 它会更改值并保存您选择的值 但是 如果您
  • OpenGL/GLUT 中的鼠标拖动对象[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我一整天都在寻找简单程序的教程或示例代码 单击对象 例如 2D 矩形 然后当您按住并移动鼠标时 对象会跟随鼠标 然后释放鼠标时 对象仍保留
  • 如何在运行时更改语言而不会出现布局问题

    我有一个 winforms 应用程序 用户必须能够在运行时更改语言 为了概括该开关并避免必须对控件名称进行硬编码 我尝试了以下扩展 internal static void SetLanguage this Form form Cultur
  • 如何在 Windows 10 C# 通用应用程序中使用 C++ 类? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想在 Windows 10 C 通用应用程序中执行 cpp 类的方法 由于我是 Windows 应用程序开发和 C 的新手 所以我可
  • 如何使用cmake在android studio中添加外部库?

    我正在尝试使用 cMake 将 live555 so 和 h 文件与 Android 项目链接 如果我不使用绝对路径 则会出现错误 My cMake file cmake minimum required VERSION 3 4 1 inc
  • 使用 jQuery Sortable() 选择多个项目?

    我需要在 jquery 可排序容器中同时拖动多个项目 在本例中 它是应用了 sortable 行为的父 div 内的一系列嵌套 div 有什么建议么 如果您询问是否可以选择多个项目 例如在一个实例中选择 1 3 和 7 在另一个实例中选择
  • 在Django通道中执行数据库查询

    我正在尝试创建一个非常简单的系统 用户为了使用消费者 需要在 WS url 中输入密钥 例如 ws 127 0 0 1 8000 main key KEY 一旦消费者被调用 Django Channels 需要执行一个非常简单的数据库查询来
  • Objective C:如何通过程序从一个选项卡栏切换到另一个选项卡栏

    我的标签栏控制器中有 5 个不同的标签 我的目的是能够通过代码从一个选项卡栏进行切换 例如 我当前位于应用程序的第五个选项卡中 当我单击 完成 按钮时 应用程序应将我的视图切换到属于第一个选项卡的 rootview 控制器 关于我如何做到这
  • SlickGrid 中的额外列

    即使没有垂直滚动条 SlickGrid 始终在标题的最右侧保留一点空间 这个额外的空间看起来就像一个额外的列 我不想要这个额外的空间 我没有找到 SlickGrid 组件的任何公开 API 来删除它 我在里面看到过自动调整列大小 Slick
  • 两个大文件彼此的平行余弦相似度

    我有两个文件 A 和 B A has 400 000 lines each having 50 float values B has 40 000 lines having 50 float values 对于 B 中的每一行 我需要在 A
  • Python:字典列表,如何获取列表中多个项目的特定键的值?

    我有一个字典列表 例如 dict list key1 dict1 value1 key2 dict1 value2 key3 dict1 value3 key1 dict2 value1 key2 dict2 value2 key3 dic
  • 每行创建多边形并保留列

    早上好 下午好或晚上好 我已将一些位置数据分组到 1 小时的分组中 对于每个我都提取了最小的纬度和经度 它看起来像这样 df lt ID time bin count lat lon maxlat minlat maxlon minlon
  • nginx 连接到 .sock 失败(13:权限被拒绝)- 502 错误网关

    我正在使用 nginx uwsgi django 在 centos7 上部署我的第一个站点 它们在测试中单独工作得很好 但我在尝试将它们连接在一起时遇到了 502 bad gateway var log nginx error log 文件
  • D3.js:折线图 - 工具提示和悬停垂直线

    我一直在研究使用 D3 js 构建的交互式折线图 一次悬停时 我希望工具提示以垂直线显示 垂直线效果很好 但是 我遇到了与工具提示相关的问题 工具提示位置不在图表上 我只获取第一个数据元素 这是我的代码 margin top 20 righ