📦معرفی و نصب

Chart.js یکی از محبوب‌ترین کتابخانه‌های جاوااسکریپت برای رسم نمودارهای تعاملی است. بر پایه <canvas> HTML5 کار می‌کند، بدون هیچ وابستگی خارجی.

نصب

<!-- فایل لوکال -->
<script src="chart.umd.min.js"></script>

<!-- CDN -->
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.2/dist/chart.umd.min.js"></script>

/* NPM */
// npm install chart.js
import { Chart } from 'chart.js/auto';

ساختار پایه

<!-- HTML: canvas -->
<canvas id="myChart"></canvas>

// JavaScript
const chart = new Chart(
  document.getElementById('myChart'),
  {
    type:    'bar',       // نوع نمودار
    data:    { labels: [...], datasets: [{...}] },
    options: { responsive: true, ... }
  }
);

انواع نمودار

نوعمقدار typeکاربرد
خطیlineروند زمانی، تغییرات متوالی
میله‌ایbarمقایسه دسته‌ها
دایره‌ایpieنسبت بخش‌ها از کل
دوناتdoughnutمثل pie + متن مرکزی
رادارradarمقایسه چند ویژگی
قطبیpolarAreaمقادیر با اندازه بصری
پراکندهscatterرابطه دو متغیر
حبابیbubbleسه متغیر (x, y, r)
ⓘ ساختار یکسان: همه نمودارها ساختار { type, data, options } یکسانی دارند. فقط با تغییر type، نوع نمودار عوض می‌شود بدون تغییر داده‌ها.

📈نمودار خطی type: 'line'

مناسب نمایش روند تغییرات در طول زمان: فروش ماهانه، بازدید سایت، دمای هوا.

new Chart(ctx, {
  type: 'line',
  data: {
    labels: ['فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور'],
    datasets: [{
      label: 'فروش (میلیون)',
      data: [12, 19, 15, 25, 22, 30],
      borderColor:     '#3498db',
      backgroundColor: 'rgba(52,152,219,0.15)',
      tension: 0.4,          // انحنا: 0=خط مستقیم، 1=منحنی کامل
      fill:    true,         // پر کردن ناحیه زیر خط
      pointRadius: 5,
      borderWidth: 2.5,
    }]
  },
  options: {
    responsive: true,
    plugins: {
      title: { display: true, text: 'آمار فروش ۶ ماهه' }
    },
    scales: {
      y: { beginAtZero: true }
    }
  }
});

Gradient Fill — پر کردن با گرادیان

// گرادیان از بالا به پایین
const gradient = ctx.createLinearGradient(0, 0, 0, 400);
gradient.addColorStop(0,   'rgba(52,152,219,0.6)');  // بالا: پررنگ
gradient.addColorStop(1,   'rgba(52,152,219,0.0)');  // پایین: شفاف

datasets[0].backgroundColor = gradient;  // به جای رنگ ثابت
▶ دمو: نمودار خطی با Gradient

گزینه‌های مهم Dataset

گزینهتوضیح
tensionانحنای خط (0=مستقیم، 0.4=منحنی متوسط)
filltrue=پر کردن ناحیه، false=خط ساده
pointRadiusاندازه نقاط (0=پنهان)
borderDashخط‌چین: [5,5]
steppedtrue=پله‌ای (Step chart)
spanGapsپل زدن روی مقادیر null

📊نمودار میله‌ای type: 'bar'

برای مقایسه مقادیر بین دسته‌ها. با indexAxis: 'y' افقی می‌شود.

new Chart(ctx, {
  type: 'bar',
  data: {
    labels: ['Q1', 'Q2', 'Q3', 'Q4'],
    datasets: [
      { label: 'محصول الف', data: [65, 59, 80, 81], backgroundColor: 'rgba(52,152,219,.8)', borderRadius: 4 },
      { label: 'محصول ب',  data: [28, 48, 40, 19], backgroundColor: 'rgba(231,76,60,.8)',  borderRadius: 4 }
    ]
  },
  options: {
    responsive: true,
    // indexAxis: 'y',  ← برای نمودار افقی
    // scales: { x: { stacked: true }, y: { stacked: true } }  ← انباشته
  }
});
▶ دمو: نمودار میله‌ای چندگانه
⚡ ترفند رنگ‌بندی شرطی: با function-based backgroundColor می‌توانید هر میله را بر اساس مقدارش رنگ‌آمیزی کنید:
backgroundColor: ctx => ctx.parsed.y > 70 ? '#88ce02' : ctx.parsed.y > 40 ? '#3498db' : '#e74c3c'

🍏نمودار دایره‌ای و دونات pie / doughnut

برای نمایش نسبت و سهم هر بخش از کل. تفاوت doughnut فقط وجود سوراخ مرکزی است.

new Chart(ctx, {
  type: 'doughnut',   // یا 'pie'
  data: {
    labels: ['موبایل', 'دسکتاپ', 'تبلت', 'سایر'],
    datasets: [{
      data: [55, 28, 12, 5],
      backgroundColor: ['#3498db', '#e74c3c', '#f1c40f', '#95a5a6'],
      hoverOffset: 8   // بیرون آمدن هنگام hover
    }]
  },
  options: {
    cutout: '60%',   // اندازه سوراخ (0 = pie)
    plugins: { legend: { position: 'right' } }
  }
});
▶ دمو: Pie و Doughnut

Pie

Doughnut

🌐رادار و قطبی radar / polarArea

Radar: مقایسه چند موجودیت از نظر چند ویژگی (مثل مقایسه بازیکنان). Polar: شبیه دایره‌ای اما اندازه شعاع نشان‌دهنده مقدار است.

new Chart(ctx, {
  type: 'radar',
  data: {
    labels: ['سرعت', 'دقت', 'دریبل', 'دفاع', 'شوت', 'پاس'],
    datasets: [
      { label: 'بازیکن الف', data: [85,92,78,60,88,90], backgroundColor: 'rgba(52,152,219,.3)', borderColor: '#3498db' },
      { label: 'بازیکن ب',  data: [72,80,95,75,70,85], backgroundColor: 'rgba(231,76,60,.3)',  borderColor: '#e74c3c' }
    ]
  },
  options: { scales: { r: { min: 0, max: 100, ticks: { stepSize: 20 } } } }
});
▶ دمو: Radar و Polar Area

Radar

Polar Area

💡Scatter و Bubble scatter / bubble

Scatter: نمایش رابطه بین دو متغیر (x و y). هر نقطه یک مشاهده است.
Bubble: مثل Scatter اما اندازه حباب (r) متغیر سومی را نشان می‌دهد.

Scatter Chart

new Chart(ctx, {
  type: 'scatter',
  data: {
    datasets: [{
      label: 'گروه الف',
      data: [
        { x: 10, y: 20 },
        { x: 15, y: 32 },
        { x: 22, y: 18 },
        // ...
      ],
      backgroundColor: 'rgba(52,152,219,.7)',
      pointRadius: 6,
      pointHoverRadius: 9
    }]
  },
  options: {
    scales: {
      x: { type: 'linear', title: { display: true, text: 'محور X' } },
      y: { type: 'linear', title: { display: true, text: 'محور Y' } }
    }
  }
});

Bubble Chart

new Chart(ctx, {
  type: 'bubble',
  data: {
    datasets: [{
      label: 'شهرها',
      data: [
        { x: 10, y: 20, r: 15 },   // r = شعاع حباب
        { x: 25, y: 35, r: 8  },
        { x: 40, y: 15, r: 22 }
      ],
      backgroundColor: 'rgba(136,206,2,.6)'
    }]
  }
});
▶ دمو: Scatter و Bubble

Scatter — دو گروه

Bubble — محبوبیت شهرها

💡 تفاوت با Line/Bar: Scatter هیچ labels‌ای ندارد. داده‌ها به‌صورت {x, y} داده می‌شوند و محورها numeric هستند.

🎪نمودار ترکیبی (Mixed Chart)

در Chart.js می‌توانید چند نوع نمودار را روی یک canvas ترکیب کنید — مثلاً میله‌ای برای مقادیر و خطی برای هدف یا میانگین.

new Chart(ctx, {
  type: 'bar',   // نوع پیش‌فرض
  data: {
    labels: ['فروردین', 'اردیبهشت', 'خرداد', 'تیر'],
    datasets: [
      {
        type: 'bar',   // ← اضافه کردن type به هر dataset
        label: 'فروش واقعی',
        data: [65, 59, 80, 81],
        backgroundColor: 'rgba(52,152,219,.8)',
        borderRadius: 5,
        order: 2   // ترتیب رسم (بزرگتر = جلوتر)
      },
      {
        type: 'line',  // ← این dataset خطی رسم می‌شود
        label: 'هدف فروش',
        data: [70, 65, 75, 85],
        borderColor: '#e74c3c',
        borderDash: [6, 4],   // خط‌چین
        pointStyle: 'circle',
        fill: false,
        tension: 0,
        order: 1
      }
    ]
  }
});
▶ دمو: Bar + Line ترکیبی
💡 کاربردهای Mixed Chart: نمایش فروش واقعی vs هدف، میانگین متحرک روی نمودار میله‌ای، نرخ رشد (line) روی مقادیر مطلق (bar).

تنظیمات و شخصی‌سازی

تنظیمات محورها (Scales)

options: {
  scales: {
    y: {
      beginAtZero: true,
      min: 0, max: 100,
      title: { display: true, text: 'مقدار (٪)' },
      grid: { color: 'rgba(0,0,0,.06)' },
      ticks: {
        callback: val => val + '٪',   // فرمت‌بندی
        stepSize: 20
      }
    },
    x: { grid: { display: false } }  // پنهان کردن خطوط عمودی
  }
}

