Skip to content
Chart.js Reference & Cheatsheet — Complete v4 API Guide

Chart.js Reference & Cheatsheet — Complete v4 API Guide

DodaTech Updated Jun 6, 2026 12 min read

This is your go-to Chart.js v4 reference for daily development. It covers every chart type, every dataset property, each configuration option, and the complete plugin API. Bookmark this page and keep it open while coding.

Real-world use: The Durga Antivirus Pro threat dashboard uses almost every option listed here — from time scales for the 24-hour threat timeline to custom plugins for threshold annotations and external tooltips for detailed threat metadata.

Where This Fits in Your Learning Path

    flowchart LR
    A["Chart.js Basics"] --> B["Line, Bar & Mixed Charts"]
    B --> C["Pie, Doughnut, Radar & Polar"]
    C --> D["Scatter & Bubble Charts"]
    D --> E["Chart.js Advanced"]
    E --> F["**Reference & Cheatsheet**"]
    style F fill:#f97316,stroke:#c2410c,color:#fff
    style A fill:#e5e7eb,stroke:#9ca3af,color:#374151
  

Getting Started

<!-- CDN (latest) -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

<!-- Specific version (recommended for production) -->
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.7/dist/chart.umd.min.js"></script>
var ctx = document.getElementById("myChart").getContext("2d");
new Chart(ctx, {
    type: "bar",
    data: { labels: [], datasets: [] },
    options: {}
});

Chart Types

type: "bar"          // Vertical and horizontal bars
type: "line"         // Line chart with optional fill
type: "radar"        // Radar/spider chart
type: "pie"          // Pie chart
type: "doughnut"     // Doughnut chart with center hole
type: "polarArea"    // Polar area chart
type: "bubble"       // Bubble chart (data: {x, y, r})
type: "scatter"      // Scatter plot (data: {x, y})

Data Structure Reference

data: {
    labels: ["A", "B", "C"],           // Category labels (not used in scatter/bubble)
    datasets: [                         // Array of data series
        {
            label: "Series 1",          // Displayed in legend and tooltip
            data: [10, 20, 30],         // Values, or {x, y}, or {x, y, r}

            // ---- Styling (all types) ----
            backgroundColor: "color",
            borderColor: "color",
            borderWidth: 1,
            hoverBackgroundColor: "color",
            hoverBorderColor: "color",
            hoverBorderWidth: 1,

            // ---- Bar-specific ----
            borderRadius: 0,
            barPercentage: 0.9,          // Width of bar as % of category
            categoryPercentage: 0.8,     // Width of category as % of step
            barThickness: "flex",        // Fixed pixel width or "flex"
            maxBarThickness: undefined,

            // ---- Line & radar ----
            fill: false,                 // Fill area under line
            tension: 0,                  // Curve smoothness (0 = straight lines)
            pointRadius: 3,
            pointBackgroundColor: "color",
            pointBorderColor: "color",
            pointBorderWidth: 1,
            pointHoverRadius: 5,
            pointHitRadius: 10,          // Hover detection zone
            borderDash: [],              // e.g. [5, 5] for dashed line
            borderDashOffset: 0,
            stepped: false,              // "before", "after", "middle", or false

            // ---- Scatter & bubble ----
            showLine: false,             // Connect scatter points with line
            hitRadius: 10,               // Extended hover detection

            // ---- All types ----
            order: 0,                    // Drawing order (lower = drawn first)
            hidden: false,               // Hide dataset on load
            xAxisID: "x",                // Which x-axis to use
            yAxisID: "y",                // Which y-axis to use
            pointStyle: "circle",        // "circle", "rect", "star", "triangle", etc.

            // ---- Pie & doughnut ----
            weight: 1,                   // Relative thickness of dataset

            // ---- Animation override ----
            animation: { /* per-dataset animation config */ }
        }
    ]
}

Options Reference

Core Options

