SVG画饼状图

另外一个版本

by Mike Lin

JavaScript

const data = {
  size: 230,
  sectors: [
    {
      percentage: 0.45,
      label: 'Thing 1'
    },
    {
      percentage: 0.21,
      label: 'Thing Two'
    },
    {
      percentage: 0.11,
      label: 'Another Thing'
    },
    {
      percentage: 0.23,
      label: 'Pineapple'
    }
  ]
}
function calculateSectors(info) {
  const sectors = [];
  const colors = [
    '#61C0BF', '#DA507A', '#BB3D49', '#DB4547'
  ];

  const radius = info.size / 2;
  let arcSweep;
  let x = 0;
  let y = 0;
  let X = 0;
  let Y = 0;
  let R = 0;

  info.sectors.map((item, key) => {
    // 角度
    const angle = 360 * item.percentage;

    /* 计算对应区块的弧度 */
    const angleCalc = (angle > 180) ? 360 - angle : angle;
    const radian = (angleCalc * Math.PI) / 180;

    /* 求出斜边的长度 */
    const hypotenuse = Math.sqrt((2 * radius * radius) -
      (2 * radius * radius * Math.cos(radian)));

    /* 计算角度的对边的长度*/
    if (angleCalc <= 90) {
      x = radius * Math.sin(radian);
    } else {
      x = radius * Math.sin(((180 - angleCalc) * Math.PI) / 180);
    }

    /* 计算角度的邻边的长度*/
    y = Math.sqrt((hypotenuse * hypotenuse) - (x * x));
    Y = y;

    /* 得到实际的绝对X轴坐标*/
    if (angle <= 180) {
      X = radius + x;
      arcSweep = 0;
    } else {
      X = radius - x;
      arcSweep = 1;
    }

    sectors.push({
      percentage: item.percentage,
      label: item.label,
      color: colors[key],
      arcSweep,
      L: radius,
      X,
      Y,
      R
    });

    R += angle;
  })
  return sectors
}
$(() => {
  const sectors = calculateSectors(data);
  const newSVG = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
  newSVG.setAttributeNS(null, 'style', `width: ${data.size}px; height: ${data.size}px`);
  $('.g-stat-pie').append(newSVG)


  sectors.map((sector) => {
    const newSector = document.createElementNS('http://www.w3.org/2000/svg', 'path');
    newSector.setAttributeNS(null, 'fill', sector.color);
    newSector.setAttributeNS(null, 'd', `M${sector.L},${sector.L}...