我希望构建一个放射状图表可视化,它可以很好地定位在我的页面上,x和y协调或位于div的中心。
它工作得很好,直到我在svg路径元素上添加了缩放动画。现在,我的整个放射图都放在左上角了,我无法把它拿出来。
你能帮忙吗?非常感谢。
const svg = d3
.select("#radial-chart")
.append("svg")
.attr("width", w)
.attr("height", h);
const handleMouseOver = (d, i, n) => {
svg.selectAll("path").transition().duration(300).style("opacity", 0.35);
d3.select(n[i]).transition().duration(300).style("opacity", 0.35);
};
const handleMouseOut = (d, i, n) => {
svg
.selectAll("path")
.transition()
.duration(300)
.style("opacity", 0.35)
.style("stroke-width", 0);
};
const handleClick = (d, i, n) => {
if (
$("#arc0").hasClass("selected") &&
$("#arc1").hasClass("selected") &&
$("#arc2").hasClass("selected") &&
$("#arc3").hasClass("selected") &&
$("#arc4").hasClass("selected") &&
$("#arc5").hasClass("selected") &&
$("#arc6").hasClass("selected") &&
$("#arc7").hasClass("selected") &&
$("#arc8").hasClass("selected")
) {
$(".arc").removeClass("selected");
$(".image").removeClass("selected");
} else {}
};
const handleNoClick = (d, i, n) => {
if (!$("#arc0").hasClass("selected") &&
!$("#arc1").hasClass("selected") &&
!$("#arc2").hasClass("selected") &&
!$("#arc3").hasClass("selected") &&
!$("#arc4").hasClass("selected") &&
!$("#arc5").hasClass("selected") &&
!$("#arc6").hasClass("selected") &&
!$("#arc7").hasClass("selected") &&
!$("#arc8").hasClass("selected")
) {
$(".arc").addClass("selected");
$(".image").addClass("selected");
} else {}
};
var h = 800
var w = 800
const arc = d3.arc();
var arcData = [{
domain: "1",
innerRadius: 0,
outerRadius: h / 1.75,
startAngle: (Math.PI * -20) / 180,
endAngle: (Math.PI * 20) / 180,
},
{
domain: " 2 ",
innerRadius: 0,
outerRadius: 300,
startAngle: (Math.PI * 20) / 180,
endAngle: (Math.PI * 60) / 180,
},
{
domain: "3",
innerRadius: 0,
outerRadius: 280,
startAngle: (Math.PI * 60) / 180,
endAngle: (Math.PI * 100) / 180,
},
{
domain: "4",
innerRadius: 0,
outerRadius: 260,
startAngle: (Math.PI * 100) / 180,
endAngle: (Math.PI * 140) / 180,
},
{
domain: "5",
innerRadius: 0,
outerRadius: 240,
startAngle: (Math.PI * 140) / 180,
endAngle: (Math.PI * 180) / 180,
},
{
domain: "6",
innerRadius: 0,
outerRadius: 220,
startAngle: (Math.PI * 180) / 180,
endAngle: (Math.PI * 220) / 180,
},
{
domain: "7",
innerRadius: 0,
outerRadius: 200,
startAngle: (Math.PI * 220) / 180,
endAngle: (Math.PI * 260) / 180,
},
{
domain: "8",
innerRadius: 0,
outerRadius: 150,
startAngle: (Math.PI * 300) / 180,
endAngle: (Math.PI * 340) / 180,
},
{
domain: "9",
innerRadius: 0,
outerRadius: 100,
startAngle: (Math.PI * 260) / 180,
endAngle: (Math.PI * 300) / 180,
},
];
// Order needs to be from JSON
var colorScale = d3
.scaleOrdinal()
.domain([
"1",
" 2 ",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
])
.range([
"#f7941e",
"#233f92",
"#14385c",
"#007ac1",
"#4c3b2d",
"#94c83d",
"#0000a0",
"#440099",
"#e7253d",
]);
const slices = arcData.map((d) => arc(d));
svg
.selectAll("path")
.data(slices)
.enter()
.append("path")
.attr("transform", "translate(325,550)")
.attr("d", (d) => d)
.attr("id", (d, i) => "arc" + i)
.style("fill", (d, i) => colorScale(i))
.style("z-index", 100)
.style("opacity", 0.5)
.attr("class", "arc selected")
.attr('transform', 'scale(0,0)')
.on("mouseover", handleMouseOver)
.on("mouseout", handleMouseOut)
.transition().transition()
.delay(400)
.duration(function(d, i) {
return 70 * i
})
.attr('transform', 'scale(1,1)')
.attr()
.on("click", function(d, i) {
handleClick();
d3.select(this).classed(
"selected",
d3.select(this).classed("selected") ? false : true
);
d3.select("image#arc" + i).classed(
"selected",
d3.select(this).classed("selected") ? true : false
);
handleNoClick();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id='radial-chart'></div>
您的问题是因为一个元素一次只能有一个属性。在这种情况下,您为每个路径指定了transform="translate(325,550)"
,但随后将其替换为transform="scale(0, 0)"
。
幸运的是,您可以将这些转换链接在一起:transform="translate(325,550) scale(0, 0)"
,它按顺序应用它们。动画之后,这将变为transform="translate(325,550) scale(1, 1)"
var h = 800
var w = 800
const arc = d3.arc();
const svg = d3
.select("#radial-chart")
.append("svg")
.attr("width", w)
.attr("height", h);
const handleMouseOver = (d, i, n) => {
svg.selectAll("path").transition().duration(300).style("opacity", 0.35);
d3.select(n[i]).transition().duration(300).style("opacity", 0.35);
};
const handleMouseOut = (d, i, n) => {
svg
.selectAll("path")
.transition()
.duration(300)
.style("opacity", 0.35)
.style("stroke-width", 0);
};
const handleClick = (d, i, n) => {
if (
$("#arc0").hasClass("selected") &&
$("#arc1").hasClass("selected") &&
$("#arc2").hasClass("selected") &&
$("#arc3").hasClass("selected") &&
$("#arc4").hasClass("selected") &&
$("#arc5").hasClass("selected") &&
$("#arc6").hasClass("selected") &&
$("#arc7").hasClass("selected") &&
$("#arc8").hasClass("selected")
) {
$(".arc").removeClass("selected");
$(".image").removeClass("selected");
} else {}
};
const handleNoClick = (d, i, n) => {
if (!$("#arc0").hasClass("selected") &&
!$("#arc1").hasClass("selected") &&
!$("#arc2").hasClass("selected") &&
!$("#arc3").hasClass("selected") &&
!$("#arc4").hasClass("selected") &&
!$("#arc5").hasClass("selected") &&
!$("#arc6").hasClass("selected") &&
!$("#arc7").hasClass("selected") &&
!$("#arc8").hasClass("selected")
) {
$(".arc").addClass("selected");
$(".image").addClass("selected");
} else {}
};
var arcData = [{
domain: "1",
innerRadius: 0,
outerRadius: h / 1.75,
startAngle: (Math.PI * -20) / 180,
endAngle: (Math.PI * 20) / 180,
},
{
domain: " 2 ",
innerRadius: 0,
outerRadius: 300,
startAngle: (Math.PI * 20) / 180,
endAngle: (Math.PI * 60) / 180,
},
{
domain: "3",
innerRadius: 0,
outerRadius: 280,
startAngle: (Math.PI * 60) / 180,
endAngle: (Math.PI * 100) / 180,
},
{
domain: "4",
innerRadius: 0,
outerRadius: 260,
startAngle: (Math.PI * 100) / 180,
endAngle: (Math.PI * 140) / 180,
},
{
domain: "5",
innerRadius: 0,
outerRadius: 240,
startAngle: (Math.PI * 140) / 180,
endAngle: (Math.PI * 180) / 180,
},
{
domain: "6",
innerRadius: 0,
outerRadius: 220,
startAngle: (Math.PI * 180) / 180,
endAngle: (Math.PI * 220) / 180,
},
{
domain: "7",
innerRadius: 0,
outerRadius: 200,
startAngle: (Math.PI * 220) / 180,
endAngle: (Math.PI * 260) / 180,
},
{
domain: "8",
innerRadius: 0,
outerRadius: 150,
startAngle: (Math.PI * 300) / 180,
endAngle: (Math.PI * 340) / 180,
},
{
domain: "9",
innerRadius: 0,
outerRadius: 100,
startAngle: (Math.PI * 260) / 180,
endAngle: (Math.PI * 300) / 180,
},
];
// Order needs to be from JSON
var colorScale = d3
.scaleOrdinal()
.domain([
"1",
" 2 ",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
])
.range([
"#f7941e",
"#233f92",
"#14385c",
"#007ac1",
"#4c3b2d",
"#94c83d",
"#0000a0",
"#440099",
"#e7253d",
]);
const slices = arcData.map((d) => arc(d));
svg
.selectAll("path")
.data(slices)
.enter()
.append("path")
.attr("d", (d) => d)
.attr("id", (d, i) => "arc" + i)
.style("fill", (d, i) => colorScale(i))
.style("z-index", 100)
.style("opacity", 0.5)
.attr("class", "arc selected")
.attr('transform', 'translate(325,550) scale(0,0)')
.on("mouseover", handleMouseOver)
.on("mouseout", handleMouseOut)
.transition().transition()
.delay(400)
.duration(function(d, i) {
return 70 * i
})
.attr('transform', 'translate(325,550) scale(1,1)')
.on("click", function(d, i) {
handleClick();
d3.select(this).classed(
"selected",
d3.select(this).classed("selected") ? false : true
);
d3.select("image#arc" + i).classed(
"selected",
d3.select(this).classed("selected") ? true : false
);
handleNoClick();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id='radial-chart'></div>