Styled Line Plot — Chart.js

A line plot using different line styles (solid, dashed, dotted, dash-dot) to distinguish multiple data series. This is especially useful for black-and-white printing or when color distinction is insufficient.

Styled Line Plot rendered with Chart.js

Renders

JavaScript source (Chart.js)

// anyplot.ai
// line-styled: Styled Line Plot
// Library: chartjs 4.4.7 | JavaScript 22.23.2
// Quality: 94/100 | Created: 2026-09-05

//# anyplot-orientation: landscape
const t = window.ANYPLOT_TOKENS;

// --- Data (in-memory, deterministic) ---------------------------------------
function lcg(seed) {
  let state = seed;
  return () => {
    state = (state * 1664525 + 1013904223) % 4294967296;
    return state / 4294967296;
  };
}
const rand = lcg(42);

const minutes = Array.from({ length: 60 }, (_, i) => i);

function coreTemperature(baseline, rampRate, plateau, noiseScale) {
  return minutes.map((minute) => {
    const ramp = Math.min(minute * rampRate, plateau - baseline);
    const noise = (rand() - 0.5) * noiseScale;
    return Math.round((baseline + ramp + noise) * 10) / 10;
  });
}

// Dash patterns tuned so each style stays distinguishable even when the
// chart is scaled down to a mobile thumbnail: the dotted style uses a round
// cap with a wide gap (reads as separated dots, not a near-solid line) and
// the dash-dot gaps are enlarged so the dot doesn't merge into the dashes.
const series = [
  { label: "Core 1", data: coreTemperature(46, 0.75, 82, 1.2), borderDash: [], cap: "butt", pointStyle: "circle" },
  { label: "Core 2", data: coreTemperature(45, 0.58, 74, 1.0), borderDash: [16, 8], cap: "butt", pointStyle: "rect" },
  { label: "Core 3", data: coreTemperature(47, 0.44, 66, 1.4), borderDash: [1, 9], cap: "round", pointStyle: "triangle" },
  { label: "Core 4", data: coreTemperature(44, 0.3, 58, 0.9), borderDash: [16, 8, 3, 8], cap: "butt", pointStyle: "rectRot" },
];

// --- Mount -----------------------------------------------------------------
const canvas = document.createElement("canvas");
document.getElementById("container").appendChild(canvas);

// Custom Chart.js plugin (afterDatasetsDraw) that annotates the hottest
// core's final reading — a deliberate focal point/data-storytelling touch
// rather than treating all four series with equal visual weight.
const peakAnnotationPlugin = {
  id: "peakAnnotation",
  afterDatasetsDraw(chart) {
    const hottest = series.reduce((best, s, i) => (s.data[s.data.length - 1] > series[best].data[series[best].data.length - 1] ? i : best), 0);
    const meta = chart.getDatasetMeta(hottest);
    const point = meta.data[meta.data.length - 1];
    if (!point) return;
    const value = series[hottest].data[series[hottest].data.length - 1];
    const { ctx } = chart;
    ctx.save();
    ctx.font = "600 15px sans-serif";
    ctx.fillStyle = t.palette[hottest];
    ctx.textAlign = "left";
    ctx.textBaseline = "middle";
    ctx.fillText(`${series[hottest].label} hottest · ${value.toFixed(1)}°C`, point.x + 12, point.y);
    ctx.restore();
  },
};

// --- Chart -----------------------------------------------------------------
new Chart(canvas, {
  type: "line",
  data: {
    labels: minutes,
    datasets: series.map((s, i) => ({
      label: s.label,
      data: s.data,
      borderColor: t.palette[i],
      backgroundColor: t.palette[i],
      borderDash: s.borderDash,
      borderCapStyle: s.cap,
      borderWidth: 3.5,
      // Sparse markers every 15 minutes reinforce the dash pattern with a
      // distinct point shape per series, so style stays legible even when
      // the dash pattern itself compresses at small thumbnail scales.
      pointStyle: s.pointStyle,
      pointRadius: (ctx) => (ctx.dataIndex % 15 === 0 ? 6 : 0),
      pointBackgroundColor: t.palette[i],
      pointBorderColor: t.palette[i],
      pointHoverRadius: 6,
      tension: 0.25,
    })),
  },
  plugins: [peakAnnotationPlugin],
  options: {
    responsive: true,
    maintainAspectRatio: false,
    animation: false,
    layout: {
      padding: { right: 260 },
    },
    plugins: {
      title: {
        display: true,
        text: "line-styled · javascript · chartjs · anyplot.ai",
        color: t.ink,
        font: { size: 22, weight: "500" },
        padding: { bottom: 24 },
      },
      legend: {
        position: "top",
        labels: { color: t.ink, font: { size: 16 }, boxWidth: 40 },
      },
    },
    scales: {
      x: {
        title: { display: true, text: "Stress Test Duration (minutes)", color: t.ink, font: { size: 16 } },
        ticks: { color: t.inkSoft, font: { size: 14 }, maxTicksLimit: 10 },
        grid: { display: false },
      },
      y: {
        title: { display: true, text: "Core Temperature (°C)", color: t.ink, font: { size: 16 } },
        ticks: { color: t.inkSoft, font: { size: 14 } },
        grid: { color: t.grid },
      },
    },
  },
});

Retrieve this implementation

Runnable source as JSON, for any HTTP client: https://api.anyplot.ai/specs/line-styled/chartjs/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": "line-styled",
  "language": "javascript",
  "library": "chartjs",
  "page": "https://anyplot.ai/line-styled/javascript/chartjs",
  "hub": "https://anyplot.ai/line-styled",
  "code_json": "https://api.anyplot.ai/specs/line-styled/chartjs/code",
  "spec_json": "https://api.anyplot.ai/specs/line-styled",
  "render_light_png": "https://storage.googleapis.com/anyplot-images/plots/line-styled/javascript/chartjs/plot-light.png",
  "render_dark_png": "https://storage.googleapis.com/anyplot-images/plots/line-styled/javascript/chartjs/plot-dark.png",
  "interactive_light_html": "https://storage.googleapis.com/anyplot-images/plots/line-styled/javascript/chartjs/plot-light.html",
  "interactive_dark_html": "https://storage.googleapis.com/anyplot-images/plots/line-styled/javascript/chartjs/plot-dark.html",
  "quality_score": 94.0,
  "license": "MIT",
  "guide": "https://anyplot.ai/llms.txt"
}

Part of Styled Line Plot on anyplot.ai.

Other implementations