javascript - 如何为一个简单的 donut 为 SVG Circle 的笔触添加边距

标签 javascript html css svg

我正在尝试构建一个非常简单的圆环图。

这是工作代码:

const countries = [
{'percent': 2,colour: 'red'},
{'percent': 28,colour: 'blue'},
{'percent': 36,colour: 'yellow'},
{'percent': 34,colour: 'orange'}
];


const donutData = countries.map((country, index) => {
  return {
    stroke: country.colour,
    dashoffset: 25 - countries.slice(0, index).reduce((a, b) => a + b.percent, 0),
    dashArray: [country.percent, 100 - country.percent]
  }
});
const div = document.createElement('div');
div.innerHTML = '<svg id="donut" width="100%" height="100%" viewBox="3 3 36 36"></svg>';
document.body.appendChild(div);
document.querySelector('#donut').innerHTML= donutData.reduce((a, item) => {
  return a +
    `<circle 
  	cx="21"
    cy="21"
    fill="transparent"
    r="15.91549430918954"
    stroke-width="2.3"
    stroke="${item.stroke}"
    stroke-dasharray="${item.dashArray[0]} ${item.dashArray[1]}"
    stroke-dashoffset="${item.dashoffset}"></circle>
`;
}, '')

https://jsfiddle.net/miladhi/1dxnkjht/1/

以上工作正常,但尝试添加 stroke-linecap="round"<circle>并且它的形状变平了,笔画在彼此之上。

正如你在这里看到的https://jsfiddle.net/miladhi/x8w4kgdv/ .

我能理解这个问题,但不知道如何在笔划之间添加一点边距以避免难看的堆叠。

我很感激任何建议。

最佳答案

这是你想要的吗?

只需从破折号长度中减去圆形端盖的半径(每端一个)。

只要圆的半径不是特别小,圆帽之间应该恰到好处。

const countries = [
{'percent': 10,colour: 'red'},
{'percent': 20,colour: 'blue'},
{'percent': 36,colour: 'yellow'},
{'percent': 34,colour: 'orange'}
];

const STROKE_WIDTH = 2.3;

const donutData = countries.map((country, index) => {
  // Subtract the radius of the round cap, twice.
  const dashLength = country.percent - STROKE_WIDTH;
  return {
    stroke: country.colour,
    dashoffset: 25 - countries.slice(0, index).reduce((a, b) => a + b.percent, 0),
    dashArray: [dashLength, 100 - dashLength]
  }
});
const div = document.createElement('div');
div.innerHTML = '<svg id="donut" width="100%" height="100%" viewBox="3 3 36 36"></svg>';
document.body.appendChild(div);
document.querySelector('#donut').innerHTML= donutData.reduce((a, item) => {
  return a +
    `<circle 
  	cx="21"
    cy="21"
    fill="transparent"
    r="15.91549430918954"
    stroke-width="${STROKE_WIDTH}"
    stroke-linecap="round"
    stroke="${item.stroke}"
    stroke-dasharray="${item.dashArray[0]} ${item.dashArray[1]}"
    stroke-dashoffset="${item.dashoffset}"></circle>
`;
}, '')

更新

一个稍微优雅地处理短行长度的版本。

const countries = [
{'percent': 10, colour: 'red'},
{'percent': 20, colour: 'blue'},
{'percent': 36, colour: 'yellow'},
{'percent': 33, colour: 'orange'},
{'percent': 1,  colour: 'green'},
];

const STROKE_WIDTH = 2.3;

const donutData = countries.map((country, index) => {
  let dashLength, offsetAdjust, caps;
  if (country.percent >= STROKE_WIDTH) {
    // Subtract the radius of the round cap, twice.
    dashLength = country.percent - STROKE_WIDTH;
    offsetAdjust = STROKE_WIDTH / 2;
    caps = "round";
  } else {
    dashLength = country.percent;
    offsetAdjust = 0;
    caps = "butt";
  }
  return {
    stroke: country.colour,
    dashoffset: 25 - countries.slice(0, index).reduce((a, b) => a + b.percent, 0) - offsetAdjust,
    dashArray: [dashLength, 100 - dashLength],
    caps: caps
  }
});
const div = document.createElement('div');
div.innerHTML = '<svg id="donut" width="100%" height="100%" viewBox="3 3 36 36"></svg>';
document.body.appendChild(div);
document.querySelector('#donut').innerHTML= donutData.reduce((a, item) => {
  return a +
    `<circle 
  	cx="21"
    cy="21"
    fill="transparent"
    r="15.91549430918954"
    stroke-width="${STROKE_WIDTH}"
    stroke-linecap="${item.caps}"
    stroke="${item.stroke}"
    stroke-dasharray="${item.dashArray[0]} ${item.dashArray[1]}"
    stroke-dashoffset="${item.dashoffset}"></circle>
`;
}, '')

关于javascript - 如何为一个简单的 donut 为 SVG Circle 的笔触添加边距,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56335682/

相关文章:

javascript - 检查 parent 是否有类(class),如果有,则将样式应用于该 parent

html - IE 7兼容模式位置:absolute bug

javascript - 使用 jQuery 从多个 div 上的当前 css 值中减去 1

html - Bootstrap 3 - NavBar 跨浏览器问题

javascript - 如何在 javascript [checkform 函数] 中使用循环 for?

php - 获取 mysql 数据进行比较,但不起作用或显示任何内容

Python:从网站获取智能手机的价格

javascript - 我如何知道 IntersectionObserver 滚动方向?

javascript - 两个地点之间的距离

javascript - 如何为我的 HTML 视频添加缓冲