如何更改 d3 图例条目间距/对齐方式

2024-04-14

我有这样一个传说:

如您所见,每个图例条目的宽度相同。相反,我希望每个图例条目的宽度根据条目符号和文本的宽度而变化。最终,我希望前导条目文本的末尾与后续条目符号的开头之间的距离相同。换句话说,我希望“OA”和加号之间的距离与“OI”和菱形以及“RARC”和正方形之间的距离相同。我需要它基于像素(字符串长度不够)。我一直在尝试各种各样的事情,但还没有成功。

这是我的代码:

        var legendData = [["OA", "yellow", "circle"], ["OI", "blue", "cross"], ["RARC", "green", "diamond"], ["CAPE", "red", "square"], ["Other", "black", "triangle-down"]];

        this.svg.selectAll('.legend').remove() //remove remnants of previous legend so new legend has clean slate...eliminates overlays during resizing

        var legend = this.svg.append('g')
            .attr("class", "legend")
            .attr("height", 0)
            .attr("width", 0)
            .attr('transform', 'translate(' + (ScatterChart.Config.margins.left + (width * .008)) + ',' + (height += .40 * ScatterChart.Config.margins.bottom) + ')');

        var legendRect = legend
            .selectAll('g')
            .data(legendData)
            ;

        var labelLength = 0
        var labelLengthPrevious = 0

        var legendRectE = legendRect.enter()
            .append("g")
            .attr("transform", function (d, i) {
                //labelLength = labelLengthPrevious //Need to figure out pixel lengths
                //labelLengthPrevious += (d[0].length) + 50
                //return 'translate(' + labelLength + ', ' + 0 + ' )';  // y is constant and x growing
                return 'translate(' + (i * (.15 * width)) + ', ' + 0 + ' )';  // y is constant and x growing
            })
            ;

        legendRectE
            .append('path')
            .attr("d", d3.svg.symbol().type((d) => {
                return d[2]
            }
            ).size((d3.min([height, width]) * ScatterChart.Config.axisFontMultiplier) * (d3.min([height, width]) * ScatterChart.Config.symbolSizeMultiplier)))
            .style("fill", function (d) {
                return d[1];
            })
            .attr('stroke', 'black')
            ;

        //This asserts legendRectE as a node...I think. I do this so I can use the width and height measurements of legendRectE.
        var node: SVGElement = <SVGElement>legendRectE.node()

        legendRectE
            .append("text")
            .attr("x", function (d) {
                return node.getBoundingClientRect().width
            })
            .attr("y", function (d) {
                return node.getBoundingClientRect().height / 2.25
            })
            .text(function (d) {
                return d[0];
            })
            .style('font-size', function () { return d3.min([height, width]) * ScatterChart.Config.axisFontMultiplier + "px" })
            ;

我认为答案与这一行有关:return 'translate(' + (i * (.15 * width)) + ', ' + 0 + ' )'; // y is constant and x growing。现在,它只是通过将指数乘以图表宽度的 15% 来向右移动。我想我需要以某种方式替换的宽度legendRectE (or of legendRect or legend)代替(I * (.15 * width))。我不知道该怎么做。

你可以看到我使用下面的方法来获取宽度legendRectE稍后在代码中:var node: SVGElement = <SVGElement>legendRectE.node(), 其次是node.getBoundingClientRect().width.

node.getBoundingClientRect().width给我一个宽度值,您现在看到它正在使用,但是当我使用相同的方法来确定我提到的翻译的值时,它会令人窒息;当我使用时legendRect or legend代替legendRectE我只得到“0”。

我想我可以像这样编辑转换函数:

    var legendRectE = legendRect.enter()
        .append("g")
        .attr("transform", function (d, i) {
             var node: SVGElement = <SVGElement>legendRectE.node()
             return 'translate(' + node.getBoundingClientRect().width + ', ' + 0 + ' )';  // y is constant and x growing
        })
        ; 

显然,我错了。有什么想法/建议吗?

附注我正在使用 d3 v3.5。


挑战在于(据我所知)在最初附加元素时很难确定变换,因为宽度未知。但是您可以在附加所有图例条目后返回并计算每个图例条目的宽度,然后相应地重新定位图例条目。

下面的代码片段将所有内容置于彼此之上以开始,然后计算svg每个图例的宽度g using getBBox。然后,使用 d3.sum 计算附加在其之前的每个元素的宽度(因此应该位于其左侧),并将翻译值相应地设置为这些宽度的总和。