options: {
    responsive: true,                    // Resize with container
    maintainAspectRatio: true,           // Preserve width/height ratio
    aspectRatio: 2,                      // width / height
    resizeDelay: 0,                      // Debounce resize (ms)
    devicePixelRatio: window.devicePixelRatio,
    color: "#666",                       // Default text color
    borderColor: "rgba(0,0,0,0.1)",     // Default border
    backgroundColor: "transparent",      // Default background
    layout: { padding: 0 },             // Padding around chart area
    locale: "en-US"                      // Number formatting locale
}

Animation

options: {
    animation: {
        duration: 1000,                  // Animation length in ms
        easing: "easeInOutQuad",         // Acceleration curve
        delay: undefined,                // function(ctx) { return delay; }
        loop: false,                     // Loop animation
        onProgress: function(anim) {},   // Callback during animation
        onComplete: function(anim) {},   // Callback after animation

        // Disable specific property animations
        colors: true,
        numbers: {
            properties: ["x", "y", "r"],
            type: "number"
        }
    },

    // Disable all animation:
    animation: false
}

Interaction & Hover

options: {
    interaction: {
        mode: "nearest",                 // "point", "nearest", "index", "dataset", "x", "y"
        intersect: true,                 // Must hover directly over element
        axis: "x",                       // "x", "y", "xy", "r"
        includeInvisible: false
    },
    hover: {
        mode: "nearest",
        intersect: true,
        animationDuration: 400
    },
    onHover: function(event, elements, chart) {},
    onClick: function(event, elements, chart) {}
}

Plugins Reference

Title

plugins: {
    title: {
        display: true,
        text: "Chart Title",             // String or [string, string] for multiline
        position: "top",                 // "top", "bottom", "left", "right"
        align: "center",                 // "start", "center", "end"
        color: "#333",
        font: { size: 18, weight: "bold", family: "sans-serif" },
        padding: { top: 10, bottom: 10 }
    }
}

Subtitle

plugins: {
    subtitle: {
        display: true,
        text: "Subtitle",
        position: "top",
        color: "#666",
        font: { size: 14 },
        padding: { bottom: 10 }
    }
}

Legend

plugins: {
    legend: {
        display: true,
        position: "top",                 // "top", "left", "bottom", "right", "chartArea"
        align: "center",                 // "start", "center", "end"
        reverse: false,
        maxWidth: undefined,
        fullSize: true,
        labels: {
            boxWidth: 40,
            boxHeight: 12,
            color: "#666",
            font: { size: 12 },
            padding: 10,
            pointStyle: "circle",        // "circle", "rect", "line", "rectRounded"
            usePointStyle: false,
            borderRadius: 0,
            generateLabels: function(chart) {},
            filter: function(item, chart) { return true; },
            sort: function(a, b) { return 0; }
        },
        onClick: function(event, legendItem, legend) {
            // Toggle dataset visibility
            var index = legendItem.datasetIndex;
            var meta = legend.chart.getDatasetMeta(index);
            meta.hidden = meta.hidden === null ?
                !legend.chart.data.datasets[index].hidden : null;
            legend.chart.update();
        },
        onHover: function(event, legendItem, legend) {},
        onLeave: function(event, legendItem, legend) {}
    }
}

Tooltip

plugins: {
    tooltip: {
        enabled: true,
        mode: "nearest",
        intersect: true,
        position: "average",              // "average", "nearest"
        backgroundColor: "rgba(0,0,0,0.8)",
        titleColor: "#fff",
        bodyColor: "#fff",
        titleFont: { size: 14, weight: "bold" },
        bodyFont: { size: 13 },
        footerFont: { size: 12 },
        padding: 10,
        cornerRadius: 4,
        caretSize: 6,
        caretPadding: 4,
        xAlign: undefined,                // "left", "center", "right"
        yAlign: undefined,                // "top", "center", "bottom"
        borderColor: undefined,
        borderWidth: 0,
        displayColors: true,
        boxPadding: 4,
        usePointStyle: false,

        callbacks: {
            // --- Title (top line) ---
            title: function(items) { return items[0].label; },
            beforeTitle: function(items) { return ""; },
            afterTitle: function(items) { return ""; },

            // --- Body (main content) ---
            label: function(context) {
                return context.dataset.label + ": " + context.formattedValue;
            },
            beforeLabel: function(context) { return ""; },
            afterLabel: function(context) { return ""; },

            // --- Color dot next to label ---
            labelColor: function(context) {
                return {
                    borderColor: "transparent",
                    backgroundColor: context.dataset.borderColor
                };
            },
            labelTextColor: function(context) { return "#fff"; },

            // --- Body section (before/after all labels) ---
            beforeBody: function(items) { return ""; },
            afterBody: function(items) { return ""; },

            // --- Footer (bottom line) ---
            footer: function(items) { return ""; },
            beforeFooter: function(items) { return ""; },
            afterFooter: function(items) { return ""; }
        },

        itemSort: function(a, b) { return 0; },
        filter: function(item) { return true; },
        external: function(context) {}     // Custom HTML tooltip (see advanced tutorial)
    }
}

Callback Context Object Properties

Inside any tooltip callback, the context object provides:

context.chart        // The chart instance
context.dataset      // The dataset object
context.datasetIndex // Index of the dataset
context.dataIndex    // Index of the data point
context.label        // Label for this point
context.parsed.x     // Parsed x value
context.parsed.y     // Parsed y value
context.parsed.r     // Parsed radius (bubble only)
context.parsed._custom // Additional parsed values
context.formattedValue // Value formatted by locale
context.raw          // Original data point
context.element      // The chart element

Scales Reference

Linear / Category Axis

scales: {
    x: {
        type: "category",                 // "category", "linear", "logarithmic", "time"
        position: "bottom",               // "bottom", "top", "left", "right"
        min: undefined,
        max: undefined,
        reverse: false,
        stacked: false,                   // Stack datasets
        beginAtZero: false,
        grace: 0,                         // "5%" or number (space above max)

        title: {
            display: true,
            text: "Axis Title",
            color: "#666",
            font: { size: 14, weight: "bold" }
        },

        ticks: {
            color: "#666",
            font: { size: 12 },
            maxTicksLimit: undefined,
            maxRotation: 45,
            minRotation: 0,
            stepSize: undefined,          // Fixed interval between ticks
            autoSkip: true,
            autoSkipPadding: 10,
            labelOffset: 0,
            padding: 3,
            mirror: false,
            count: undefined,
            callback: function(value, index, ticks) { return value; }
        },

        grid: {
            display: true,
            color: "rgba(0,0,0,0.05)",
            lineWidth: 1,
            drawBorder: true,
            drawOnChartArea: true,
            drawTicks: true,
            tickLength: 8,
            tickColor: "rgba(0,0,0,0.05)",
            tickWidth: 1,
            circular: false,              // Radar only
            offset: false                 // Offset grid from axes
        }
    },

    // Secondary y-axis (dual axes)
    y1: {
        type: "linear",
        position: "right",
        grid: { drawOnChartArea: false }  // Don't draw grid for this axis
    }
}

Radial Axis (Radar & Polar Area)

scales: {
    r: {
        beginAtZero: true,
        min: 0,
        max: 100,
        ticks: {
            backdropColor: "rgba(255,255,255,0.8)",
            stepSize: 20,
            callback: function(value) { return value; }
        },
        pointLabels: {
            display: true,
            font: { size: 12 },
            color: "#666",
            padding: 20
        },
        grid: {
            circular: false,               // Circular grid lines
            color: "rgba(0,0,0,0.1)"
        },
        angleLines: {
            display: true,
            color: "rgba(0,0,0,0.1)"
        }
    }
}

Time Scale

Requires the chartjs-adapter-date-fns package:

// npm install chartjs-adapter-date-fns
// or use CDN bundle (see CDN Links below)

scales: {
    x: {
        type: "time",
        time: {
            unit: "month",                 // "millisecond", "second", "minute", "hour", "day", "week", "month", "quarter", "year"
            displayFormats: {
                month: "MMM yyyy",
                day: "MMM d"
            },
            tooltipFormat: "MMM d, yyyy",
            isoWeekday: true,
            parser: "yyyy-MM-dd"           // Only needed if data format isn't ISO
        },
        adapters: {
            date: {}                       // Adapter config (auto-detected)
        }
    }
}

