Activity Rings Progress Chart — Apache ECharts

An activity rings chart displays goal completion for several metrics at once using concentric radial progress arcs, in the style popularized by fitness trackers. Each ring is a partial arc with rounded end caps that starts at the top (12 o'clock) and sweeps clockwise in proportion to how close the metric is to its goal, with a distinct color per metric and a faint background track showing the full circle. It is instantly recognizable and ideal for at-a-glance comparison of progress across a small set of related goals, filling the general radial-progress gap that needle gauges (`gauge-basic`) and polar bars (`polar-bar`) do not cover.

Activity Rings Progress Chart rendered with Apache ECharts

JavaScript source (Apache ECharts)

// anyplot.ai
// gauge-activity-rings: Activity Rings Progress Chart
// Library: echarts 5.5.1 | JavaScript 22.22.3
// Quality: 89/100 | Created: 2026-06-14
//# anyplot-orientation: square

const t = window.ANYPLOT_TOKENS;

// --- Data (daily fitness goals with spread completion levels) ---
const metrics = [
  { name: "Steps",      value: 4521, goal: 10000, display: "4,521 / 10,000 steps" },
  { name: "Active Min", value: 57,   goal: 60,    display: "57 / 60 min"           },
  { name: "Stand",      value: 12,   goal: 12,    display: "12 / 12 hr"            },
];
const colors = [t.palette[0], t.palette[1], t.palette[2]];

// Track colors: ring hue at ~15% opacity
const trackColors = [
  "rgba(0,158,115,0.15)",
  "rgba(196,117,253,0.15)",
  "rgba(68,103,163,0.15)",
];

// Percentage completion (clamped to 100)
const pcts = metrics.map(m =>
  parseFloat(Math.min(m.value / m.goal * 100, 100).toFixed(1))
);

// Ring geometry: outer → inner, larger radii to fill canvas vertically
// Outer ring bottom: 600 + 74%×600 = 1044px; gap to text row ~24px
const radii = ["74%", "56%", "38%"];
const ringW  = 34;  // CSS px (→ 68 physical px at DPR 2)

// --- Init ---
const chart = echarts.init(document.getElementById("container"));

// --- Option ---
chart.setOption({
  animation: false,
  backgroundColor: "transparent",

  title: {
    text: "gauge-activity-rings · javascript · echarts · anyplot.ai",
    left: "center",
    top: 24,
    textStyle: { color: t.ink, fontSize: 22, fontWeight: "normal" },
  },

  // Center labels + bottom values row (1200×1200 CSS mount, center at 600,600)
  // Inner ring inner radius: 38%×600 − 34 = 194px → center space spans y 406–794
  graphic: {
    elements: [
      // "Daily Goals" header
      {
        type: "text",
        style: {
          x: 600, y: 542,
          text: "Daily Goals",
          fill: t.inkSoft,
          fontSize: 16,
          textAlign: "center",
          fontStyle: "italic",
        },
      },
      // Per-ring: "Metric: XX.X%" in the ring's color
      ...metrics.map((m, i) => ({
        type: "text",
        style: {
          x: 600, y: 576 + i * 38,
          text: `${m.name}: ${pcts[i]}%`,
          fill: colors[i],
          fontSize: 22,
          fontWeight: "bold",
          textAlign: "center",
        },
      })),
      // Bottom row: raw values for each metric, just below outer ring
      {
        type: "text",
        style: {
          x: 600, y: 1068,
          text: metrics.map(m => m.display).join("   ·   "),
          fill: t.inkSoft,
          fontSize: 16,
          textAlign: "center",
        },
      },
    ],
  },

  series: metrics.map((m, i) => ({
    type: "gauge",
    startAngle: 90,
    endAngle: -270,   // full circle clockwise from top
    min: 0,
    max: 100,
    radius: radii[i],
    center: ["50%", "50%"],
    progress: {
      show: true,
      roundCap: true,
      width: ringW,
      itemStyle: { color: colors[i] },
    },
    axisLine: {
      roundCap: true,
      lineStyle: { width: ringW, color: [[1, trackColors[i]]] },
    },
    pointer:   { show: false },
    axisTick:  { show: false },
    splitLine: { show: false },
    axisLabel: { show: false },
    detail:    { show: false },
    title:     { show: false },
    data: [{ value: pcts[i] }],
  })),
});

Part of Activity Rings Progress Chart on anyplot.ai.

Other implementations