gpt4 book ai didi

javascript - 循环 JSON 数据以创建 d3 饼图

转载 作者:行者123 更新时间:2023-11-29 23:45:45 25 4
gpt4 key购买 nike

我已经成功地使用 d3 和 JSON 创建了我的第一个饼图,但我正在努力让多个饼图出现。我查看了许多示例,包括 Mike Bostock's donut-multiples ,看来我的代码中需要一个 for-each 循环。

这是我的程序的简化版本,它生成一个饼图而不是两个:

<!doctype html>
<html>
<head>
<title>Pie Chart Test</title>
<meta charset="UTF-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
</head>

<style>
.arc path {
stroke: white;
}
</style>

<body>
<script>
var width = 300,
height = 300,
radius = Math.min(width, height) / 2;

var arc = d3.svg.arc()
.outerRadius(radius)
.innerRadius(radius - (radius / 2));

var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.ratio; });

var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

d3.json("data.json", function(error, data) {
if (error) throw error;

node = data.data[0].pie1.results;

var g = svg.selectAll(".arc")
.data(pie(node))
.enter().append("g")
.attr("class", "arc")

g.append("path")
.attr("d", arc)
.style("fill", function(d) {
if (d.data.failures > 0) {
return "#d63535";
} else {
return "#22c12d";
}
});
});
</script>
</body>
</html>

这是填充图表的 JSON:

    {"data":[
{"pie1": {
"results": [
{"ratio": 0.04, "total": 7, "failures": 1},
{"ratio": 0.04, "total": 8, "failures": 0},
{"ratio": 0.04, "total": 9001, "failures": 0}
]}
},
{"pie2": {
"results": [
{"ratio": 0.04, "total": 10, "failures": 0},
{"ratio": 0.04, "total": 11, "failures": 1},
{"ratio": 0.04, "total": 12, "failures": 1}
]}
}
]}

最佳答案

it appears I need a for-each loop in my code

一般来说,在d3中for each循环是可以避免的。大多数 d3 的规范示例都避免使用它们。

您可以使用标准的 d3 输入选择来为数据数组中的每个项目创建一个 svg 元素,而不是 for-each 循环(即每个饼图一个 svg)。这会将每个饼图的数据绑定(bind)到其各自的 svg:

    var svg = d3.select("body").selectAll("svg")
.data(data.data)
.enter()
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

现在您可以使用绑定(bind)数据为每个 svg 创建饼图:

    var g = svg.selectAll(".arc")
.data(function(d,i) { return pie(d["pie"+(i+1)].results) })
.enter().append("g")
.attr("class", "arc")

g.append("path")
.attr("d", arc)
.style("fill", function(d) { return (d.data.failures > 0) ? "#d63535" : "#22c12d"; });

所有这些看起来像:

var data  = {"data":[
{"pie1": {
"results": [
{"ratio": 0.04, "total": 7, "failures": 1},
{"ratio": 0.04, "total": 8, "failures": 0},
{"ratio": 0.04, "total": 9001, "failures": 0}
]}
},
{"pie2": {
"results": [
{"ratio": 0.04, "total": 10, "failures": 0},
{"ratio": 0.04, "total": 11, "failures": 1},
{"ratio": 0.04, "total": 12, "failures": 1}
]}
}
]};

var width = 300,
height = 300,
radius = Math.min(width, height) / 2;

var arc = d3.svg.arc()
.outerRadius(radius)
.innerRadius(radius - (radius / 2));

var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.ratio; });

var svg = d3.select("body").selectAll("svg")
.data(data.data)
.enter()
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

var g = svg.selectAll(".arc")
.data(function(d,i) { return pie(d["pie"+(i+1)].results) })
.enter().append("g")
.attr("class", "arc")

g.append("path")
.attr("d", arc)
.style("fill", function(d) { return (d.data.failures > 0) ? "#d63535" : "#22c12d"; });
.arc path {
stroke: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>

当然,您的数据结构确实让事情变得有点复杂。我将它保留在上面的代码片段中,但稍作更改将有助于简化代码:

var data = [
{
"name":"pie1",
"results": [
{"ratio": 0.04, "total": 7, "failures": 1},
{"ratio": 0.04, "total": 8, "failures": 0},
{"ratio": 0.04, "total": 9001, "failures": 0}
]
},
{
"name":"pie2",
"results": [
{"ratio": 0.04, "total": 10, "failures": 0},
{"ratio": 0.04, "total": 11, "failures": 1},
{"ratio": 0.04, "total": 12, "failures": 1}
]
}
]

var width = 300,
height = 300,
radius = Math.min(width, height) / 2;

var arc = d3.svg.arc()
.outerRadius(radius)
.innerRadius(radius - (radius / 2));

var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.ratio; });

var svg = d3.select("body").selectAll("svg")
.data(data)
.enter()
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

var g = svg.selectAll(".arc")
.data(function(d,i) { return pie(d.results) })
.enter().append("g")
.attr("class", "arc")

g.append("path")
.attr("d", arc)
.style("fill", function(d) { return (d.data.failures > 0) ? "#d63535" : "#22c12d"; });
.arc path {
stroke: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>

第二个代码片段不需要访问数据数组中每个元素的唯一属性。如果每个数据元素都有唯一标识符,只需将其分配给数据数组中每个项目的通用命名属性即可。

您不必将数据绑定(bind)到多个 svg 元素,您也可以使用多个 g 元素(例如)。

关于javascript - 循环 JSON 数据以创建 d3 饼图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44272103/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com