我需要做什么才能使用 D3.js 更改对象的大小和颜色?

问题描述

请查看 Observablehq notebook 中的代码https://observablehq.com/@erayalan/radial-scatter-plot

我想了解如何更改此作品中每个项目的大小和颜色:

data = [{ name : "foo",r: 40,theta: 1.4 },{ name : "bar",r: 30,theta: 4.8 },{ name : "baz",r: 60,theta: 3.05}] 

解决方法

要更改圆圈的大小,您可以使用 "r" 属性,类似于使用“cx”和“cy”的方式。我假设您想将“theta”映射到大小。首先,您需要创建 a scale:

  const radiusScale = d3.scaleLinear().domain(d3.extent(data,d=> d.theta)).range([10,20])

d3.extent(data,d=> d.theta) 中的函数 extent 返回 theta 属性中数据的最大值和最小值(在本例中为 [1.4,4.8])。这意味着这个标度的域为 [1.4,4.8],范围为 [10,20],所以如果你调用 radiusScale(1.4) 它将输出 10,而 radiusScale(4.8) 将输出 { {1}}。有了这个,您将 theta 值映射到足够的半径,并且可以在 SVG 圆的 20 属性上使用它:

"r"

类似的逻辑适用于在 .attr("cx",d => d.r * Math.cos(d.theta)) .attr("cy",d => d.r * Math.sin(d.theta)) .attr("r",d => radiusScale(d.theta)) 属性中定义的颜色。您想将“foo”、“bar”和“baz”映射到不同的颜色。您可以为此使用 "fill" 和颜色数组:

scaleOrdinal

这个刻度的范围是 const colorScale = d3.scaleOrdinal().range(d3.schemeCategory10) ,它只是一个包含一些常见颜色的数组(你可以使用任何颜色数组)。您不需要此比例的域,因为 d3 可以自动为比例接收的每个唯一值分配不同的颜色。

然后您可以补充映射,将颜色分配给填充属性。

d3.schemeCategory10

这里是 a fork of your notebook 上面的变化:

附注:

在我的回答中,我将 theta 的值直接映射到半径。不建议使用圆的半径来编码一个值,最好的做法是使用它的面积。为简单起见,我不会在这里深入介绍,但您可以查看映射大小 here 的更好方法。

D3 的学习曲线可能有点陡峭。您在此答案中看到了几个用于更改颜色和大小(比例、域、范围、范围等!)的概念。您可能需要检查 the official d3 introduction 以更连续的方式查看这些概念。

,

这是一个包含尺寸和颜色的片段:

data = [
  {name: "foo",r: 40,theta: 1.4,size: 10,color: 'red'},{name: "bar",r: 30,theta: 4.8,size: 12,color: 'green'},{name: "baz",r: 60,theta: 3.05,size: 14,color: 'blue'}
];

const width = 200;
const height = 200;
const svg = d3.select('svg');

const radius = 100;
const r = d3.scaleLinear()
      .domain([0,1])
      .range([0,radius]);

svg
  .attr("viewBox",`${-width / 2} ${-height / 2} ${width} ${height}`)
  .attr('width',width)
  .attr('height',height)
  .style("font","10px sans-serif");

const gr = svg.append('g')
  .attr('class','r axis')
  .selectAll('g')
  .data(r.ticks(5).slice(1))
  .enter()
  .append('g');

gr.append('circle')
  .attr("fill","none")
  .attr("stroke","#ebebeb")
  .attr('r',r);

const ga = svg.append('g')
  .attr('class','a axis')
  .selectAll('g')
  .data(d3.range(0,360,30)) // line density
  .enter()
  .append('g')
  .attr('transform',d => 'rotate(' + -d + ')');

 ga.append('line')
   .attr("fill","none")
   .attr("stroke","#aaa")
   .attr('x2',radius);
  
 svg.selectAll("point") // No longer "rect"
  .data(data)
  .enter()
  .append("circle")
  .attr("cx",d => d.size)
  .style('stroke',d => d.color)
  .style('fill','white');

  svg.selectAll("text") // Note "text",not "circle" or "rect"
  .data(data)
  .enter()
  .append("text")
  .text(d => d.name)
  .attr("x",d => d.r * Math.cos(d.theta))
  .attr("y",d => d.r * Math.sin(d.theta))
  .attr('alignment-baseline','middle')
  .attr('text-anchor','middle')
  .attr("font-family","sans-serif")
  .attr("font-size","11px")
  .attr("fill",d => d.color);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg/>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...