Skip to content
Chart.js Line, Bar & Mixed Charts — Complete Guide with Examples

Chart.js Line, Bar & Mixed Charts — Complete Guide with Examples

DodaTech Updated Jun 6, 2026 10 min read

Line and bar charts are the most common chart types in data visualization. Chart.js makes both simple while offering deep customization for multi-series, stacking, axis configuration, and mixed chart combinations.

What You’ll Learn

By the end of this tutorial, you’ll build single and multi-series line charts with custom point styling and fill areas, create vertical and horizontal bar charts with grouped and stacked bars, build mixed charts combining bars and lines with dual y-axes, configure cartesian axes with tick formatting, labels, and grid lines, and use logarithmic and time scales for specialized data.

Prerequisites: You should understand the Chart.js configuration structure — the type, data, and options pattern.

When to Use Line vs Bar

This is the most common question beginners ask:

  • Line charts: Show trends over time (monthly sales, stock prices, temperature changes). The connected points emphasize the direction and rate of change.
  • Bar charts: Compare quantities across categories (sales by product, population by country, votes by candidate). The bar lengths make it easy to compare magnitudes side by side.

Real-world use: Durga Antivirus Pro uses both types on its dashboard. A line chart shows detected threats per minute over 24 hours (trend). A bar chart compares total threats by category — malware vs phishing vs ransomware (comparison). A mixed chart overlays both to show how the trend line relates to category totals.

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"]
    style B fill:#f97316,stroke:#c2410c,color:#fff
    style A fill:#e5e7eb,stroke:#9ca3af,color:#374151
    style E fill:#22c55e,stroke:#16a34a,color:#22c55e
  

Line Chart

A line chart connects data points with a line, making it easy to see trends.

new Chart(ctx, {
  type: 'line',
  data: {
    labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
    datasets: [{
      label: 'Revenue',
      data: [12000, 19000, 15000, 22000, 18000, 25000],
      borderColor: 'rgb(54, 162, 235)',
      backgroundColor: 'rgba(54, 162, 235, 0.1)',
      fill: true,
      tension: 0.4,        // curve smoothness
      pointRadius: 4,
      pointHoverRadius: 6
    }]
  },
  options: {
    responsive: true,
    plugins: {
      title: { display: true, text: 'Monthly Revenue' }
    },
    scales: {
      y: {
        beginAtZero: true,
        ticks: { callback: (v) => '$' + v }
      }
    }
  }
})

Making a Multi-Series Line Chart

Compare two or more datasets on the same chart:

datasets: [
  {
    label: 'Revenue 2024',
    data: [12000, 19000, 15000, 22000, 18000, 25000],
    borderColor: 'rgb(54, 162, 235)',
    tension: 0.4
  },
  {
    label: 'Revenue 2023',
    data: [10000, 15000, 12000, 18000, 14000, 20000],
    borderColor: 'rgb(255, 99, 132)',
    borderDash: [5, 5],   // dashed line
    tension: 0.4
  }
]

The borderDash property helps distinguish the two lines — dashed for the previous year, solid for the current year.

Line Chart Options Reference

PropertyEffect
tension: 0.4Curve smoothness (0 = straight lines, 0.4 = default smooth)
fill: trueFill the area below the line to the x-axis
fill: 'origin'Fill to the zero axis
fill: '-1'Fill to the previous dataset (for stacked fills)
stepped: trueStep interpolation instead of smooth curves
borderDash: [5, 5]Dashed line pattern [dash, gap]
spanGaps: falseSkip null data points instead of connecting

Bar Chart

Bar charts compare values across categories.

Basic Vertical Bar Chart

new Chart(ctx, {
  type: 'bar',
  data: {
    labels: ['Product A', 'Product B', 'Product C', 'Product D'],
    datasets: [{
      label: 'Sales',
      data: [45, 80, 60, 95],
      backgroundColor: [
        'rgba(255, 99, 132, 0.7)',
        'rgba(54, 162, 235, 0.7)',
        'rgba(255, 206, 86, 0.7)',
        'rgba(75, 192, 192, 0.7)'
      ],
      borderWidth: 2,
      borderRadius: 4
    }]
  },
  options: {
    responsive: true,
    scales: { y: { beginAtZero: true } }
  }
})

Horizontal Bar Chart

Swap the axes by setting indexAxis: 'y':

type: 'bar',
options: {
  indexAxis: 'y'  // bars go horizontal
}

Use horizontal bars when category labels are long (they fit better along the y-axis) or when you have many categories.

Grouped Bar Chart (Multiple Series)

Add more datasets for grouped comparison:

datasets: [
  { label: '2024', data: [45, 80, 60, 95], backgroundColor: 'rgba(54, 162, 235, 0.7)' },
  { label: '2023', data: [35, 70, 55, 80], backgroundColor: 'rgba(255, 99, 132, 0.7)' }
]

Stacked Bar Chart

Stack datasets on top of each other instead of grouping side by side:

options: {
  scales: {
    x: { stacked: true },
    y: { stacked: true, beginAtZero: true }
  }
}

Stacked bars are useful for showing “part of whole” — e.g., total sales broken down by product category over time.


Mixed Chart (Bar + Line)

Sometimes you need two chart types together. For example, bar chart for revenue and a line chart for the growth rate on the same canvas.

new Chart(ctx, {
  type: 'bar',   // Default type
  data: {
    labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
    datasets: [
      {
        label: 'Revenue ($K)',
        type: 'bar',             // This dataset is a bar
        data: [120, 190, 150, 220, 180, 250],
        backgroundColor: 'rgba(54, 162, 235, 0.7)',
        order: 2                  // Draw behind the line
      },
      {
        label: 'Growth Rate (%)',
        type: 'line',            // This dataset is a line
        data: [5, 8, 3, 12, 7, 10],
        borderColor: 'rgb(255, 99, 132)',
        tension: 0.4,
        yAxisID: 'y1',           // Use secondary y-axis
        order: 1                  // Draw in front
      }
    ]
  },
  options: {
    responsive: true,
    plugins: {
      title: { display: true, text: 'Revenue & Growth' }
    },
    scales: {
      y: {
        type: 'linear', position: 'left',
        title: { display: true, text: 'Revenue ($K)' }
      },
      y1: {
        type: 'linear', position: 'right',
        title: { display: true, text: 'Growth Rate (%)' },
        grid: { drawOnChartArea: false },  // Don't overlay grid
        beginAtZero: true
      }
    }
  }
})

What’s happening:

  1. Each dataset overrides the default type — some are bar, others line
  2. The line uses yAxisID: 'y1' to use a secondary axis on the right
  3. grid: { drawOnChartArea: false } on y1 prevents grid lines from overlapping visually
  4. The order property controls draw order — bars behind, lines in front

Cartesian Axis Configuration

Fine-tune your axes for clear, professional charts.

scales: {
  x: {
    type: 'category',
    position: 'bottom',
    title: { display: true, text: 'Month', color: '#666', font: { size: 14, weight: 'bold' } },
    ticks: {
      color: '#666', font: { size: 12 },
      maxRotation: 45,       // Rotate long labels
      autoSkip: true,        // Skip labels if they overlap
      autoSkipPadding: 10,
      callback: (value) => value.substring(0, 3)  // Truncate to 3 chars
    },
    grid: { display: true, color: 'rgba(0,0,0,0.05)' }
  },
  y: {
    type: 'linear',
    position: 'left',
    beginAtZero: true,
    title: { display: true, text: 'Value' },
    ticks: {
      callback: (value) => '$' + value.toLocaleString()
    },
    grace: '5%'   // Add 5% padding above the max value
  }
}

Logarithmic Scale

Use when data spans multiple orders of magnitude (e.g., 1, 10, 100, 1000):

scales: { y: { type: 'logarithmic', title: { display: true, text: 'Log Scale' } } }

Time Scale

For date-based data, use the time scale. Requires the date adapter:

npm install chart.js chartjs-adapter-date-fns date-fns
scales: {
  x: {
    type: 'time',
    time: {
      unit: 'month',
      displayFormats: { month: 'MMM yyyy' },
      tooltipFormat: 'MMM yyyy'
    },
    min: new Date('2023-01-01'),
    max: new Date('2024-01-01')
  }
}

Common Mistakes Beginners Make

1. Bar Chart Baseline Not at Zero

Always set beginAtZero: true on the y-axis for bar charts. Starting at a non-zero value exaggerates differences and misleads viewers.

2. Line Chart Fill Obscuring Other Data

// Wrong: fill to axis, hiding bars behind it
fill: true

// Better: fill to previous dataset or no fill
fill: '-1'   // fill to previous dataset
fill: false  // no fill

3. Mixed Chart Scales Misaligned

When combining bar and line with different units, always use separate y-axes (yAxisID: 'y1') and configure both axes with appropriate titles and ranges.

4. Long Labels Overlapping

Set maxRotation, autoSkip, and autoSkipPadding on ticks to prevent label overlap. For very long labels, use horizontal bars.

5. Not Handling Large Datasets

Chart.js v4 handles thousands of points, but performance drops eventually. For large datasets, enable showLine: false for scatter plots, use the decimation plugin, or aggregate data on the server.


Practice Questions

  1. What property makes a bar chart horizontal instead of vertical? indexAxis: 'y' in the options.

  2. How do you create a mixed chart with both bars and lines? Each dataset overrides the type property. Set type: 'bar' on some datasets and type: 'line' on others.

  3. What does yAxisID: 'y1' do in a mixed chart? It assigns a dataset to a secondary y-axis, allowing different units (e.g., dollars on the left, percentage on the right).

  4. What does the tension property do in a line chart? It controls the Bezier curve smoothness. 0 = straight lines, 0.4 = default smooth, higher = more curved.

  5. When should you use stacked bars instead of grouped bars? When you want to show both the total and the composition — e.g., total sales broken down by region, where each region stacks on top of the others.

Challenge

Create a sales dashboard with three linked charts:

  • A grouped bar chart comparing monthly sales for two years
  • A line chart showing the same data with a visible trend line
  • A mixed chart with bars for revenue and a line for growth percentage on a secondary axis
  • Sync the data across all three charts when clicking a “Randomize” button

FAQ

How do I make a bar chart with both positive and negative values?

Set beginAtZero: false and configure min/max on the y-axis. Bars below zero point downward automatically.

Can I have different bar colors per data point?

Yes. Pass an array of colors to backgroundColor instead of a single string. Each data point gets the corresponding color from the array.

How do I create an area chart?

Set fill: true on a line chart dataset and use backgroundColor with transparency for the fill area. The area below the line will be filled.

What is the difference between categoryPercentage and barPercentage?

categoryPercentage controls the width of the category group. barPercentage controls the width of individual bars within that group. Together they control bar spacing.

How do I add data labels on top of bars?

Use the chartjs-plugin-datalabels plugin. It positions text values at the top (or any position) of each bar.

Try It Yourself: Sales Dashboard

A three-card dashboard with a bar chart, a line chart, and a mixed chart — all using the same monthly sales data.

<!DOCTYPE html>
<html>
<head>
  <title>Sales Dashboard</title>
  <style>
    body { font-family: sans-serif; padding: 20px; }
    .dashboard { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; max-width: 900px; }
    .card { border: 1px solid #ddd; border-radius: 8px; padding: 15px; }
    .card h3 { margin: 0 0 10px 0; font-size: 14px; color: #666; }
    .card.full { grid-column: 1 / -1; }
  </style>
</head>
<body>
  <h2>Sales Dashboard</h2>
  <div class="dashboard">
    <div class="card"><h3>Monthly Sales (Bar)</h3><canvas id="barChart"></canvas></div>
    <div class="card"><h3>Sales Trend (Line)</h3><canvas id="lineChart"></canvas></div>
    <div class="card full"><h3>Revenue & Growth Rate (Mixed)</h3><canvas id="mixedChart"></canvas></div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
  <script>
    const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']
    new Chart(document.getElementById('barChart'), { type: 'bar', data: { labels: months, datasets: [{ label: 'Sales', data: [65,59,80,81,56,95], backgroundColor: 'rgba(54,162,235,0.7)', borderColor: 'rgb(54,162,235)', borderWidth: 1 }] }, options: { responsive: true, plugins: { legend: { display: false } }, scales: { y: { beginAtZero: true } } } })
    new Chart(document.getElementById('lineChart'), { type: 'line', data: { labels: months, datasets: [{ label: '2024', data: [65,59,80,81,56,95], borderColor: 'rgb(54,162,235)', tension: 0.4 }, { label: '2023', data: [45,49,60,71,46,75], borderColor: 'rgb(255,99,132)', borderDash: [5,5], tension: 0.4 }] }, options: { responsive: true, scales: { y: { beginAtZero: true } } } })
    new Chart(document.getElementById('mixedChart'), { type: 'bar', data: { labels: months, datasets: [{ label: 'Revenue ($K)', type: 'bar', data: [120,190,150,220,180,250], backgroundColor: 'rgba(54,162,235,0.7)', order: 2 }, { label: 'Growth (%)', type: 'line', data: [5,8,3,12,7,10], borderColor: 'rgb(255,99,132)', tension: 0.4, yAxisID: 'y1', order: 1 }] }, options: { responsive: true, plugins: { legend: { position: 'bottom' } }, scales: { y: { position: 'left', title: { display: true, text: 'Revenue ($K)' } }, y1: { position: 'right', title: { display: true, text: 'Growth (%)' }, grid: { drawOnChartArea: false }, beginAtZero: true } } } })
  </script>
</body>
</html>

What to expect: A three-panel dashboard. Top left shows a bar chart, top right a dual-line chart with dashed/solid lines, and the bottom panel shows a mixed chart with revenue bars and a growth percentage line on a secondary axis.


What’s Next

TutorialWhat You’ll Learn
Pie, Doughnut, Radar & PolarCircular charts, proportional data, multi-dimensional comparison
Scatter & Bubble ChartsX/Y relationships, three-variable bubbles

Related topics: Chart.js Basics, Data Visualization best practices.

What’s Next

Congratulations on completing this Chartjs Line Bar 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