可能可以稍微清理一下,速度有点快。如果在正确定位元素之前存在延迟,则透明地附加它们,然后在定位后将它们淡入可能是一个优雅的(视觉上,不太编程)解决方案(或最初将它们附加到视图框之外)。

d3v4:

var data = ['short text','much longer text','the longest text passage','short text'];

var svg = d3.select('body')
  .append('svg')
  .attr('width',800)
  .attr('height',200);
  
var groups = svg.selectAll('g')
 .data(data)
 .enter()
 .append('g');
 
var rect = groups.append('rect')
  .attr('fill',function(d,i) { return d3.schemeCategory10[i];})
  .attr('height',30)
  .attr('width',30);

var text = groups.append('text')
  .attr('y', 20)
  .attr('x', 35)
  .text(function(d) { return d; });
  
// Now space the groups out after they have been appended:
var padding = 10;
groups.attr('transform', function(d,i) { 
  return "translate("+(d3.sum(data, function(e,j) {
    if (j < i) { return groups.nodes()[j].getBBox().width; } else return 0; }) + padding * i) + ",0)";
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>

d3v3:

var data = ['short text','much longer text','the longest text passage','short text'];

var svg = d3.select('body')
  .append('svg')
  .attr('width',800)
  .attr('height',200);
  
var groups = svg.selectAll('g')
 .data(data)
 .enter()
 .append('g');
 
var color = ["orange","red","purple","green"];
 
var rect = groups.append('rect')
  .attr('fill',function(d,i) { return color[i];})
  .attr('height',30)
  .attr('width',30);

var text = groups.append('text')
  .attr('y', 20)
  .attr('x', 35)
  .text(function(d) { return d; });
  
// Now space the groups out after they have been appended:
var padding = 10;
groups.attr('transform', function(d,i) { 
  return "translate("+(d3.sum(data, function(e,j) {
    if (j < i) { return groups[0][j].getBBox().width; } else return 0; }) + padding * i) + ",0)";
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何更改 d3 图例条目间距/对齐方式 的相关文章

  • SVG/XML 中有一些innerHTML 替代品吗?

    在 HTML 中 我可以通过提供字符串形式的模板来构建一个简单的模板系统 替换其中的某些部分 然后使用innerHTML到某个容器 var templ span myText span var newContent templ replac
  • 如何在 Imagick 中读取 SVG 字符串?

    我有一个包含 svg 元素标记的字符串
  • Android Vector Drawable 不支持。如何修复它?

    尝试从 AndroidStudio 2 2 Ubuntu 14 04 的本地 svg 文件生成矢量资源时出现此错误 Could not generate a preview In icon svg ERROR line 6
  • 在 SVG 中绘制 DOM 对象时如何在 Canvas 中使用 Google 字体?

    根据 Mozilla 的文档 您可以在 Canvas 上绘制复杂的 HTML 例如this https developer mozilla org en US docs Web API Canvas API Drawing DOM obje
  • D3:如何在Groups of Force布局节点上绘制多个凸包?

    我试图在力布局中的所有组上绘制凸包 但我只画出了一半的凸包 当 D3 尝试绘制其余的船体时 控制台返回错误 元素尚未创建 然而 当我检查控制台中的 groups 变量时 所有组数据都在那里 x y 数据都设置得很好 见下图 我什至尝试在ti
  • svg 圆不是用 javascript 绘制的

    我一直在尝试使用 HTML 中的 javascript 来进行 svg 操作的 hello world 我编写了下面的代码 虽然它生成了正确的 html 但我在浏览器中没有看到任何输出 也没有看到任何错误
  • IPython Notebook Markdown——允许的 HTML 标签列表是什么以及如何更改它们?

    我正在使用 IPython Notebook markdown 创建一个文档 它确实允许一些 HTML 例如 img 例如但我添加了包含 SVG 文件 但它不会显示在 IPython Notebook 输出中 我仔细检查了 IPython
  • 内联 svg 不显示在 xhtml 中

    我创建了一个带有内联 SVG 的 XHTML 文件 当测试为 XHTML 时 它不会显示 但当测试为 HTML 时 它会显示 我已经搜索过互联网并相信我已经指定了正确的名称空间等 但是 我很困惑为什么它没有显示 请帮助我理解我做错了什么 注
  • 将元素添加到 D3 圆包节点

    我正在尝试制作一个可缩放的圆形包装图 我希望每个子圆圈包含一个较小的图表 该图表始终具有相同的结构 即 4 列 只有条形的高度会改变 我尝试添加一个简单的rect到目前为止我的图表 但矩形没有添加到圆圈中并且是静态的 JS var marg
  • 仅当现有填充颜色为特定值时才填充 SVG

    我正在使用此代码来更改 SVG 对象的填充颜色 它可以工作 function g mouseenter function path rect circle this attr fill 00C8C8 但是 我只想在现有填充颜色具有特定值时更
  • 使用 jQuery 修改 svg 文件

    我有一个 svg 文件 其中包含一些形状和一些文本 我想在运行时修改 svg 以便某些形状可以更改颜色 某些文本可以更改其内容 假设我的外部 svg 文件中只有两个元素 圆圈 1 具有该 id 的蓝色实心圆圈 text1 包含该 id 的
  • 如何以 JavaScript 编程方式获取旋转的 svg 文本边界

    我正在动态渲染 SVG 图像并创建旋转文本 如果旋转的文本与其他文本重叠 我需要删除该文本 但我无法测量旋转的文本来创建边界并检查下一个标签文本区域 我创建了 3 个 SVG 元素来解释 SVG 1 显示重叠的文本 SVG 2 显示重叠的旋
  • IE11 元元素破坏 SVG

    我已将 SVG 文件数据直接嵌入到我的 html 中 它在 Chrome 和 Firefox 中显示 但在 IE11 中根本不显示 SVG 的 Pastebin 链接是http pastebin com eZpLXFfD http past
  • 在 d3 中应用转换时出现错误

    我正在尝试对我在 d3 中设计的条形图应用一些过渡效果 这是我的代码 svg selectAll bar data data enter append g attr class bar append rect attr rx barRadi
  • 如何使用 Selenium webdriver 测试对 SVG 对象的点击?

    我正在尝试编写代码来检查单击 SVG 对象的功能 例如此 URL 上的美国州 http www amcharts com svg maps map usa 这可行 但是有更好的方法吗 不需要物理移动鼠标的东西 robert new Robo
  • 限制在三角形内

    我正在寻找一段通用代码 javascript 它可以与 jquery UI 一起使用来限制三角形内 div 的移动 拖动 与此类似 http stackoverflow com questions 8515900 how to constr
  • 在 Java 中使用 Batik 检查和删除 SVG 中的属性

    这个问题基本上说明了一切 如何检查 SVG 是否具有 viewBox 属性 我正在使用蜡染库 我需要这个 因为我需要 至少 通知用户有一个 viewBox 属性 我可以删除它吗 使用 org w3c dom 类 您可以按照以下方式做一些事情
  • Safari 滚动条和 SVG

    问题 Safari 无法正常工作 而是使用滚动条渲染我的 SVG 图像 问题的改进版本 如何填充设定的宽度并根据 Safari 中的宽高比计算高度 感谢普罗格兹 相关代码 SVG File viewBox 0 0 800 800 未指定高度
  • GeoJson 世界数据库 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在开发一个项目 需要使用 d3 js 显示国家和城市的地图 实际上 D3支持GeoJson格式 通常
  • 如何使 d3 饼图响应式?

    我有一个 PIE 图表 它工作正常 但我无法使其具有响应能力和可调整大小 我需要它与移动浏览器和 iPad 等兼容 div div

随机推荐

  • Kubernetes Istio 入口网关始终响应 503

    我正在使用 Helm 配置 Istio 在这里你可以找到我的istio config yaml global proxy accessLogFile dev stdout resources requests cpu 10m memory
  • 为什么当参数作为参数传递时 sp_executesql 运行速度变慢

    查询1 快如闪电 sp executesql select from tablesView where Id 1 vs 查询2 太慢 sp executesql select from tablesView where Id Id N Id
  • Chrome 扩展:在 Javascript 中检测新的一天(更改的日期)?

    我知道没有新的一天 或小时 分钟 的事件侦听器 但在我的 Chrome 扩展中 我需要知道新的一天何时开始 这意味着我必须使用 setInterval 函数来找出这一天何时发生变化 但是 我不确定间隔值使用什么 10 秒 还是 10 分钟
  • 如何使用 pandas 将 200.13K 和 1.2M 等数字字符串转换为整数? [复制]

    这个问题在这里已经有答案了 我的 df 中有一个列 Vol 其中的值以 K 和 M 结尾 分别表示数千和数百万 这些值是 dtype 中的 对象 我需要将它们转换为 双精度 Example for the column what I nee
  • Firebase身份验证:如何获取当前用户的密码?

    我是新来的火力地堡身份验证 所以 我正在创建一个带有配置文件的基本应用程序 我做了一个活动来编辑用户的基本信息 例如DisplayName and Email 我不想添加更改密码的功能 但首先 我不想检查当前用户的密码并将其与String从
  • 如何在linux中查找包含字符串的行[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我在 Linux 中有一个文件 我想显示该文件中包含特定字符串的行 该怎么做 通常的方法是使用grep https linux die n
  • Android 4.0 添加日历和事件

    我想在android 4 0及以上版本的设备中添加日历事件 目前我正在使用以下代码添加事件 if android os Build VERSION SDK INT lt 7 Uri calendars Uri parse content c
  • 如何使用摄像头直播作为活动背景?

    我正在尝试制作一个应用程序 其中我需要使用相机实时馈送作为背景 我知道这是一件愚蠢的事情 但无能为力 这是客户的要求 我尝试过使用SurfaceView但到目前为止还没有成功 到目前为止 我在 Stack Overflow 上发现的更多内容
  • 从conda为pip3创建requirements.txt

    我通常使用 conda 来管理我的环境 但现在我正在进行的项目需要比我的笔记本电脑更多的马力 因此 我尝试使用我大学的配备新英特尔至强处理器的工作站 但我没有管理员权限 而且工作站没有 conda 所以我被迫使用 virtualenv 和
  • 公共运算符 new、私有运算符删除:使用 new 时出现 C2248“无法访问私有成员”

    类具有重载运算符new and delete new是公开的 delete是私人的 在构造此类的实例时 出现以下错误 pFoo new Foo bar example cpp 1 错误 C2248 Foo operator delete 无
  • Android IAB 错误 - 需要身份验证

    我在我的应用程序中测试 In App Billing v3 时遇到问题 我无法使用测试帐户购买任何东西 它总是向我显示一个 Play 商店对话框 Error Authentication is required You must log i
  • Clang 和二进制折叠表达式 — 空参数包的诅咒

    具体来说 Clang 3 6 0 目前由 Coliru 托管 所有这些片段都是从以下位置调用的 int main foo std cout lt lt n n foo 1 2 3 以下代码 template
  • XAML 编辑器的黑色背景

    我目前正在开发一个具有白色文本和透明背景的用户控件 不幸的是 因为 VS2010 中的 XAML 设计视图具有白色背景 所以我看不到我正在设计的任何内容 我已经浏览了我能想到的所有设置对话框 但一直无法找到更改 XAML 设计器背景颜色的设
  • Android:多次播放 AudioTrack 会导致崩溃

    我正在尝试使用 AudioTrack 播放音频缓冲声音 wav 请参阅下面的代码 我需要在Thread下调用这个函数来支持同时播放 在线程下很好 正常播放声音效果很好 但是 如果我连续使用 AudioTrack 执行播放声音 即在完成第一个
  • 点冻结与点列表

    为什么pip list生成比以下更全面的列表pip freeze pip list feedparser 5 1 3 pip 1 4 1 setuptools 1 1 5 wsgiref 0 1 2 pip freeze feedparse
  • 对于大文件,使用 dataURI 创建 iframe 失败,有解决方法吗? [复制]

    这个问题在这里已经有答案了 function openNewWindow strPreviewId let newWindowViewer window open var index mapPreviewIdWithFile strPrev
  • 同一浏览器中不同用户的 Cookie

    网站页面上有一些下拉菜单 用户只有在经过身份验证后才能访问此页面 我想将此值保存到 cookie 中 并在用户返回我的网站时将其设置回下拉菜单 将当前选择的下拉选项值保存到 cookie 并稍后检索它不是问题 但是 如果我由另一个用户在同一
  • 如何在 LaTeX 中扩展文章文档类?

    我真的不需要对默认文章文档类进行大量更改 我想要的只是 重新定义页边距 我希望它们在所有页面上都相同 但与默认值不同 使用扉页 在标题页上添加更多元素 title author and date对我来说还不够 我想要company和公司lo
  • Android 版本是否有最小堆大小?

    许多帖子都谈到了 Android 堆大小 到目前为止我发现最大堆大小的唯一共同点是它至少为 16MB 但这是自 API 3 以来的限制 为了使用更多内存 人们会建议使用 NDK 或任何超出 正常 Android 开发的东西 是否有任何 An
  • 如何更改 d3 图例条目间距/对齐方式

    我有这样一个传说 如您所见 每个图例条目的宽度相同 相反 我希望每个图例条目的宽度根据条目符号和文本的宽度而变化 最终 我希望前导条目文本的末尾与后续条目符号的开头之间的距离相同 换句话说 我希望 OA 和加号之间的距离与 OI 和菱形以及