Elements Reference

options: {
    elements: {
        point: {
            radius: 3,
            backgroundColor: "color",
            borderColor: "color",
            borderWidth: 1,
            hitRadius: 10,
            hoverRadius: 5,
            hoverBorderWidth: 1,
            pointStyle: "circle"           // "circle", "cross", "crossRot", "dash", "line", "rect", "rectRounded", "rectRot", "star", "triangle"
        },
        line: {
            tension: 0,
            backgroundColor: "color",
            borderColor: "color",
            borderWidth: 2,
            borderDash: [],
            borderDashOffset: 0,
            capBezierPoints: true,
            fill: false,
            stepped: false
        },
        bar: {
            backgroundColor: "color",
            borderColor: "color",
            borderWidth: 0,
            borderRadius: 0,
            borderSkipped: "start"         // "start", "end", false
        },
        arc: {                              // Pie, doughnut, polar area
            backgroundColor: "color",
            borderColor: "#fff",
            borderWidth: 2,
            hoverOffset: 4
        }
    }
}

Plugins API (Custom Plugins)

var myPlugin = {
    id: "pluginName",                      // Required: unique identifier
    start: function() {},
    stop: function() {},
    beforeInit: function(chart, args, opts) {},
    afterInit: function(chart, args, opts) {},
    beforeUpdate: function(chart, args, opts) {},
    afterUpdate: function(chart, args, opts) {},
    beforeLayout: function(chart, args, opts) {},
    afterLayout: function(chart, args, opts) {},
    beforeRender: function(chart, args, opts) {},
    afterRender: function(chart, args, opts) {},
    beforeDraw: function(chart, args, opts) {},
    afterDraw: function(chart, args, opts) {},
    beforeDatasetsDraw: function(chart, args, opts) {},
    afterDatasetsDraw: function(chart, args, opts) {},
    beforeEvent: function(chart, args, opts) {},
    afterEvent: function(chart, args, opts) {},
    resize: function(chart, size, opts) {},
    destroy: function(chart) {},
    defaults: {},                          // Default plugin options
    defaultRoutes: {}
};

Chart.register(myPlugin);                 // Must register to activate

Default Colors

// Chart.js built-in array of 7 colors:
var defaultColors = [
    "rgb(255, 99, 132)",    // Red
    "rgb(54, 162, 235)",    // Blue
    "rgb(255, 205, 86)",    // Yellow
    "rgb(75, 192, 192)",    // Green
    "rgb(153, 102, 255)",   // Purple
    "rgb(255, 159, 64)",    // Orange
    "rgb(201, 203, 207)"    // Grey
];

Utility Methods

// Parsed value access in callbacks
context.parsed.y         // Parsed y value
context.parsed.x         // Parsed x value
context.parsed.r         // Parsed radius (bubble)
context.formattedValue   // Formatted string

// Chart instance methods
chart.update()             // Animate update
chart.update("none")      // Instant update (no animation)
chart.reset()              // Reset to initial animation state
chart.render()             // Force re-render
chart.stop()               // Stop running animations
chart.resize()             // Resize to container dimensions
chart.resize(600, 300)    // Resize to specific dimensions
chart.destroy()            // Destroy chart (prevent memory leaks)

// Data access
chart.data.datasets       // Datasets array
chart.data.labels         // Labels array
chart.options             // Options object

// Dataset visibility
chart.getDatasetMeta(index)     // Dataset metadata (includes hidden state)
chart.getDataVisibility(index)
chart.setDataVisibility(index, bool)
chart.toggleDataVisibility(index)

Events

// Hover and click handlers
chart.options.onHover = function(event, elements, chart) {};
chart.options.onClick = function(event, elements, chart) {};

// elements is an array of: { element, datasetIndex, index }
// event is the native mouse event

CDN Links

<!-- Chart.js v4 (latest) -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

<!-- Chart.js v4 specific version -->
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.7/dist/chart.umd.min.js"></script>

<!-- With date adapter (for time scales) -->
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.7/dist/chart.umd.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns@3/dist/chartjs-adapter-date-fns.bundle.min.js"></script>

