简体   繁体   English

如何从 d3 导入子模块以轻松创建图例?

[英]How to import submodules from d3 to easily create legend?

I'm relatively new to JavaScript and D3 so please keep that in mind.我对 JavaScript 和 D3 比较陌生,所以请记住这一点。 I've created a visualization to show the visit frequency to particular locations in a warehouse and would like to add a legend using a continuous color scale.我创建了一个可视化来显示对仓库中特定位置的访问频率,并希望使用连续色标添加图例。

在此处输入图片说明

I've looked at several blocks and could come up with something tangential, however I came across this webpage and would like to use the legend function.我看过几个块,可以想出一些切线的东西,但是我遇到了这个网页并想使用图例功能。 Naively, I tried adding天真地,我尝试添加

import {legend} from "@d3/color-legend"

which failed as expected.正如预期的那样失败了。 I am not sure what to do in order to make this import work.我不知道该怎么做才能使这个导入工作。 I've downloaded the latest d3.zip file and have tried the following sources without any success.我已经下载了最新的 d3.zip 文件并尝试了以下来源但没有成功。

<script type="text/javascript" src="https://d3js.org/d3.v5.js"></script>
<script type="text/javascript" src="d3.js"></script>

Any guidance would be greatly appreciated.任何指导将不胜感激。

Given the relative path of that module name that import will only work in a Observable's cell.给定该模块名称的相对路径, import只能在 Observable 的单元格中工作。 If that's not your case, simply copy the whole function, which you'll find below (click "Show code snippet"), or save it as a file (and then you can do an import with the adequate module name):如果这不是您的情况,只需复制整个函数,您将在下面找到(单击“显示代码片段”),或将其另存为文件(然后您可以使用适当的模块名称进行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(); }

However, there is another hurdle: currently that function will also only work in an Observable's cell.然而,还有另一个障碍:目前该函数也只能在 Observable 的单元格中工作。 If you want it to work on a regular web page, change its returned value (or append the SVG as a side effect).如果您希望它在常规网页上工作,请更改其返回值(或附加 SVG 作为副作用)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM