javascript - 如何根据数据点索引更改元素绘制顺序?
问题描述
我正在为我在 d3.js 数据可视化中使用的数据的每个数据点绘制几个元素。这会根据数据创建一个简单的项目列表。它输出以下内容:
<div>
<p>[Title of datapoint 1]</p>
<svg>[SVG using datapoint 1]</svg>
</div>
<div>
<p>[Title of datapoint 2]</p>
<svg>[SVG using datapoint 2]</svg>
</div>
<div>
<p>[Title of datapoint 3]</p>
<svg>[SVG using datapoint 3]</svg>
</div>
<div>
<p>[Title of datapoint 4]</p>
<svg>[SVG using datapoint 4]</svg>
</div>
<div>
<p>[Title of datapoint 5]</p>
<svg>[SVG using datapoint 5]</svg>
</div>
对于大多数人来说,这正是他们想要的。
但是,我想要实现的是能够更改绘图顺序,例如,每个偶数数据点都应该以 SVG 标记开头并以 p 标记结尾。看起来像这样:
<div>
<p>[Title of datapoint 1]</p>
<svg>[SVG using datapoint 1]</svg>
</div>
<div>
<svg>[SVG using datapoint 2]</svg>
<p>[Title of datapoint 2]</p>
</div>
<div>
<p>[Title of datapoint 3]</p>
<svg>[SVG using datapoint 3]</svg>
</div>
<div>
<svg>[SVG using datapoint 4]</svg>
<p>[Title of datapoint 4]</p>
</div>
<div>
<p>[Title of datapoint 5]</p>
<svg>[SVG using datapoint 5]</svg>
</div>
请注意,数据点 2 和 4 的绘图顺序已更改
谁能告诉我 d3.js 是否提供了实现这一目标的方法,或者你能告诉我你将如何自己解决这个问题吗?
解决方案
不幸的是你没有分享你的代码,所以我们不能重构它。
因此,我将使用 写一个答案selection.each
,这可以说是您案例中惯用的 D3 解决方案。这里唯一重要的是将索引传递给余数运算符 as i % 2
,它返回true
( 1
) 用于奇数索引和false
( 0
) 用于偶数索引。然后,使用if
,我们可以选择要附加的元素。例如:
.each(function(_, i) {
if (i % 2) {
appendSvg(d3.select(this))
appendParagraph(d3.select(this))
} else {
appendParagraph(d3.select(this))
appendSvg(d3.select(this))
}
});
在这种情况下,我使用了两个不同的函数,我将当前选择传递给它们,但您可以简单地使用您拥有的块(尽管更多重复的代码)。
这是演示:
const body = d3.select("body");
const divs = body.selectAll(null)
.data(d3.range(5))
.enter()
.append("div")
.each(function(_, i) {
if (i % 2) {
appendSvg(d3.select(this))
appendParagraph(d3.select(this))
} else {
appendParagraph(d3.select(this))
appendSvg(d3.select(this))
}
});
function appendSvg(sel) {
sel.append("svg")
.attr("width", 80)
.attr("height", 20);
};
function appendParagraph(sel) {
sel.append("p")
.html("This is a p element")
};
div {
display: inline-block;
margin-right: 10px;
border: 1px solid gray;
padding: 2px;
}
svg {
background-color: tan;
}
p {
font-size: 12px;
margin-bottom: 4px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
推荐阅读
- angular - 在 Angular 2 中使用 Freemarker 模板标签
- module - 无法在 hassio 上的 Node-RED 中安装任何模块(节点)
- c - 如果用户输入错误,则使一段代码循环回代码中的某个点
- python - 数据框:尝试修复不可散列的类型:“列表”错误
- java - 存储字符串的整数的通用数组列表?
- excel - Excel 工作簿外部链接在网络驱动器上保存时未更新。
- javascript - React Native“获取”返回没有信息的服务器响应
- mysql - MySQL 8.0 - 客户端不支持服务器请求的认证协议;考虑升级 MySQL 客户端
- google-apps-script - 具有 Google 表格访问权限的用户无法使用脚本菜单插件
- angular - 如何从Angular中另一个输入的值设置输入的默认值?