使用JavaScript d3可视化将彩色圆圈替换为图像圆圈

goqiplq2  于 2023-06-23  发布在  Java
关注(0)|答案(1)|浏览(115)

我正在尝试用图像圆圈替换彩色圆圈。下面的图是用JavaScript中的d3绘制的。我不能添加图像,由于我不到10的评级。
enter image description here

// https://observablehq.com/@d3/smooth-zooming@58

function _chart(width,height,d3,data,radius)
{
  let currentTransform = [width / 2, height / 2, height];

  const svg = d3.create("svg")
      .attr("viewBox", [0, 0, width, height])

  const g = svg.append("g");

  g.selectAll("circle")
    .data(data)
    .join("circle")
      .attr("cx", ([x]) => x)
      .attr("cy", ([, y]) => y)
      .attr("r", radius)
      .attr("fill", (d, i) => d3.interpolateRainbow(i/360))

  function transition() {
    const d = data[Math.floor(Math.random() * data.length)];
    const i = d3.interpolateZoom(currentTransform, [...d, radius * 2 + 1]);

    g.transition()
        .delay(250)
        .duration(i.duration)
        .attrTween("transform", () => t => transform(currentTransform = i(t)))
        .on("end", transition);
  }

  function transform([x, y, r]) {
    return `
      translate(${width / 2}, ${height / 2})
      scale(${height / r})
      translate(${-x}, ${-y})
    `;
  }

  return svg.call(transition).node();
}

function _height(){return(
500
)}

function _radius(){return(
  2
)}

function _step(radius){return(
radius * 2
)}

function _data(step,theta,width,height){return(
Array.from({length: 2000}, (_, i) => {
  const r = step * Math.sqrt(i += 0.5), a = theta * i;
  return [
    width / 2 + r * Math.cos(a),
    height / 2 + r * Math.sin(a)
  ];
})
)}

function _theta(){return(
Math.PI * (3 - Math.sqrt(5))
)}

function _d3(require){return(
require("d3@6")
)}

export default function define(runtime, observer) {
  const main = runtime.module();
  
  main.variable(observer("chart")).define("chart", ["width","height","d3","data","radius"], _chart);
  main.variable().define("height", _height);
  main.variable().define("radius", _radius);
  main.variable().define("step", ["radius"], _step);
  main.variable().define("data", ["step","theta","width","height"], _data);
  main.variable().define("theta", _theta);
  main.variable().define("d3", ["require"], _d3);
  return main;
}

我想我们可能需要改变数据功能。我不能用图像来展示它,因为我是JavaScript的初学者。

ghhkc1vu

ghhkc1vu1#

首先,你的直接问题是:
我正在尝试用图像圆圈替换彩色圆圈。
这个问题在StackOverflow for example here上得到了多次回答。
但是,在d3上下文中这样做有点不同,因为您可能需要一些代码沿着如下所示:

let url = ...
let defs = svg.append("defs");
defs
  .append("pattern")
  ...
  .attr("id", 'image')
  .append("image")
  ...
  .attr("href", url);

下面有更多的细节。
此外,您发布的代码块在我看来像是由Observalbe嵌入API返回的,即:https://api.observablehq.com/@d3/smooth-zooming.js?v=3
我已经分叉了笔记本,并做了必要的更改,包括一些图像。Here's the fork,下面是嵌入该代码的正确方法:

<div id="observablehq-chart-25b97cbc"></div>
<script type="module">
import {Runtime, Inspector} from "https://cdn.jsdelivr.net/npm/@observablehq/runtime@5/dist/runtime.js";
import define from "https://api.observablehq.com/d/adfba0cfb4396df0.js?v=3";
new Runtime().module(define, name => {
  if (name === "chart") return new Inspector(document.querySelector("#observablehq-chart-25b97cbc"));
});
</script>

如果您检查forked notebook,您应该注意到顶部附近的代码块如下所示:

image_urls = [
  "https://upload.wikimedia.org/wikipedia/commons/3/3d/Perspectiva_Corporum_Regularium_36a.jpg",
  "https://upload.wikimedia.org/wikipedia/commons/7/7f/Hexaeder_NdFeB_5041.jpg",
  "https://upload.wikimedia.org/wikipedia/commons/f/f6/Hexader_1.jpg"
]

我猜这可能是任何指向图像的公开访问URL列表。
下一个代码块定义了chart,它包含几行,看起来像这样:

let defs = svg.append("defs");
image_urls.forEach(function (url, i) {
  defs
    .append("pattern")
    .attr("id", `image${i}`)
    .attr("x", "0%")
    .attr("y", "0%")
    .attr("width", "100%")
    .attr("height", "100%")
    .attr("viewBox", "50 50 200 100")
    .append("image")
    .attr("x", "0%")
    .attr("y", "0%")
    .attr("width", "100%")
    .attr("height", "100%")
    .attr("href", url);
});

它设置了可用作填充的图案。最后,稍后在连接圆时使用该位:

g.selectAll("circle")
  .data(data)
  .join("circle")
  ...
  .attr("fill", (_, i) => `url(#image${i % image_urls.length}`);

相关问题