简体   繁体   中英

Rotating rectangles on an arc in D3js

I am attempting to position rectangles on d3js arcs at 0, 90, 180 and 270 degrees. Here is a simple example I put together that uses an arc generator to create 4 arcs and the arc.centroid function to place the rectangles at the center points of each arc:

<!DOCTYPE html>
<meta charset="utf-8">
<head>
  <title>Rotate rectangles to arc positions: 0, 90, 180 & 270 </title>
</head>

<style>
path {
    fill: white;
    stroke: black;
}
</style>

<body>
  <svg width="700" height="220">
     <g transform="translate(200, 110)"></g>
  </svg>

  <script src="https://d3js.org/d3.v5.min.js" charset="utf-8"></script>

  <script>
    // Create an arc generator with configuration
    var arcGenerator = d3.arc()
        .innerRadius(80)
        .outerRadius(100);

    var arcData = [
        {startAngle: 0, endAngle: Math.PI * 2 / 4, degree: 0},
        {startAngle: Math.PI * 2 / 4, endAngle: Math.PI, degree: 90},
        {startAngle: Math.PI, endAngle: Math.PI * 3 / 2, degree: 180},
        {startAngle: Math.PI * 3 / 2, endAngle: Math.PI * 2, degree: 270},
    ];

    // Create a path element and set its d attribute
    d3.select('g')
        .selectAll('path')
        .data(arcData)
        .enter()
        .append('path')
        .attr('d', arcGenerator);

    // Add labels, using .centroid() to position
    d3.select('g')
        .selectAll('rect')
        .data(arcData)
        .enter()
        .append('rect')
        .each(function(d) {
            var centroid = arcGenerator.centroid(d);
            d3.select(this)
                .attr('x', centroid[0])
                .attr('y', centroid[1])
                .attr('width', 10)
                .attr('height', 35)
        });
  </script>
</body>
</html>

Here is the result: 该图显示了每个弧的质心位置处的矩形

Instead, I would like each rectangle to be placed at the start or end position of each arc and rotated so that each rectangle is portrait oriented (10 px wide and 35 px long).

Here is my: jsfiddle

Create arc data records for the angles you want and use the centroid() for these dummy arcs

You have some illegal html after the g element.

 // Create an arc generator with configuration var arcGenerator = d3.arc() .innerRadius(80) .outerRadius(100); var arcData = [ {startAngle: 0, endAngle: Math.PI * 2 / 4, degree: 0}, {startAngle: Math.PI * 2 / 4, endAngle: Math.PI, degree: 90}, {startAngle: Math.PI, endAngle: Math.PI * 3 / 2, degree: 180}, {startAngle: Math.PI * 3 / 2, endAngle: Math.PI * 2, degree: 270}, ]; var rectData = arcData.map(d => { return {startAngle: d.startAngle, endAngle:d.startAngle}; }); // Create a path element and set its d attribute d3.select('g') .selectAll('path') .data(arcData) .enter() .append('path') .attr('d', arcGenerator); // Add labels, using .centroid() to position d3.select('g') .selectAll('.grect') .data(rectData) .enter() .append('g') .attr('class', 'grect') .attr('transform', d => { var centroid = arcGenerator.centroid(d); return `translate(${centroid[0]},${centroid[1]})`; }) .append('rect') .attr('x', -5) .attr('y', -17) .attr('width', 10) .attr('height', 35); 
 path { fill: white; stroke: black; } 
 <meta charset="utf-8"> <head> <title>Rotate rectangles to arc positions: 0, 90, 180 and 270 </title> </head> <body> <svg width="700" height="220"> <g transform="translate(200, 110)"></g> </svg> <script src="https://d3js.org/d3.v5.min.js" charset="utf-8"></script> </body> 

Edit

You can create the rectData on the fly.

    d3.select('g')
        .selectAll('.grect')
        .data(arcData)
        .enter()
        .append('g')
        .attr('class', 'grect')
        .attr('transform', d => {
            var centroid = arcGenerator.centroid({startAngle: d.startAngle, endAngle:d.startAngle});
            return `translate(${centroid[0]},${centroid[1]})`;
        })
        .append('rect')
        .attr('x', -5)
        .attr('y', -17)
        .attr('width', 10)
        .attr('height', 35);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM