如何从d3导入子模块以轻松创建图例? [英] How to import submodules from d3 to easily create legend?

查看:288
本文介绍了如何从d3导入子模块以轻松创建图例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对JavaScript和D3比较陌生,因此请记住这一点。我创建了一个可视化效果,以显示访问仓库中特定位置的频率,并希望使用连续的色标添加图例。

I'm relatively new to JavaScript and D3 so please keep that in mind. 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.

我看了几个块,可能会切线,但是我遇到了网页,并希望使用图例功能。天真地,我尝试从 @ d3 / color-legend中添加

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"

失败。我不确定要执行此导入操作该怎么做。我已经下载了最新的d3.zip文件,并尝试了以下来源,但没有成功。

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.

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

任何指导将不胜感激。

推荐答案

给出 import 只能在Observable的单元格中起作用的模块名称的相对路径。如果不是这种情况,只需复制下面将要找到的整个函数(单击显示代码段),或将其保存为文件(然后可以执行 import ,并带有适当的模块名称):

Given the relative path of that module name that import will only work in a Observable's cell. 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):

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作为副作用)。

However, there is another hurdle: currently that function will also only work in an Observable's cell. If you want it to work on a regular web page, change its returned value (or append the SVG as a side effect).

这篇关于如何从d3导入子模块以轻松创建图例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