javascript - 如何从 d3 导入子模块以轻松创建图例?
问题描述
我对 JavaScript 和 D3 比较陌生,所以请记住这一点。我创建了一个可视化来显示对仓库中特定位置的访问频率,并希望使用连续色标添加图例。
我已经查看了几个块并且可以想出一些切线的东西,但是我遇到了这个网页并想使用图例功能。天真地,我尝试添加
import {legend} from "@d3/color-legend"
正如预期的那样失败了。我不知道该怎么做才能使这个导入工作。我已经下载了最新的 d3.zip 文件并尝试了以下来源但没有成功。
<script type="text/javascript" src="https://d3js.org/d3.v5.js"></script>
<script type="text/javascript" src="d3.js"></script>
任何指导将不胜感激。
解决方案
给定该模块名称的相对路径,该路径import
仅适用于 Observable 的单元格。如果这不是您的情况,只需复制您将在下面找到的整个函数(单击“显示代码片段”),或将其保存为文件(然后您可以import
使用适当的模块名称进行操作):
function legend({
color,
title,
tickSize = 6,
width = 320,
height = 44 + tickSize,
marginTop = 18,
marginRight = 0,
marginBottom = 16 + tickSize,
marginLeft = 0,
ticks = width / 64,
tickFormat,
tickValues
} = {}) {
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [0, 0, width, height])
.style("overflow", "visible")
.style("display", "block");
let x;
// Continuous
if (color.interpolator) {
x = Object.assign(color.copy()
.interpolator(d3.interpolateRound(marginLeft, width - marginRight)), {
range() {
return [marginLeft, width - marginRight];
}
});
svg.append("image")
.attr("x", marginLeft)
.attr("y", marginTop)
.attr("width", width - marginLeft - marginRight)
.attr("height", height - marginTop - marginBottom)
.attr("preserveAspectRatio", "none")
.attr("xlink:href", ramp(color.interpolator()).toDataURL());
// scaleSequentialQuantile doesn’t implement ticks or tickFormat.
if (!x.ticks) {
if (tickValues === undefined) {
const n = Math.round(ticks + 1);
tickValues = d3.range(n).map(i => d3.quantile(color.domain(), i / (n - 1)));
}
if (typeof tickFormat !== "function") {
tickFormat = d3.format(tickFormat === undefined ? ",f" : tickFormat);
}
}
}
// Discrete
else if (color.invertExtent) {
const thresholds = color.thresholds ? color.thresholds() // scaleQuantize
:
color.quantiles ? color.quantiles() // scaleQuantile
:
color.domain(); // scaleThreshold
const thresholdFormat = tickFormat === undefined ? d => d :
typeof tickFormat === "string" ? d3.format(tickFormat) :
tickFormat;
x = d3.scaleLinear()
.domain([-1, color.range().length - 1])
.rangeRound([marginLeft, width - marginRight]);
svg.append("g")
.selectAll("rect")
.data(color.range())
.join("rect")
.attr("x", (d, i) => x(i - 1))
.attr("y", marginTop)
.attr("width", (d, i) => x(i) - x(i - 1))
.attr("height", height - marginTop - marginBottom)
.attr("fill", d => d);
tickValues = d3.range(thresholds.length);
tickFormat = i => thresholdFormat(thresholds[i], i);
}
svg.append("g")
.attr("transform", `translate(0, ${height - marginBottom})`)
.call(d3.axisBottom(x)
.ticks(ticks, typeof tickFormat === "string" ? tickFormat : undefined)
.tickFormat(typeof tickFormat === "function" ? tickFormat : undefined)
.tickSize(tickSize)
.tickValues(tickValues))
.call(g => g.selectAll(".tick line").attr("y1", marginTop + marginBottom - height))
.call(g => g.select(".domain").remove())
.call(g => g.append("text")
.attr("y", marginTop + marginBottom - height - 6)
.attr("fill", "currentColor")
.attr("text-anchor", "start")
.attr("font-weight", "bold")
.text(title));
return svg.node();
}
但是,还有另一个障碍:目前该功能也只能在 Observable 的单元格中工作。如果您希望它在常规网页上工作,请更改其返回值(或附加 SVG 作为副作用)。
推荐阅读
- java - quarkus 休眠模式中的内存不足错误
- python - 我希望导航抽屉作为示例运行;但是,MDNavigationDrawer 可能会执行两次
- r - 用 R 中的 if 语句填充 for 循环中的表
- microsoft-graph-api - 如何使用 Microsoft Graph API 阅读附加电子邮件的附件
- c++ - 如何使用 std::vector 中的备用容量?
- javascript - 为什么 Threebox.js 中的 WORLD_SIZE 为 1024000
- ios - 如何正确执行 SwiftUI StateObjects 的依赖注入?
- r - 拟合的 coxph 模型随时间变化的地层和集群的公式中的项排序而变化
- typescript - 如何在 TypeScript 中为单个文件启用严格模式?
- java - 从多个作为 Enum 参数的 Set 创建映射