我有这段代码可生成9个甜甜圈图。事实是,SVG
画布被附加到DOM的次数很多,绘制的甜甜圈图也是如此,并且当我尝试在屏幕顶部放置一个text
元素时(如一个大标题来解释图形),它也会被附加9次(在每个容纳每个甜甜圈的SVG
画布中)。我只需要一个SVG
画布,并在其中包含9个甜甜圈,但是我很难做到这一点。
这是我到目前为止的摘要。
$("#chartdiv").empty()
var dataObj = {
data1: [19, 81],
data2: [15, 85],
data3: [13, 91],
data4: [8, 92],
data5: [7, 93],
data7: [6, 94],
data8: [5, 95],
data9: [4, 96],
data10: [3, 97],
data11: [2, 98],
data11: [1, 99],
data12: [0, 100],
};
var newarr = ["Manufacturing", "Technology", "Other", "Engineering", "Automotive", "Consulting/professiona services", "Entertaiment and media", "Financial services", "Apparel and textile", "Construction", "Academic and educational", "Legal services"]
var width = 140,
height = 140,
radius = (Math.min(width, height) / 2.8);
function drawDonut(data, divchart, index, chartName) {
var color = ["#00338D", "#dedede"];
var pie = d3.pie()
.sortValues(null)
.value(function(d) {
return d
})(data);
var arc = d3.arc()
.outerRadius(radius - 10)
.innerRadius(radius - (radius / 1.9));
var labelArc = d3.arc()
.outerRadius(radius - 31)
.innerRadius(radius - 31);
var svg = d3.select("#chartdiv")
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + 75 + "," + 50 + ")");
var g = svg.selectAll("arc")
.data(pie)
.enter().append("g")
.attr("class", "arc");
function easeInverse(ease) {
return function(e) {
var min = 0,
max = 1;
while (max - min > 1e-3) {
var mid = (max + min) * 0.5;
emid = ease(mid);
if (emid > e) {
max = mid;
} else {
min = mid;
}
}
return max;
}
}
var inverseCubic = easeInverse(d3.easeCubic);
var oneOver2Pi = 1.0 / (2 * Math.PI);
var total_msec = 900;
g.append("path")
.style("fill", function(d, i) {
return color[i];
})
.transition()
.ease(d3.easeLinear)
.delay(function(d) {
return total_msec * inverseCubic(d.startAngle * oneOver2Pi);
})
.duration(function(d) {
return total_msec * (inverseCubic(d.endAngle * oneOver2Pi) - inverseCubic(d.startAngle * oneOver2Pi));
})
.attrTween("d", arcTween);
function arcTween(d) {
var i = d3.interpolate(inverseCubic(d.startAngle * oneOver2Pi), inverseCubic(d.endAngle * oneOver2Pi));
return function(t) {
d.endAngle = 2 * Math.PI * d3.easeCubic(i(t));
return arc(d);
}
}
g.append("text")
.attr("transform", "translate(0,5) scale(1.4)")
.attr("font-weight", "bold")
.attr("class", "st0 donutsTextElemnt")
.attr("font-size", "11px")
.attr("text-anchor", "middle")
.html(data[0] + "%");
svg.append("foreignObject")
.attr("transform", "translate(-30,50) scale(.75)")
.attr("width", 120)
.attr("height", 80)
.attr("class", "caption 3rForeignObj")
.append("xhtml:body")
.html(newarr[index])
.style("background", "white");
var lastDonut = $("#donutdiv").children().eq(6)
lastDonut.css({
'transform': 'translate(0 , 20px)'
});
}
Object.keys(dataObj).forEach(function(d, i) {
drawDonut(dataObj[d], '#pie' + (i + 1), i, 'chart' + (i + 1));
});
body {
background: rgb(92, 29, 186);
height: 100vh;
}
* {
box-sizing: border-box;
}
.list-group-item {
font-size: 24px;
background: inherit;
border: none;
color: #fff!important;
}
/* .action{
font-size: 14px!important;
background: inherit;
border: none;
color:#fff!important;
} */
.list-group-item:hover {
color: black!important;
}
.firstPage {
background: #470a68;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%)
}
.secondPage {
background: #00A3A1;
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
;
-o-transform: translate(-50%, -50%);
;
transform: translate(-50%, -50%);
;
}
.thirdPage {
background: #00A3A1;
}
.fourthPage {
background: #f45f42;
}
.submenuTitle p {
font-size: 30px;
color: #fff;
}
.sectionsTitle {
font-size: 52px!important;
}
.inactive {
display: none;
}
.active {
display: block;
}
#chartdiv {
background: #fff;
}
.chart {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.heightZero {
height: 0;
overflow: hidden
}
@keyframes slideUp {
to {
height: 100%
}
}
.slideUp {
animation: slideUp .6s ease-in forwards;
}
.thirdDonutsDiv {
display: inline
}
a {
font-size: 16px!important;
}
.back {
transform: scale(.7)
}
.container-fluid {
width: 512px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%)
}
.sectionsTitle {
font-family: KPMG Extralight;
color: white;
font-weight: bold;
}
p.mainTitle {
color: #fff;
font-size: 115px;
font-family: KPMG Extralight;
margin-top: 5px;
}
p.standardP {
color: #fff;
font-family: univers;
font-size: 1.666rem;
line-height: 1.2;
margin: 1rem 1;
margin-top: 30px;
}
h3.mainTitle {
color: #fff;
font-family: KPMG;
margin-top: 14px;
margin-bottom: 14px;
font-size: 3.8rem;
font-weight: bolder;
}
p.standardP {
color: #fff;
font-family: univers;
font-size: 1.666rem;
line-height: 1.2;
margin: 1rem 1;
margin-top: 30px;
}
ul {
list-style-type: none;
padding: 0;
margin-right: 10px;
margin-left: 10px;
}
label {
width: 100%;
height: 100%;
padding: 0.85rem 1rem;
background-color: hsla(0, 0%, 100%, 0);
color: #fff;
cursor: pointer;
border-radius: 4px;
margin-bottom: 11px;
transition: all .4s;
font-size: 16px;
font-weight: normal;
}
label:hover {
background-color: white;
color: #000;
transition: background-color .2s
}
.labelUnselected {
background-color: hsla(0, 0%, 100%, .6);
color: #fff;
}
div.mainDiv p {
word-wrap: break-word;
line-height: 100%;
}
input {
display: none;
}
.backSubMenu1 {
text-align: center;
}
/* donut chart 4*/
.st0 {
fill: #00338D;
}
#fourtySeven {
transform: translate(50px, 0px)
}
#twentyEight {
transform: translate(-63.104974985120286px, 86.28081103480314px)
}
.icon2 {
opacity: 0;
animation: fadeIn 1s linear 1.5s forwards;
transform: translate(-50px, -45px)
}
@keyframes fadeIn {
to {
opacity: 1;
}
}
.rect {
opacity: 0;
animation: fadeIn 1.3s linear 1.5s forwards;
}
@keyframes fadeIn {
to {
opacity: 1;
}
}
.ifram {
width: 512px;
}
.iconXY {
opacity: 0;
animation: fadeIn 1.5s linear 1.8s forwards;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://d3js.org/d3.v5.min.js"></script>
<div class="row">
<div class="col-sm-12" id="chartdiv"></div>
<div class="text-left backSubMenu1">
<i class="fas fa-chevron-left back" style="font-size: 40px;color:aliceblue" targetX="secondPage">
<a href="#firstPage"></a>
</i>
</div>
<div id="pie1" class="thirdDonutsDiv"></div>
<div id="pie2" class="thirdDonutsDiv"></div>
<div id="pie3" class="thirdDonutsDiv"></div>
<div id="pie4" class="thirdDonutsDiv"></div>
<div id="pie5" class="thirdDonutsDiv"></div>
<div id="pie6" class="thirdDonutsDiv"></div>
<div id="pie7" class="thirdDonutsDiv"></div>
<div id="pie8" class="thirdDonutsDiv"></div>
<div id="pie9" class="thirdDonutsDiv"></div>
</div>
答案 0 :(得分:2)
这里有一个 d3ish 重构,可以实现一个包含所有饼图的SVG的目标:
<!DOCTYPE html>
<html>
<body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<div class="row">
<div class="col-sm-12" id="chartdiv">
</div>
</div>
<script>
var dataObj = {
data1: [19, 81],
data2: [15, 85],
data3: [13, 91],
data4: [8, 92],
data5: [7, 93],
data7: [6, 94],
data8: [5, 95],
data9: [4, 96],
data10: [3, 97],
data11: [2, 98],
data11: [1, 99],
data12: [0, 100],
};
var newarr = ["Manufacturing", "Technology", "Other", "Engineering", "Automotive", "Consulting/professiona services", "Entertaiment and media", "Financial services", "Apparel and textile", "Construction", "Academic and educational", "Legal services"]
var width = 140,
height = 140,
radius = (Math.min(width, height) / 2.8),
numCol = 4;
var svg = d3.select("#chartdiv")
.append("svg")
.attr("width", width * numCol)
.attr("height", height * (newarr.length / numCol));
svg.selectAll(".donut")
.data(d3.values(dataObj))
.enter()
.append("g")
.attr("class", "donut")
.each(drawDonut);
function drawDonut(data, index) {
var color = ["#00338D", "#dedede"];
var pie = d3.pie()
.sortValues(null)
.value(function(d) {
return d
})(data);
var arc = d3.arc()
.outerRadius(radius - 10)
.innerRadius(radius - (radius / 1.9));
var labelArc = d3.arc()
.outerRadius(radius - 31)
.innerRadius(radius - 31);
var xPos = 75 + ((index % numCol) * width),
yPos = 50 + (Math.floor(index / numCol) * height);
var group = svg
.append("g")
.attr("transform", "translate(" + xPos + "," + yPos + ")");
var g = group.selectAll("arc")
.data(pie)
.enter().append("g")
.attr("class", "arc");
function easeInverse(ease) {
return function(e) {
var min = 0,
max = 1;
while (max - min > 1e-3) {
var mid = (max + min) * 0.5;
emid = ease(mid);
if (emid > e) {
max = mid;
} else {
min = mid;
}
}
return max;
}
}
var inverseCubic = easeInverse(d3.easeCubic);
var oneOver2Pi = 1.0 / (2 * Math.PI);
var total_msec = 900;
g.append("path")
.style("fill", function(d, i) {
return color[i];
})
.transition()
.ease(d3.easeLinear)
.delay(function(d) {
return total_msec * inverseCubic(d.startAngle * oneOver2Pi);
})
.duration(function(d) {
return total_msec * (inverseCubic(d.endAngle * oneOver2Pi) - inverseCubic(d.startAngle * oneOver2Pi));
})
.attrTween("d", arcTween);
function arcTween(d) {
var i = d3.interpolate(inverseCubic(d.startAngle * oneOver2Pi), inverseCubic(d.endAngle * oneOver2Pi));
return function(t) {
d.endAngle = 2 * Math.PI * d3.easeCubic(i(t));
return arc(d);
}
}
g.append("text")
.attr("transform", "translate(0,5) scale(1.4)")
.attr("font-weight", "bold")
.attr("class", "st0 donutsTextElemnt")
.attr("font-size", "11px")
.attr("text-anchor", "middle")
.html(data[0] + "%");
svg.append("text")
.attr("transform", "translate(" + (xPos) + "," + (yPos + height / 2.4) + ") scale(.75)")
.attr("text-anchor", "middle")
.text(newarr[index]);
}
</script>
</body>
</html>