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

时间:2016-10-26 15:50:43

标签: javascript d3.js svg

!简化了问题!

附加代码生成64个小圆圈的图案,通向更大的圆圈。

问题是关于基于数据集驱动每个圆的颜色,例如下面,其中可以基于1-6中的数据值为每个圆分配颜色: 一个部分的示例数据集: [1,3,5,2, 3 ...]这里,前4个数字代表第一组4个小圆圈的值,这些小圆圈通向一个大圆圈,最后一个number表示该大圆的值。

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

注意:理想情况下,代码中的圆圈都需要移动一点,以便它们也适合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> 

1 个答案:

答案 0 :(得分:2)

我将提供一个 ad hoc 解决方案:因为我是您在问题中发布的代码,我知道如何绘制圆圈:逆时针,从中心到外部。话虽这么说,我的解决方案涉及到课程。

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

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

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

d3.selectAll(".circle8")

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

所以,如果你设置这样的数组:

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

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

这是一个演示它的演示。课程从6点开始0,逆时针开始,7点左右结束。这些是颜色:

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>

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