Range Interval Chart — MUI X Charts

A range interval chart displays min-max ranges or intervals as vertical or horizontal bars/segments for each category, making it ideal for visualizing uncertainty bounds, confidence intervals, or value spreads. Unlike error bars which extend from a central data point, range intervals show the full span between two values as a filled bar or line segment, emphasizing the range itself rather than deviation from a center. This visualization excels at comparing ranges across multiple categories simultaneously.

Range Interval Chart rendered with MUI X Charts

Renders

JavaScript source (MUI X Charts)

// anyplot.ai
// range-interval: Range Interval Chart
// Library: muix 7.29.1 | JavaScript 22.23.2
// Quality: 88/100 | Created: 2026-09-02
import { BarChart } from "@mui/x-charts/BarChart";
import { useXScale, useYScale } from "@mui/x-charts/hooks";

const t = window.ANYPLOT_TOKENS;
const TITLE = "range-interval · javascript · muix · anyplot.ai";
const TITLE_HEIGHT = 56;

// --- Data (in-memory, deterministic) ----------------------------------------
// Annual base-salary ranges by department at a mid-size tech company ($k).
const departments = [
  "Customer Support",
  "Marketing",
  "Sales",
  "Data Analytics",
  "Product Management",
  "DevOps & Infrastructure",
  "Software Engineering",
  "Engineering Leadership",
];
const minSalary = [42, 48, 45, 62, 78, 88, 85, 120];
const maxSalary = [58, 72, 95, 98, 125, 145, 165, 210];

const axisMin = 30;
const axisMax = 220;

// --- Range bars ---------------------------------------------------------
// Community BarChart has no native floating-bar / range primitive. Rather than
// faking one out of two stacked series (transparent spacer + visible span —
// which hits a real react-spring paint bug on the first stacked item), the
// range is drawn directly with the chart's own x/y scale hooks: the same
// documented extension point the community surface offers for custom
// overlays (see e.g. ChartsReferenceLine). No animation, no clip-path — a
// single deterministic <rect> per category.
function RangeBars() {
  const xScale = useXScale();
  const yScale = useYScale();
  const barHeight = yScale.bandwidth() * 0.72;
  const capRadius = barHeight * 0.34;

  return (
    <g>
      {departments.map((dept, i) => {
        const x0 = xScale(minSalary[i]);
        const x1 = xScale(maxSalary[i]);
        const yMid = yScale(dept) + yScale.bandwidth() / 2;
        const y = yMid - barHeight / 2;
        return (
          <g key={dept}>
            <rect
              x={Math.min(x0, x1)}
              y={y}
              width={Math.abs(x1 - x0)}
              height={barHeight}
              rx={4}
              fill={t.palette[0]}
              stroke={t.ink}
              strokeWidth={1}
            >
              <title>
                {dept}: ${minSalary[i]}k – ${maxSalary[i]}k
              </title>
            </rect>
            {/* Endpoint markers: small ink-ringed caps pin the exact min/max bounds. */}
            <circle
              cx={x0}
              cy={yMid}
              r={capRadius}
              fill={t.palette[0]}
              stroke={t.ink}
              strokeWidth={1}
            />
            <circle
              cx={x1}
              cy={yMid}
              r={capRadius}
              fill={t.palette[0]}
              stroke={t.ink}
              strokeWidth={1}
            />
          </g>
        );
      })}
    </g>
  );
}

// --- Chart (default-exported component — the harness mounts it) -------------
export default function Chart() {
  const chartHeight = window.ANYPLOT_SIZE.height - TITLE_HEIGHT;

  return (
    <div
      style={{
        width: window.ANYPLOT_SIZE.width,
        height: window.ANYPLOT_SIZE.height,
      }}
    >
      <div
        style={{
          height: TITLE_HEIGHT,
          lineHeight: `${TITLE_HEIGHT}px`,
          paddingLeft: 24,
          fontSize: 22,
          fontWeight: 500,
          color: t.ink,
        }}
      >
        {TITLE}
      </div>
      <BarChart
        width={window.ANYPLOT_SIZE.width}
        height={chartHeight}
        layout="horizontal"
        skipAnimation
        margin={{ left: 240, right: 40, top: 24, bottom: 70 }}
        series={[]}
        xAxis={[
          {
            min: axisMin,
            max: axisMax,
            domainLimit: "strict",
            valueFormatter: (v) => `$${v}k`,
            label: "Annual Base Salary ($ thousands)",
            labelStyle: { fontSize: 16 },
            tickLabelStyle: { fontSize: 14 },
          },
        ]}
        yAxis={[
          {
            scaleType: "band",
            data: departments,
            tickLabelStyle: { fontSize: 14 },
          },
        ]}
        grid={{ vertical: true }}
        slots={{ noDataOverlay: () => null }}
        slotProps={{ legend: { hidden: true } }}
      >
        <RangeBars />
      </BarChart>
    </div>
  );
}

Retrieve this implementation

Runnable source as JSON, for any HTTP client: https://api.anyplot.ai/specs/range-interval/muix/code. Any spec id and library id listed in llms-full.txt fit the same URL shape; every URL below is complete and callable.

{
  "spec_id": "range-interval",
  "language": "javascript",
  "library": "muix",
  "page": "https://anyplot.ai/range-interval/javascript/muix",
  "hub": "https://anyplot.ai/range-interval",
  "code_json": "https://api.anyplot.ai/specs/range-interval/muix/code",
  "spec_json": "https://api.anyplot.ai/specs/range-interval",
  "render_light_png": "https://storage.googleapis.com/anyplot-images/plots/range-interval/javascript/muix/plot-light.png",
  "render_dark_png": "https://storage.googleapis.com/anyplot-images/plots/range-interval/javascript/muix/plot-dark.png",
  "interactive_light_html": "https://storage.googleapis.com/anyplot-images/plots/range-interval/javascript/muix/plot-light.html",
  "interactive_dark_html": "https://storage.googleapis.com/anyplot-images/plots/range-interval/javascript/muix/plot-dark.html",
  "quality_score": 88.0,
  "license": "MIT",
  "guide": "https://anyplot.ai/llms.txt"
}

Part of Range Interval Chart on anyplot.ai.

Other implementations