محور دوم Y (Dual Axis)

datasets: [
  { yAxisID: 'y',  data: [...] },  // محور چپ
  { yAxisID: 'y1', data: [...] }   // محور راست
],
scales: {
  y:  { type: 'linear', position: 'left'  },
  y1: { type: 'linear', position: 'right', grid: { drawOnChartArea: false } }
}

Tooltip سفارشی

plugins: {
  tooltip: {
    backgroundColor: 'rgba(44,52,59,.95)',
    titleColor: '#88ce02',
    bodyColor:  '#fff',
    padding: 12,
    callbacks: {
      label:  ctx => ` ${ctx.parsed.y} میلیون تومان`,
      footer: ctx => ctx[0].parsed.y > 70 ? '✅ هدف محقق شد' : '⚠️ زیر هدف'
    }
  }
}

انیمیشن

options: {
  animation: {
    duration: 1200,
    easing: 'easeInOutQuart',  // easeInQuad, easeOutBounce, easeInElastic ...
    onComplete: () => console.log('آماده شد!')
  }
}
▶ دمو: tooltip سفارشی + رنگ‌بندی شرطی

📱به‌روزرسانی زنده (Live Update)

با تغییر آرایه data و فراخوانی chart.update()، نمودار با انیمیشن به‌روز می‌شود.

// اضافه کردن داده جدید
chart.data.labels.push('مهر');
chart.data.datasets[0].data.push(42);

// حذف داده قدیمی (rolling window)
chart.data.labels.shift();
chart.data.datasets[0].data.shift();

chart.update();        // با انیمیشن
chart.update('none');   // بدون انیمیشن (سریع‌تر)
▶ دمو: نمودار زنده Real-time
⚡ نکته عملکردی: برای داشبوردهای با به‌روزرسانی مکرر، از chart.update('none') استفاده کنید تا انیمیشن اجرا نشود و CPU کمتر مصرف شود. تعداد نقاط را با shift() محدود نگه دارید.

👉Events و تعامل

Chart.js امکان دریافت رویداد کلیک، hover و انتخاب عناصر نمودار را فراهم می‌کند.

onClick روی نمودار

options: {
  onClick: (event, elements) => {
    if (elements.length > 0) {
      const el          = elements[0];
      const datasetIndex = el.datasetIndex;
      const dataIndex    = el.index;
      const label        = chart.data.labels[dataIndex];
      const value        = chart.data.datasets[datasetIndex].data[dataIndex];
      console.log(`کلیک: ${label} = ${value}`);
    }
  },
  onHover: (event, elements) => {
    event.native.target.style.cursor = elements.length ? 'pointer' : 'default';
  }
}

getElementsAtEventForMode

// یافتن همه عناصر در یک point (بدون نیاز به onClick option)
canvas.addEventListener('click', e => {
  const elements = chart.getElementsAtEventForMode(
    e, 'nearest', { intersect: true }, false
  );
  if (elements.length) {
    const { datasetIndex, index } = elements[0];
    console.log('کلیک شد:', chart.data.datasets[datasetIndex].data[index]);
  }
});

برجسته‌سازی Dataset

// پنهان/نمایش یک dataset با کلیک
document.getElementById('btn').addEventListener('click', () => {
  const meta = chart.getDatasetMeta(0);
  meta.hidden = !meta.hidden;
  chart.update();
});
▶ دمو: کلیک روی نمودار — روی هر میله کلیک کنید
روی هر میله کلیک کنید...

🌟نکات حرفه‌ای

متدهای مهم Chart

متدکاربرد
chart.update()اعمال تغییرات با انیمیشن
chart.update('none')اعمال بدون انیمیشن (سریع‌تر)
chart.destroy()حذف کامل و آزادسازی حافظه
chart.reset()اجرای مجدد انیمیشن ورود
chart.resize()تغییر اندازه دستی
chart.toBase64Image()خروجی تصویر PNG
chart.getDatasetMeta(i)اطلاعات Dataset شماره i

دانلود نمودار به PNG

function downloadChart(chart, filename = 'chart') {
  const a = document.createElement('a');
  a.download = filename + '.png';
  a.href = chart.toBase64Image('image/png', 1.0);
  a.click();
}
▶ دمو: دانلود نمودار

بهترین روش‌ها

🔗 chartjs.org 📚 GitHub: chartjs/Chart.js ★ 64k+ stars 🔌 MIT License canvas-based

🚀زمین بازی کد (Playground)

کد Chart.js را همین‌جا ویرایش کن و نمودار را زنده ببین. نوع نمودار، داده‌ها و رنگ‌ها را تغییر بده و ▶ اجرا را بزن. تب HTML شامل <canvas> است و تب JS کد نمودار. نسخهٔ ۴.۴.۲ آفلاین بارگذاری می‌شود.

💡 محیط ایزوله است. برای انواع دیگر کافی است type را به 'bar'، 'pie'، 'radar' و… تغییر دهی.