如何从具有多个对象的单个数组使用 D3 创建多个饼图?
How to create multiple pie charts with D3 from a single array with multiple objects?
我正在学习如何使用 D3.js,我正在尝试根据从外部 API 获取的 JSON 数据呈现多个饼图。我正在处理的数据如下所示
tickers = [{
"symbol": "GME",
"buy": 0,
"hold": 3,
"period": "2021-08-01",
"sell": 5,
"strongBuy": 0,
"strongSell": 2
}, {
"symbol": "AMD",
"buy": 21,
"hold": 16,
"period": "2021-08-01",
"sell": 1,
"strongBuy": 8,
"strongSell": 0
}]
我正在尝试为数组中的每个对象呈现一个饼图,但我似乎无法使数据流正确地流向我的饼图。我只想要每个饼图上的“强力卖出”、“卖出”、“持有”、“买入”和“强力买入”信息。
我已经尝试了以下代码,并附上了显示 HTML 和饼图
的屏幕截图
var margin = 20, width = 250, height = 250
var radius = Math.min(width, height) / 2 - margin
var new_data = tickers.map(function(d){
if (d){
var temp = {"Strong Sell": d.strongSell, "Sell": d.sell, "Hold": d.hold, "Buy": d.buy, "Strong Buy": d.strongBuy}
} else {
var temp = {"Strong Sell": 0, "Sell": 0, "Hold": 0, "Buy": 0, "Strong Buy": 0}
}
return temp
})
var color = d3.scaleOrdinal()
.domain(["Strong Sell", "Sell", "Hold", "Buy", "Strong Buy"])
.range(["#570e00", "#ff2a00", "#ffff00", "#00ff08", "#00570c"])
var pie = d3.pie()
.value(function(d) {return d.value; })
var data_ready = pie(d3.entries(new_data))
var recommendSvg = d3.selectAll(".company-recommend")
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
recommendSvg
.selectAll('g')
.data(data_ready)
.enter()
.append('path')
.attr('d', d3.arc()
.innerRadius(0)
.outerRadius(radius)
)
.attr('fill', function(d){ return(color(d.data.key)) })
.attr("stroke", "black")
.style("stroke-width", "2px")
.style("opacity", 0.7)
如有任何帮助或建议,我们将不胜感激!
Locations where I want pie charts to show
HTML in the console
这是一个完整的示例,假设“公司推荐”div已经创建。
我已经修改了您的代码,因此您不需要使用 d3.entries
。我从一开始就把数据放在那种格式中。此外,我更新了 recommendSvg
以便 data
数组绑定到它。这意味着每个 div 都绑定到 data
数组中的一个元素。在每组中绘制饼图时,我们将该图表的数据传递给 pie
生成器并为每个切片创建一个路径。
<html>
<head>
<script src="https://d3js.org/d3.v7.min.js"></script>
</head>
<body>
<div class="company-container">
<div class="company-profile"></div>
<div class="company-recommend"></div>
</div>
<div class="company-container">
<div class="company-profile"></div>
<div class="company-recommend"></div>
</div>
<script>
const tickers = [
{
"symbol": "GME",
"buy": 0,
"hold": 3,
"period": "2021-08-01",
"sell": 5,
"strongBuy": 0,
"strongSell": 2
},
{
"symbol": "AMD",
"buy": 21,
"hold": 16,
"period": "2021-08-01",
"sell": 1,
"strongBuy": 8,
"strongSell": 0
}
];
const margin = 20;
const width = 250;
const height = 250;
const radius = Math.min(width, height) / 2 - margin;
const data = tickers.map(d => [
{ key: 'Strong Sell', value: d.strongSell },
{ key: 'Sell', value: d.sell },
{ key: 'Hold', value: d.hold },
{ key: 'Buy', value: d.buy },
{ key: 'Strong Buy', value: d.strongBuy },
]);
const color = d3.scaleOrdinal()
.domain(["Strong Sell", "Sell", "Hold", "Buy", "Strong Buy"])
.range(["#570e00", "#ff2a00", "#ffff00", "#00ff08", "#00570c"]);
const pie = d3.pie().value(d => d.value);
const arc = d3.arc()
.innerRadius(0)
.outerRadius(radius);
// bind our data to the divs. add a group to each div.
const recommendSvg = d3.selectAll('.company-recommend')
.data(data)
.append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', `translate(${width / 2},${height / 2})`);
// draw the pie chart in each group
// by creating one path for each slice
recommendSvg.selectAll('path')
.data(d => pie(d))
.join('path')
.attr('d', arc)
.attr('fill', d => color(d.data.key))
.attr('stroke', 'black')
.attr('stroke-width', '2px')
.attr('opacity', 0.7);
</script>
</body>
</html>
我正在学习如何使用 D3.js,我正在尝试根据从外部 API 获取的 JSON 数据呈现多个饼图。我正在处理的数据如下所示
tickers = [{
"symbol": "GME",
"buy": 0,
"hold": 3,
"period": "2021-08-01",
"sell": 5,
"strongBuy": 0,
"strongSell": 2
}, {
"symbol": "AMD",
"buy": 21,
"hold": 16,
"period": "2021-08-01",
"sell": 1,
"strongBuy": 8,
"strongSell": 0
}]
我正在尝试为数组中的每个对象呈现一个饼图,但我似乎无法使数据流正确地流向我的饼图。我只想要每个饼图上的“强力卖出”、“卖出”、“持有”、“买入”和“强力买入”信息。
我已经尝试了以下代码,并附上了显示 HTML 和饼图
的屏幕截图 var margin = 20, width = 250, height = 250
var radius = Math.min(width, height) / 2 - margin
var new_data = tickers.map(function(d){
if (d){
var temp = {"Strong Sell": d.strongSell, "Sell": d.sell, "Hold": d.hold, "Buy": d.buy, "Strong Buy": d.strongBuy}
} else {
var temp = {"Strong Sell": 0, "Sell": 0, "Hold": 0, "Buy": 0, "Strong Buy": 0}
}
return temp
})
var color = d3.scaleOrdinal()
.domain(["Strong Sell", "Sell", "Hold", "Buy", "Strong Buy"])
.range(["#570e00", "#ff2a00", "#ffff00", "#00ff08", "#00570c"])
var pie = d3.pie()
.value(function(d) {return d.value; })
var data_ready = pie(d3.entries(new_data))
var recommendSvg = d3.selectAll(".company-recommend")
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
recommendSvg
.selectAll('g')
.data(data_ready)
.enter()
.append('path')
.attr('d', d3.arc()
.innerRadius(0)
.outerRadius(radius)
)
.attr('fill', function(d){ return(color(d.data.key)) })
.attr("stroke", "black")
.style("stroke-width", "2px")
.style("opacity", 0.7)
如有任何帮助或建议,我们将不胜感激!
Locations where I want pie charts to show
HTML in the console
这是一个完整的示例,假设“公司推荐”div已经创建。
我已经修改了您的代码,因此您不需要使用 d3.entries
。我从一开始就把数据放在那种格式中。此外,我更新了 recommendSvg
以便 data
数组绑定到它。这意味着每个 div 都绑定到 data
数组中的一个元素。在每组中绘制饼图时,我们将该图表的数据传递给 pie
生成器并为每个切片创建一个路径。
<html>
<head>
<script src="https://d3js.org/d3.v7.min.js"></script>
</head>
<body>
<div class="company-container">
<div class="company-profile"></div>
<div class="company-recommend"></div>
</div>
<div class="company-container">
<div class="company-profile"></div>
<div class="company-recommend"></div>
</div>
<script>
const tickers = [
{
"symbol": "GME",
"buy": 0,
"hold": 3,
"period": "2021-08-01",
"sell": 5,
"strongBuy": 0,
"strongSell": 2
},
{
"symbol": "AMD",
"buy": 21,
"hold": 16,
"period": "2021-08-01",
"sell": 1,
"strongBuy": 8,
"strongSell": 0
}
];
const margin = 20;
const width = 250;
const height = 250;
const radius = Math.min(width, height) / 2 - margin;
const data = tickers.map(d => [
{ key: 'Strong Sell', value: d.strongSell },
{ key: 'Sell', value: d.sell },
{ key: 'Hold', value: d.hold },
{ key: 'Buy', value: d.buy },
{ key: 'Strong Buy', value: d.strongBuy },
]);
const color = d3.scaleOrdinal()
.domain(["Strong Sell", "Sell", "Hold", "Buy", "Strong Buy"])
.range(["#570e00", "#ff2a00", "#ffff00", "#00ff08", "#00570c"]);
const pie = d3.pie().value(d => d.value);
const arc = d3.arc()
.innerRadius(0)
.outerRadius(radius);
// bind our data to the divs. add a group to each div.
const recommendSvg = d3.selectAll('.company-recommend')
.data(data)
.append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', `translate(${width / 2},${height / 2})`);
// draw the pie chart in each group
// by creating one path for each slice
recommendSvg.selectAll('path')
.data(d => pie(d))
.join('path')
.attr('d', arc)
.attr('fill', d => color(d.data.key))
.attr('stroke', 'black')
.attr('stroke-width', '2px')
.attr('opacity', 0.7);
</script>
</body>
</html>