Hand-gezeichnetes Tortendiagramm (mlcrough Renderer-API)

Treibt die `mlcrough`-Engine-Extension über Engine.getMlcrough() an. Das User-Skript berechnet jeden Slice-Pfad und gibt ihn an die `.path()`-Methode mit `multi-hachure`-Füllung — jeder Slice wird einzeln gezeichnet. Der hervorgehobene Slice ist radial herausgezogen. Labels über rohe SVG-<text>-Tags mit Stroke-Paint für Lesbarkeit.

Hand-drawn pie chart
Hand-drawn pie chart — Hand-gezeichnetes Tortendiagramm (mlcrough Renderer-API)
JavaScript
// Hand-drawn pie chart via Engine.getMlcrough().
// demo_rough_piechart.js
//!NOIMAGE
//!OUTPUT: OUTPUT
//!PARAM: WIDTH:integer=600,min=300,max=1200
//!PARAM: HEIGHT:integer=600,min=300,max=1200
//!PARAM: SCALE:number=2,min=1,max=4,step=0.5

const r = Engine.getMlcrough({
  width: WIDTH, height: HEIGHT, background: "#f8f9fa",
});

const data = [
  { label: "A", value: 30, color: "#e74c3c" },
  { label: "B", value: 50, color: "#3498db", highlight: true },
  { label: "C", value: 20, color: "#2ecc71" },
  { label: "D", value: 40, color: "#f1c40f" },
];

const cx = WIDTH / 2;
const cy = HEIGHT / 2;
const radius = Math.min(WIDTH, HEIGHT) * 0.36;
const total = data.reduce((s, d) => s + d.value, 0);
let start = -Math.PI / 2;

data.forEach(d => {
  const slice = (d.value / total) * 2 * Math.PI;
  const end = start + slice;

  // Exploded slice — offset the centre.
  let x = cx, y = cy;
  if (d.highlight) {
    const mid = start + slice / 2;
    x += Math.cos(mid) * 20;
    y += Math.sin(mid) * 20;
  }

  const x1 = x + Math.cos(start) * radius;
  const y1 = y + Math.sin(start) * radius;
  const x2 = x + Math.cos(end) * radius;
  const y2 = y + Math.sin(end) * radius;
  const largeArc = slice > Math.PI ? 1 : 0;

  r.path(
    `M ${x} ${y} L ${x1} ${y1} A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2} Z`,
    { fill: d.color, fillStyle: "multi-hachure", hachureAngle: 45, hachureGap: 5 },
  );

  // Label inside the slice.
  const labA = start + slice / 2;
  const lr = radius * 0.7;
  r.raw(`<text x="${x + Math.cos(labA) * lr}" y="${y + Math.sin(labA) * lr}" text-anchor="middle" dominant-baseline="middle" font-family="sans-serif" font-size="16" font-weight="bold" fill="#fff" stroke="#000" stroke-width="0.5" paint-order="stroke">${d.label}</text>`);

  start = end;
});

r.toImage(SCALE).save(OUTPUT);

// © 2026 Michael Lechner · mlc OpticScript · https://mlcgo.eu · Elastic License 2.0