随机颜色:return 填充属性的函数

Random color: return a function for the fill attribute

我正在使用 for 循环为包布局动态创建数据。 我希望圆圈的颜色是随机的。 我的代码 return 填充属性的实际功能:

<circle cx="532.0508075688773" cy="219.6152422706632" r="46.41016151377546" fill="function () {
                    return "hsl(" + Math.random() * 360 +",100%,50%)"
                    }" name="1"></circle>

如何更改我的代码,使其成为传递给 fill 属性的函数的 return?

数据如何用于创建根节点的相关部分

...
for (var j=0;j<10;j++){
    child = {}; 
    child["name"]= +j;
    child["value"]=2;
    child["fill"]=function() {
        return "hsl(" + Math.random() * 360 + ",100%,50%)";
        };
...

这就是我创建圆圈的方式

d3.select('svg g')
    .selectAll('circle')
    .data(rootNode.descendants())
    .enter()
    .append('circle')
    ...
    .attr('fill', function(d) { return d.data.fill; })

而不是将函数设置为节点的数据...

child["fill"] = function() {
    return "hsl(" + Math.random() * 360 + ", 100%, 50%)";
};

...只需设置值本身:

child["fill"] = "hsl(" + Math.random() * 360 + ", 100%, 50%)";

这是遵循相同原理的基本演示:

var svg = d3.select("svg")
var data = [{
  name: "foo",
  fill: "hsl(" + Math.random() * 360 + ",100%,50%)"
}, {
  name: "bar",
  fill: "hsl(" + Math.random() * 360 + ",100%,50%)"
}, {
  name: "baz",
  fill: "hsl(" + Math.random() * 360 + ",100%,50%)"
}];
var circles = svg.selectAll(null)
  .data(data)
  .enter()
  .append("circle")
  .attr("cy", 50)
  .attr("r", 40)
  .attr("cx", function(_, i) {
    return 50 + 100 * i
  })
  .style("fill", function(d) {
    return d.fill
  })
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>

但是,我会说在数据中存储函数(Math.random() 是一个函数)不是一个好的(或标准)做法。

为什么不自己存储亮度和饱和度呢?然后,你可以直接在回调中使用Math.random()

.style("fill", function(d) {
    return "hsl(" + Math.random() * 360 + "," + d.saturation + "," + d.lightness + ")"
})

这是演示:

var svg = d3.select("svg")
var data = [{
  name: "foo",
  saturation: "100%",
  lightness: "50%"
}, {
  name: "bar",
  saturation: "40%",
  lightness: "30%"
}, {
  name: "baz",
  saturation: "100%",
  lightness: "80%"
}];
var circles = svg.selectAll(null)
  .data(data)
  .enter()
  .append("circle")
  .attr("cy", 50)
  .attr("r", 20)
  .attr("cx", function(_, i) {
    return 50 + 50 * i
  })
  .style("fill", function(d) {
    return "hsl(" + Math.random() * 360 + "," + d.saturation + "," + d.lightness + ")"
  })
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>