javascript - D3.JS SVG 圆圈中的数据驱动颜色

标签 javascript d3.js svg

!简化问题!

附加代码生成了一个由 64 个小圆圈组成的图案,这些小圆圈通向更大的圆圈。

问题是关于根据数据集驱动每个圆圈的颜色,如下所示,其中每个圆圈可以根据 1-6 的数据值分配颜色: 一个部分的示例数据集: [1,3,5,2,3...] 在这里,前 4 个数字代表第一组 4 个小圆圈引出其中一个大圆圈的值,最后一个数字代表那个大圆圈的值。

如果有人可以根据上面的示例根据“硬编码”数据集帮助驱动每个圆圈的颜色,那么下一步我将考虑将该数据集附加到我的数据库中。 (最终结果将根据驱动颜色的数据库值字符串加载此图像)

注意:理想情况下,代码中的圆圈都需要稍微移动一下,以便它们也适合 4 个象限,但这里的关键挑战是基于数据集进行分配。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3 Test</title>
<script src="https://d3js.org/d3.v4.min.js"></script>
<style type="text/css">

</style>

</head> 
<body>
<script type="text/javascript">


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

    var color = d3.scaleOrdinal(d3.schemeCategory10)
      .domain(d3.range(16));

    var data1 = d3.range(16);
    var dataRadius = [70, 110, 150, 190, 230];

    svg.append("circle").attr("cx", width / 2)
        .attr("cy", height / 2)
        .attr("r", 30)
        .attr("fill", "yellow");

    //my additions

    svg.append("circle").attr("cx", 40)
        .attr("cy", 40)
        .attr("r", 30)
        .attr("fill", "lightgrey")
        .attr("stroke-width", "1")
        .attr("stroke", "grey");

    svg.append("circle").attr("cx", width - 40)
        .attr("cy", height - 40)
        .attr("r", 30)
        .attr("fill", "lightgrey")
        .attr("stroke-width", "1")
        .attr("stroke", "grey");

    svg.append("circle").attr("cx", width - 40)
        .attr("cy", 40)
         .attr("r", 30)
        .attr("fill", "lightgrey")
        .attr("stroke-width", "1")
        .attr("stroke", "grey");

    svg.append("circle").attr("cx", 40)
        .attr("cy", height - 40)
        .attr("r", 30)
        .attr("fill", "lightgrey")
        .attr("stroke-width", "1")
        .attr("stroke", "grey");

    svg.append("line") 
        .attr("y1", height /2) 
        .attr("y2" , height /2) 
        .attr("x1" , 0) 
        .attr("x2" , width)
        .attr("stroke-width","2") 
        .attr("stroke", "black");

    svg.append("line")
     .attr("x1", height / 2)
     .attr("x2", height / 2)
     .attr("y1", 0)
     .attr("y2", width)
     .attr("stroke-width", "2")
     .attr("stroke", "black");

    //end of my additions
    var groups = svg.selectAll(".groups")
        .data(dataRadius)
        .enter()
        .append("g");

    var circles = groups.selectAll(".circles")
        .data(data1)
        .enter()
        .append("circle");

    circles.attr("cx", function (d, i) { var radius = this.parentNode.__data__; return width / 2 + (radius * Math.sin(i * (360 / (data1.length) * Math.PI / 180))) })
        .attr("cy", function (d, i) { var radius = this.parentNode.__data__; return height / 2 + (radius * Math.cos(i * (360 / (data1.length) * Math.PI / 180))) })
        .attr("r", function () { return this.parentNode.__data__ == 230 ? 24 : 14 })
        .attr("fill", function (d, i) { return i == 13 || i == 14 ? color(i - 2) : "#ccc" });
</script>   

</body>

</html> 

最佳答案

我将提供一个临时解决方案:因为我是编写您在问题中发布的这段代码的人,所以我知道圆圈是如何绘制的:逆时针方向,从中心向外.话虽如此,我的解决方案涉及类。

如果我们在 circles 变量的末尾添加这一行:

.attr("class", function(d){ return "circle" + d});

我们将为圈子设置一个类。但有趣的是,我们每圈有 16 个圆圈,因此,下一个(外部)环中的所有圆圈都将具有相同的类!而且,由于它们是从内到外绘制的,所以很简单:

d3.selectAll(".circle8")

将按您想要的顺序选择属于 .circle8 类的所有 5 个圆圈。