Common npm Packages

npm install chart.js                                          # Core library
npm install chartjs-adapter-date-fns                          # Time scale adapter
npm install chartjs-plugin-datalabels                         # Data labels on chart
npm install chartjs-plugin-annotation                         # Annotation lines/boxes
npm install chartjs-plugin-zoom                               # Zoom & pan
npm install chartjs-plugin-streaming                          # Real-time streaming data

Common Mistakes

1. Referencing Deprecated v3 Options

Chart.js v4 changed several option paths. scales.xAxes and scales.yAxes (v3) are now scales.x and scales.y (v4). If your v3 code doesn’t work, check that you’re using the flat scale syntax.

2. Not Calling chart.destroy() in SPAs

In single-page applications, navigating away without calling chart.destroy() leaves the chart listening to resize events — causing memory leaks. Always destroy in a cleanup hook.

3. Forgetting type: "linear" on Scatter Axes

Scatter and bubble charts require type: "linear" on both axes. Without it, Chart.js uses the default category axis, which spaces points evenly and destroys the visual relationship.

4. Time Scale Without the Adapter

Using type: "time" requires installing chartjs-adapter-date-fns. Without it, the chart throws an error about a missing adapter.

5. Plugin Registration Order

Plugins must be registered with Chart.register() before creating the chart. Registering after chart creation has no effect.


Practice Questions

  1. What property do you set to create a dashed line in a line chart? borderDash: [5, 5] — an array of alternating dash and gap lengths.

  2. How do you create a chart with two y-axes (left and right)? Define two y-scales: y with position: "left" and y1 with position: "right". Reference them in datasets via yAxisID: "y" and yAxisID: "y1".

  3. What type of scale does a scatter chart need on both axes? type: "linear" — scatter charts plot one numeric variable against another, requiring linear scales on both axes.

  4. How do you access the raw data point inside a tooltip callback? context.raw returns the original data object. For bubble charts, this gives you { x, y, r }.

  5. What must you install to use time scales? The chartjs-adapter-date-fns package (via npm or CDN). Without it, type: "time" throws an error.

Challenge

Open the Chart.js Advanced dashboard example and try to:

  • Add a second y-axis on the right showing a different scale
  • Change the tooltip to show values as currency (hint: use the label callback with formattedValue)
  • Add a gradient background using a custom plugin

FAQ

What changed between Chart.js v3 and v4?

The most significant change is scale configuration. v3 used scales: { xAxes: [...], yAxes: [...] } (arrays), v4 uses scales: { x: {...}, y: {...} } (objects). Plugin API and tooltip callbacks also changed.

How do I create a chart with mixed types (bars + line)?

Use type: "bar" at the top level, then override per dataset with the dataset’s own type property. One dataset can have type: "line" while others remain bars.

What is the difference between responsive and maintainAspectRatio?

responsive resizes the chart when its container changes size. maintainAspectRatio keeps the width/height ratio fixed during resize. Both are true by default.

How do I format tooltip values as currency?

Use the label callback: label: function(ctx) { return ctx.dataset.label + ': $' + ctx.parsed.y.toFixed(2); }.

Can I use Chart.js without a build system?

Yes. Use the CDN script tag. It registers Chart as a global variable — no npm or bundler needed.

How do I add data labels on top of bars?

Install chartjs-plugin-datalabels and register it. It adds the datalabels plugin option where you can configure position, format, and styling of inline labels.

What’s Next

TutorialWhat You’ll Learn
Chart.js BasicsReview fundamentals or start from scratch
Chart.js AdvancedAnimation, custom plugins, interactive dashboards

Related topics: JavaScript array methods (map, reduce, filter) are used everywhere in Chart.js data preparation. CSS grid and flexbox control chart container sizing.

What’s Next

Congratulations on completing this Chartjs Reference tutorial! Here’s where to go from here:

  • Practice daily — Consistency is more important than long study sessions
  • Build a project — Apply what you learned by building something real
  • Explore related topics — Check out other tutorials in the same category
  • Join the community — Discuss with other learners and share your progress

Remember: every expert was once a beginner. Keep coding!

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro