Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

180
Visualizações
How can I create a doughnut chart with rounded edges only on one end of each segment?

I'm trying to build a doughnut chart with rounded edges only on one side. My problem is that I have both sided rounded and not just on the one side. Also can't figure out how to do more foreground arcs not just one.

    const tau = 2 * Math.PI; // http://tauday.com/tau-manifesto
    const arc = d3.arc()
        .innerRadius(80)
        .outerRadius(100)
        .startAngle(0)
        .cornerRadius(15);
    const svg = d3.select("svg"),
        width = +svg.attr("width"),
        height = +svg.attr("height"),
        g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

Background arc, but I'm not sure if this is even needed?

const background = g.append("path")
        .datum({endAngle: tau})
        .style("fill", "#ddd")
        .attr("d", arc);

    const data = [ .51];
    const c = d3.scaleThreshold()
          .domain([.200,.205,.300,.310, .501, 1])
          .range(["green","#ddd", "orange","#ddd", "red"]);
    Const pie = d3.pie()
          .sort(null)
          .value(function(d) {
            return d;
          });

Only have one foreground, but need to be able to have multiple:

 const  foreground = g.selectAll('.arc')
        .data(pie(data))
        .enter()
        .append("path")
        .attr("class", "arc")
        .datum({endAngle: 3.8})
        .style("fill", function(d) {
            return c(d.value);
          })
        .attr("d", arc)

What am I doing wrong?

var tau = 2 * Math.PI; // http://tauday.com/tau-manifesto

// An arc function with all values bound except the endAngle. So, to compute an
// SVG path string for a given angle, we pass an object with an endAngle
// property to the `arc` function, and it will return the corresponding string.
var arc = d3.arc()
    .innerRadius(80)
    .outerRadius(100)
    .startAngle(0)
    .cornerRadius(15);

// Get the SVG container, and apply a transform such that the origin is the
// center of the canvas. This way, we don’t need to position arcs individually.
var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height"),
    g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

// Add the background arc, from 0 to 100% (tau).
var background = g.append("path")
    .datum({endAngle: tau})
    .style("fill", "#ddd")
    .attr("d", arc);

var data = [ .51];
var c = d3.scaleThreshold()
      .domain([.200,.205,.300,.310, .501, 1])
      .range(["green","#ddd", "orange","#ddd", "red"]);
var pie = d3.pie()
      .sort(null)
      .value(function(d) {
        return d;
      });
// Add the foreground arc in orange, currently showing 12.7%.
var foreground = g.selectAll('.arc')
    .data(pie(data))
    .enter()
    .append("path")
    .attr("class", "arc")
    .datum({endAngle: 3.8})
    .style("fill", function(d) {
        return c(d.value);
      })
    .attr("d", arc)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="960" height="500"></svg>

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

The documentation states, that the corner radius is applied to both ends of the arc. Additionally, you want the arcs to overlap, which is also not the case.

You can add the one-sided rounded corners the following way:

  1. Use arcs arc with no corner radius for the data.
  2. Add additional path objects corner just for the rounded corner. These need to be shifted to the end of each arc.
  3. Since corner has rounded corners on both sides, add a clipPath that clips half of this arc. The clipPath contains a path for every corner. This is essential for arcs smaller than two times the length of the rounded corners.
  4. raise all elements of corner to the front and then sort them descending by index, so that they overlap the right way.

const arc = d3.arc()
    .innerRadius(50)
    .outerRadius(70);
const arc_corner = d3.arc()
    .innerRadius(50)
    .outerRadius(70)
    .cornerRadius(10);

const svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height"),
    g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

const clipPath = g.append("clipPath")
  .attr("id", "clip_corners");

const c = d3.scaleQuantile()
  .range(["#f7fcf0","#e0f3db","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#08589e"]);

const pie = d3.pie().value(d => d);

function render(values) {
  c.domain(values);
  const arcs = pie(values);
  const corners = pie(values).map(d => {
    d.startAngle = d.endAngle - 0.2;
    d.endAngle = d.endAngle + 0.2;
    return d;
  });
  const clip = pie(values).map(d => {
    d.startAngle = d.endAngle - 0.01;
    d.endAngle = d.endAngle + 0.2;
    return d;
  });

  g.selectAll(".arc")
      .data(arcs)
      .join("path")
        .attr("class", "arc")
        .style("fill", d => c(d.value))
        .attr("d", arc);

  clipPath.selectAll("path")
    .data(clip)
    .join("path")
      .attr("d", arc);

  g.selectAll(".corner")
    .data(corners)
    .join("path")
      .raise()
      .attr("class", "corner")
      .attr("clip-path", "url(#clip_corner)")
      .style("fill", d => c(d.value))
      .attr("d", arc_corner)
      .sort((a, b) => b.index - a.index);
}

function randomData() {
  const num = Math.ceil(8 * Math.random()) + 2;
  const values = Array(num).fill(0).map(d => Math.random());
  render(values);
}

d3.select("#random_data")
  .on("click", randomData);

 randomData();
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.3.0/d3.min.js"></script>
<button id="random_data">
Random data
</button>
<svg width="150" height="150"></svg>

I changed the dependency to the current version of d3.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda