使用d3.js创建具有径向渐变的颜色范围

时间:2016-02-09 23:35:41

标签: javascript d3.js

我正在尝试使用渐变来构建颜色范围,方法是迭代十六进制代码颜色数组并创建svg渐变定义,然后将渐变网址插入到另一个数组中。见下文。

var color_chart = d3.select("body")
                          .append("svg")
                          .attr("width", 1000)
                          .attr("height", 500);

var numRange = [1, 1.5, 2, 2.5, 3, 4, 5, 7, 10, 15, 25, 45, 70, 100, 150, 240],
    colorRange = ["#0500FF","#0100FF","#0022FF","#0064FF",
            "#00A4FF","#00E4FF","#00FF83","#17FF00",
            "#B0FF00","#FFF000","#FFC800","#FFA000",
            "#FF7800","#FF5000","#FF2800","#FF0000"],
    gradientRange = [];

var defs = color_chart.append("defs");

  for (var i = 0; i < colorRange.length; i++) {
     var gradient = defs.append("radialGradient")
        .attr("id", "radial-gradient" + i);

    gradient.append("stop")
        .attr("offset", "0%")
        .attr("stop-color", colorRange[i])
        .attr("stop-opacity", 1);

    gradient.append("stop")
        .attr("offset", "100%")
        .attr("stop-color", colorRange[i])
        .attr("stop-opacity", 0);

这是我遇到麻烦的地方。在下一行我试图插入字符串以通过id获取渐变def到数组中。这在我对字符串ex进行硬编码时有效。 gradientRange.push("url(#radial-gradient1)");,但在我使用i时却没有。使用i代替输出元素的数据值而不是for循环的当前索引。

        gradientRange.push("url(#radial-gradient" + i + ")");
  };


var color = d3.scale.linear()
              .domain(numRange)
              .range(gradientRange);

  color_chart.selectAll("circle")
            .data(temps)
            .enter()
            .append("circle")
            .attr("cx", function(d,i) { return coors[i].x })
            .attr("cy", function(d,i) { return coors[i].y })
            .attr("r", 10)
            .attr("fill", color);

您可以在下图中看到输出。

enter image description here

我需要他们在fill属性中使用正确的id,如下所示:

<circle cx="..." cy="..." r="..." fill="url(#radial-gradient1)"></circle>
<circle cx="..." cy="..." r="..." fill="url(#radial-gradient15)"></circle>
<circle cx="..." cy="..." r="..." fill="url(#radial-gradient3)"></circle>
<circle cx="..." cy="..." r="..." fill="url(#radial-gradient12)"></circle>
<circle cx="..." cy="..." r="..." fill="url(#radial-gradient1)"></circle>

1 个答案:

答案 0 :(得分:0)

似乎temps数组包含带小数点的数字。如果temps数组值位于numRange之间,则可以将临时值四舍五入以解决此问题。

.attr("fill", function(d, i) {
        return color(Math.round(d));
});

&#13;
&#13;
var temps = [25.2, 1.45, 240.25, 3.1],
  coors = [{
    x: 10,
    y: 20
  }, {
    x: 50,
    y: 60
  }, {
    x: 50,
    y: 80
  }, {
    x: 90,
    y: 100
  }];

var color_chart = d3.select("body")
  .append("svg")
  .attr("width", 1000)
  .attr("height", 500);

var numRange = [1, 1.5, 2, 2.5, 3, 4, 5, 7, 10, 15, 25, 45, 70, 100, 150, 240],
  colorRange = ["#0500FF", "#0100FF", "#0022FF", "#0064FF",
    "#00A4FF", "#00E4FF", "#00FF83", "#17FF00",
    "#B0FF00", "#FFF000", "#FFC800", "#FFA000",
    "#FF7800", "#FF5000", "#FF2800", "#FF0000"
  ],
  gradientRange = [];

var defs = color_chart.append("defs");

for (var i = 0; i < colorRange.length; i++) {
  var gradient = defs.append("radialGradient")
    .attr("id", "radial-gradient" + i);

  gradient.append("stop")
    .attr("offset", "0%")
    .attr("stop-color", colorRange[i])
    .attr("stop-opacity", 1);

  gradient.append("stop")
    .attr("offset", "100%")
    .attr("stop-color", colorRange[i])
    .attr("stop-opacity", 0);

  gradientRange.push("url(#radial-gradient" + i + ")");
};

console.log(numRange);
console.log(gradientRange);

var color = d3.scale.linear()
  .domain(numRange)
  .range(gradientRange);

color_chart.selectAll("circle")
  .data(temps)
  .enter()
  .append("circle")
  .attr("cx", function(d, i) {
    return coors[i].x
  })
  .attr("cy", function(d, i) {
    return coors[i].y
  })
  .attr("r", 10)
  .attr("fill", function(d, i) {
    return color(Math.round(d));
  });
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
&#13;
&#13;
&#13;