所以,如果你像这样设置一个数组:

var colour8 = ["yellow", "yellow", "tan", "red", "purple"];

它们将按照从内到外的顺序绘制。

这是一个展示它的演示。类(class)从 6 点钟的 0 开始,逆时针方向进行,到 7 点钟左右的 15 结束。这些是颜色:

var color0 = ["teal", "blue", "red", "red", "cyan"];//6 o'clock
var color8 = ["red", "red", "red", "red", "pink"];//12 o'clock
var color9 = ["tan", "tan", "green", "cyan", "lime"];//just next to it

查看演示:

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

    var color = d3.scaleOrdinal(d3.schemeCategory10)
      .domain(d3.range(16));

    var data1 = d3.range(16);
    var dataRadius = [70, 110, 150, 190, 230];

    svg.append("circle").attr("cx", width / 2)
        .attr("cy", height / 2)
        .attr("r", 30)
        .attr("fill", "yellow");

    //my additions

    svg.append("circle").attr("cx", 40)
        .attr("cy", 40)
        .attr("r", 30)
        .attr("fill", "lightgrey")
        .attr("stroke-width", "1")
        .attr("stroke", "grey");

    svg.append("circle").attr("cx", width - 40)
        .attr("cy", height - 40)
        .attr("r", 30)
        .attr("fill", "lightgrey")
        .attr("stroke-width", "1")
        .attr("stroke", "grey");

    svg.append("circle").attr("cx", width - 40)
        .attr("cy", 40)
         .attr("r", 30)
        .attr("fill", "lightgrey")
        .attr("stroke-width", "1")
        .attr("stroke", "grey");

    svg.append("circle").attr("cx", 40)
        .attr("cy", height - 40)
        .attr("r", 30)
        .attr("fill", "lightgrey")
        .attr("stroke-width", "1")
        .attr("stroke", "grey");

    svg.append("line") 
        .attr("y1", height /2) 
        .attr("y2" , height /2) 
        .attr("x1" , 0) 
        .attr("x2" , width)
        .attr("stroke-width","2") 
        .attr("stroke", "black");

    svg.append("line")
     .attr("x1", height / 2)
     .attr("x2", height / 2)
     .attr("y1", 0)
     .attr("y2", width)
     .attr("stroke-width", "2")
     .attr("stroke", "black");

    //end of my additions
    var groups = svg.selectAll(".groups")
        .data(dataRadius)
        .enter()
        .append("g");

    var circles = groups.selectAll(".circles")
        .data(data1)
        .enter()
        .append("circle");

    circles.attr("cx", function (d, i) { var radius = this.parentNode.__data__; return width / 2 + (radius * Math.sin(i * (360 / (data1.length) * Math.PI / 180))) })
        .attr("cy", function (d, i) { var radius = this.parentNode.__data__; return height / 2 + (radius * Math.cos(i * (360 / (data1.length) * Math.PI / 180))) })
        .attr("r", function () { return this.parentNode.__data__ == 230 ? 24 : 14 })
				.attr("fill", "#ccc")
				.attr("class", function(d){ return "circle" + d});
				
		var color0 = ["teal", "blue", "red", "red", "cyan"];
    var color8 = ["red", "red", "red", "red", "pink"];
    var color9 = ["tan", "tan", "green", "cyan", "lime"];
				
		svg.selectAll(".circle0").attr("fill", function(d,i){
				return color0[i];
				});
				
		svg.selectAll(".circle8").attr("fill", function(d,i){
				return color8[i];
				});
				
		svg.selectAll(".circle9").attr("fill", function(d,i){
				return color9[i];
				});
<script src="https://d3js.org/d3.v4.min.js"></script>

这只是一般的想法。当然,您必须编写函数以避免冗余代码。

关于javascript - D3.JS SVG 圆圈中的数据驱动颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40266778/

相关文章:

javascript - 在定义之前就使用了tinymce

javascript - 子组件内的子服务在父组件中是否可见?

python - 在 Python 中调用 Inkscape

javascript - 未定义的纬度和经度谷歌地图

d3.js - D3js 甘特图兼容 D3.4

javascript - 与 javascript 和 d3.js 中的作用域相关的奇怪行为

javascript - 暂停和恢复过渡

javascript - 当元素超出视口(viewport)时我应该删除它吗?

JavaScript 创建 svg 过滤器

javascript - 每个 mootools "this"?