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:折线图 - 工具提示和悬停垂直线 的相关文章

  • 如何检测浏览器是否支持自定义元素

    我正在查看 Modernizr 它应该有助于功能检测 这应该可以帮助确定您的网站是否与给定的 Web 浏览器兼容 但我没有看到任何表明我可以使用它来检测自定义 HTML 的内容我们在内容中创建和定义的元素 如果不是 Modernizr 我如
  • JavaScript onTouch 不工作

    谁能告诉我为什么这个 onTouch 处理程序没有触发 var myDiv document getElementById existingContent var myButton a href log out a myDiv append
  • 使用 vscode 调试器调试 next.js

    我已经使用安装了一个项目创建下一个应用程序 https github com segmentio create next app 我需要使用我的编辑器 vscode 调试服务器端渲染 所以我访问过vscode recipes 如何调试 ne
  • Android 设备上的 PhoneGap 蓝牙插件

    我一直在尝试让 PhoneGap 工作的蓝牙插件 但我似乎不知道哪里出了问题 首先 我的测试设备是 Galaxy S3 GT 19305T 应用程序是使用PhoneGap CLI http docs phonegap com en 3 0
  • 如何重定向到 instagram://user?username={username}

    我的 html 页面上有这个链接 可以在特定用户上打开 Instagram 应用程序 a href Link to Instagram Profile a 我一直在寻找自动运行 url instagram user username USE
  • 如何重置使用 JavaScript 更改的 CSS 属性?

    我的导航按钮的宽度从 100px 增加到 150px 当鼠标悬停在 nav li hover width 150px 但是使用 javascript 我已经做到了 无论选择哪个选项 宽度都将继续为 150px 当选择每个选项时 它会使其他选
  • 使用模数按字母顺序对列表进行排序

    我在获取元素列表并按字母顺序对它们进行排序方面没有任何问题 但我很难理解如何使用模数来做到这一点 更新 这是按我的方式工作的代码 但是 我更喜欢下面提供的答案的可重用性 因此接受了该答案
  • 如何监听 jQuery AJAX 请求?

    以下两种实现 ajaxRequest 1 2 的方法应该是等效的 话说回来 为什么验证回调已执行的单元测试 3 在 1 中成功而在 2 中失败 我应该如何重写测试 3 来监视 2 中的成功回调 如果我尝试stub jQuery ajax使用
  • 从未用 @flow 标记的导入文件中获取类型定义

    TL DR我怎么告诉flow从未声明的导入模块导入类型定义 flow 加长版 流接缝能够从不使用流语法的文件中派生类型 请参阅示例 示例文件 flow js if Math random lt 0 5 var y hello else va
  • 如何将 Google Charts 与 Vue.js 库一起使用?

    我正在尝试使用 Vue js 库使用 Google Charts 制作图表 但我不知道如何添加到 div 这是我尝试做的 这是如何使用普通 javascript 添加图表 这是文档的代码示例 https developers google
  • 跟踪用户何时点击浏览器上的后退按钮

    是否可以检测用户何时单击浏览器的后退按钮 我有一个 Ajax 应用程序 如果我可以检测到用户何时单击后退按钮 我可以显示适当的数据 任何使用 PHP JavaScript 的解决方案都是优选的 任何语言的解决方案都可以 只需要我可以翻译成
  • 在javascript中解析json - 长数字被四舍五入

    我需要解析一个包含长数字的 json 在 java servlet 中生成 问题是长数字被四舍五入 当执行这段代码时 var s x 6855337641038665531 var obj JSON parse s alert obj x
  • Firefox 书签探索未超过 Javascript 的第一级

    我已经编写了一些代码来探索我的 Firefox 书签 但我只获得了第一级书签 即我没有获得文件夹中的链接 e g 搜索引擎 雅虎网站 谷歌网站 在此示例中 我只能访问 Search engines 和 google com 不能访问 yah
  • Javascript 数组到 VBScript

    我有一个使用 Javascript 构建的对象数组 我需要使用 VBScript 读取它 如下例所示 我找不到在 VbScript 代码中循环遍历数组的方法myArray object 这个例子是我的问题的简化 我无法更改页面的默认语言 这
  • Javascript 纪元时间(以天为单位)

    我需要以天为单位的纪元时间 迄今为止 我已经看到过有关如何翻译它的帖子 但几天后就没有了 我对纪元时间很不好 我怎么能得到这个 我需要以天为单位的纪元时间 我将解释为您想要自纪元以来的天数 纪元本身是第 0 天 或第 1 天的开始 无论您如
  • Safari 支持 JavaScript window.onerror 吗?

    我有一个附加到 window onerror 的函数 window onerror function errorMsg url line window alert asdf 这在 firefox chrome 和 IE 中工作正常 但在 s
  • 如何更改此 jquery 插件的时区/时间戳?

    我正在使用这个名为 timeago 的插件 在这里找到 timeago yarp com 它工作得很好 只是它在似乎不同的时区运行 我住在美国东部 费城时区 当我将准确的 EST 时间放入 timeago 插件时 比如 2011 05 28
  • 为什么 jquery 没有检测到单选按钮未被选中的情况? [复制]

    这个问题在这里已经有答案了 可能的重复 JQuery radioButton change 在取消选择期间不会触发 https stackoverflow com questions 5176803 jquery radiobutton c
  • 将 MQTTNet 服务器与 MQTT.js 客户端结合使用

    我已经启动了一个 MQTT 服务器 就像this https github com chkr1011 MQTTnet tree master例子 该代码托管在 ASP Net Core 2 0 应用程序中 但我尝试过控制台应用程序 但没有成
  • 使用 Ajax 请求作为源数据的 Jquery 自动完成搜索

    我想做的事 我想使用 jquery 自动完成函数创建一个输入文本字段 该函数从跨域curl 请求获取源数据 结果应该与此示例完全相同 CSS 在这里并不重要 http abload de img jquerydblf5 png http a

随机推荐

  • 如何使用 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