代码之家  ›  专栏  ›  技术社区  ›  SERG

将每个饼状扇区拆分为更小的扇区

  •  0
  • SERG  · 技术社区  · 3 年前

    我有5个扇区,我需要将每个扇区分成更小的扇区,它们之间的间距为1px(就像我在扇区5中用红线画的一样)。但当我尝试这样做时,较小的扇区与大扇区(馅饼)之间的填充重叠。

    我的代码在这里jsfidde.net/fcxvrbd/2/和下面:

    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.6.1/d3.min.js"></script>
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Indicator test</title>
      <script src="https://d3js.org/d3.v7.min.js"></script>
      <style>
        body,
        html {
          margin: 0px;
          height: 0px;
          font-family: sans-serif;
        }
    
        .parent {
          display: flex;
          flex-direction: row;
          flex-wrap: wrap;
          justify-content: center;
          align-items: center;
          height: 100vh;
        }
    
        .child {
          border: 1px solid red
        }
    
        div.tooltip {
          position: absolute;
          text-align: center;
          padding: 2px;
          /* font: 12px sans-serif; */
          background: lightsteelblue;
          border: 0px;
          border-radius: 8px;
        }
    
        .highlight {
          fill: steelblue;
        }
    
        .hover {
          fill: #69c !important;
          stroke: #333 !important;
          stroke-width: 2px !important;
        }
    
        .d3map {
          border: 1px solid red;
        }
    
        .map-title {
          font-size: 30px
        }
    
        .map-text {
          /* font-size: 12px; */
          text-align: center;
        }
    
        .map-text-container {
          display: flex;
          flex-direction: column;
          font-size: 14px;
          line-height: 1;
          align-items: center;
          max-width: 155px;
        }
      </style>
    </head>
    
    
    <body>
    
      <div id="main">
        <div class="parent">
          <div id="d3map" class="child" style="width:100%; height:100%; "></div>
        </div>
      </div>
    
      <script>
    
        createMap("d3map")
    
        function createMap(divId) {
    
          const mainData = {
            cities: []
          }
    
          const svgDiv = document.getElementById(divId).getBoundingClientRect();
          let width = 600;
          let height = 600;
          const radius = width / 2
    
          const svg = d3
            .select("#" + divId)
            .append("svg")
            .attr("viewBox", `0 0 ${width} ${height}`)
    
          ready(null, randomData())
          async function ready(error, data) {
    
            // console.log('data: ', data);
    
            // const numberOfPies = data.children.reduce((partialSum, a) => partialSum + a.children.length, 0);
            const numberOfPies = 5
            console.log("123", numberOfPies);
    
            svg.append("circle")
              .style("stroke", "rgba(0,0,0,0.2)")
              .style("stroke-width", "1")
              .style("fill", "rgba(0,0,0,0)")
              .attr("r", radius - 1)
              .attr("cx", width / 2)
              .attr("cy", height / 2);
    
            const sectors = [...Array(numberOfPies)].map((i, key) => {
              return {
                name: key, size: 10,
              }
            });
            console.log('pie(sectors): ', sectors);
    
            const arc = (offset = 5) => {
              return d3.arc()
                .outerRadius(radius - offset)
                .innerRadius(radius)
            }
    
            const labelArc = d3.arc()
              .innerRadius(150)
              .outerRadius(radius)
    
            // const labelArcCircle = d3.arc()
            //   .innerRadius(210)
            //   .outerRadius(radius)
    
            const pie = d3.pie()
              .startAngle(-90 * Math.PI / 180)
              .endAngle(-90 * Math.PI / 180 + 2 * Math.PI)
              .value(1)
              .padAngle(.05) // space between pies
              .sort(null);
    
            // prepare a helper function
            const lineFunc = d3.line()
              .x(function (d) { return d.x })
              .y(function (d) { return d.y })
    
    
            const labels = svg.append('g')
              .attr("class", "labels")
              .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
    
            labels.selectAll('.pies')
              .data(pie(sectors))
              .enter()
              .append('path')
              .attr('d', labelArc)
              .attr('class', "pies")
              .attr("stroke", "none")
              .attr("fill", d => "gray")
              .style("stroke-width", "1px")
              .style("opacity", d => {
                return d.data.skipThisSector ? 0 : 1
              })
    
    
            labels.selectAll('.lines')
              .data(pie(sectors))
              .enter()
              .append('path')
              .attr('d', d => {
                console.log('d: ', d);
    
                const pies = d3.pie()
                  .startAngle(d.startAngle)
                  .endAngle(d.endAngle)
                  .value(1)
                  .padAngle(.01) // space between pies
                  .sort(null);
    
                labels.selectAll('.piesss')
                  .data(pies(randomData()))
                  .enter()
                  .append('path')
                  .attr('d', labelArc)
                  .attr('class', "pies")
                  .attr("stroke", "none")
                  .attr("fill", d => "red")
                  .style("stroke-width", "1px")
                  .style("opacity", "0.4")
    
    
              })
    
            labels.selectAll(".labelsText")
              .data(pie(sectors))
              .enter()
              .append("text")
              .attr("dx", d => {
                const [x, y] = labelArc.centroid(d)
                return x
              })
              .attr("dy", d => {
                const [x, y] = labelArc.centroid(d)
                return y + 5
              })
              .text(function (d) {
                if (!d.data.skipThisSector) {
                  return d.data.name
                } else {
                  return  //Draw numbers around the circle
                }
              })
              .style("font-size", "8px")
              .style("text-anchor", "middle")
              .attr("transform", function (d) {
                var locationData = this.getBBox();
                var x = locationData.x + (locationData.width / 2);
                var y = locationData.y + (locationData.height / 2);
                let angle = (Math.atan2(y, x) * 180) / Math.PI;
    
                if (angle > 90) angle = 180 + angle
                if (angle < -90 && angle > -180) angle = 180 + angle
                var result = 'translate(' + x + ',' + y + ')';
                result += `rotate(${angle})`;
                result += 'translate(' + (-x) + ',' + (-y) + ')';
    
                return result;
              })
              .style("text-anchor", function (d) {
                var locationData = this.getBBox();
                var x = locationData.x + (locationData.width / 2);
                var y = locationData.y + (locationData.height / 2);
                let angle = (Math.atan2(y, x) * 180) / Math.PI;
                if (angle > 90) return "end"
                if (angle < -90 && angle > -180) return "end"
                return "start"
              })
              .attr("fill", d => {
                return "white"
              })
          }
        }
    
        function randomData() {
    
          return [...Array(Math.floor(Math.random() * 11))].map((i, key) => {
            return {
              name: key, size: 10,
            }
          });
    
        }
    
    
        const delay = ms => new Promise(res => setTimeout(res, ms));
      </script>
    </body>
    
    </html>

    enter image description here

    0 回复  |  直到 3 年前