نمودارها

همه نمودارها روی ApexCharts ساخته شده‌اند و یک پوسته مشترک دارند: رنگ‌ها از توکن‌های فعال، فونت Vazirmatn، جهت راست‌به‌چپ خودکار و بازسازی هنگام تغییر تم.

استفاده اعلانی

<div class="chart" data-chart-key="revenue" data-chart="area" data-chart-height="320"></div>

کنترل‌کننده صفحه داده را از لایه سرویس می‌گیرد و به initCharts(root) می‌دهد. برای ساخت نمودار دستی، ضابطه data-chart-series را با JSON بدهید:

<div class="chart"
     data-chart="column"
     data-chart-height="300"
     data-chart-series='[{"name":"فروش","data":[120,180,140,210]}]'
     data-chart-labels='["فروردین","اردیبهشت","خرداد","تیر"]'></div>

استفاده برنامه‌ای

// گزینه ۱ — مستقیم روی یک عنصر
import { createChart } from './js/core/charts.js';

await createChart(document.querySelector('#revenue'), {
  type: 'area',
  height: 320,
  series: [{ name: 'درآمد', data: [42, 58, 51, 74] }],
  labels: ['فروردین', 'اردیبهشت', 'خرداد', 'تیر'],
});

// گزینه ۲ — از داخل کنترل‌کننده صفحه با کمکی `kit.chart`
import { chart } from './js/pages/kit.js';

container.innerHTML = chart({ key: 'revenue', type: 'area', height: 320, series: [{ name: 'درآمد', data: [42, 58, 51, 74] }], labels: ['فروردین'] });
initCharts(container);

انواع پشتیبانی‌شده

نوعکاربرد پیشنهادی
areaروند درآمد و ترافیک
lineمقایسه دو سری زمانی
columnمقایسه دسته‌ای، فروش ماهانه
barرتبه‌بندی افقی (محصول، کارشناس)
donutسهم (دستگاه، پلن، منبع ترافیک)
pieتوزیع ساده
radarمقایسه چند شاخص
radialBarپیشرفت تک‌شاخصی
heatmapالگوی ساعتی/روزانه
sparklineریز‌نمودار داخل کارت آماری

رنگ‌ها و تم

پالت از توکن‌های --nv-chart-1…‑6 خوانده می‌شود؛ پس با تغییر data-primary یا روشن/تاریک شدن، نمودارها هم عوض می‌شوند.

import { refreshCharts } from './js/core/charts.js';
refreshCharts();   // پس از تغییر تم یا زبان

به‌صورت خودکار، ماژول theme.js رویداد تغییر تم را منتشر می‌کند و charts.js همه نمودارهای صفحه را دوباره می‌سازد؛ نیازی به کد اضافه نیست.

فرمت اعداد و برچسب تقویم

محورها و تولتیپ‌ها از numbers.js استفاده می‌کنند: جداکننده هزارگان فارسی، اعداد فشرده (formatCompact) و درصد فارسی. برچسب‌های زمانی از تقویم فعال (شمسی یا میلادی) پیروی می‌کنند.

کارایی

  • نمودارها فقط وقتی ساخته می‌شوند که ظرف آن‌ها در صفحه باشد (initCharts روی [data-chart-key] کار می‌کند).
  • با تغییر اندازه پنجره، نمودار بدون بازسازی دوباره مقیاس می‌شود.
  • برای صفحات سنگین، نمودارها را در تب‌های پنهان نسازید؛ پس از نمایش تب initCharts(panel) را صدا بزنید.
نکته: برای حذف یک نمودار قبل از بازسازی، chartInstance.destroy() را صدا بزنید؛ charts.js نمونه‌ها را در یک WeakMap نگه می‌دارد تا نشتی نداشته باشید
هشدار: بسته vendor-charts حدود ۵۴۰ کیلوبایت است و فقط در صفحاتی بارگذاری می‌شود که نمودار دارند (code splitting با Vite)

آن را به صفحات بدون نمودار اضافه نکنید.

Charts

All charts are built on ApexCharts and share one skin: colours from the active tokens, the Vazirmatn font, automatic right-to-left direction and a rebuild when the theme changes.

Declarative usage

<div class="chart" data-chart-key="revenue" data-chart="area" data-chart-height="320"></div>

The page controller fetches the data from the service layer and passes it to initCharts(root). To build a chart by hand, provide data-chart-series as JSON:

<div class="chart"
     data-chart="column"
     data-chart-height="300"
     data-chart-series='[{"name":"Sales","data":[120,180,140,210]}]'
     data-chart-labels='["Farvardin","Ordibehesht","Khordad","Tir"]'></div>

Programmatic usage

// Option 1 — directly on an element
import { createChart } from './js/core/charts.js';

await createChart(document.querySelector('#revenue'), {
  type: 'area',
  height: 320,
  series: [{ name: 'Revenue', data: [42, 58, 51, 74] }],
  labels: ['Farvardin', 'Ordibehesht', 'Khordad', 'Tir'],
});

// Option 2 — from a page controller with the `kit.chart` helper
import { chart } from './js/pages/kit.js';

container.innerHTML = chart({ key: 'revenue', type: 'area', height: 320, series: [{ name: 'Revenue', data: [42, 58, 51, 74] }], labels: ['Farvardin'] });
initCharts(container);

Supported types

TypeSuggested use
areaRevenue and traffic trends
lineComparing two time series
columnCategory comparison, monthly sales
barHorizontal ranking (product, agent)
donutShare (device, plan, traffic source)
pieSimple distribution
radarComparing several metrics
radialBarSingle-metric progress
heatmapHourly/daily patterns
sparklineMicro chart inside a stat card

Colours and theme

The palette is read from the --nv-chart-1…6 tokens, so charts change too when data-primary changes or when switching between light and dark.

import { refreshCharts } from './js/core/charts.js';
refreshCharts();   // after a theme or language change

Automatically, the theme.js module emits the theme-change event and charts.js rebuilds every chart on the page; no extra code is needed.

Number format and calendar labels

Axes and tooltips use numbers.js: localized thousands separators, compact numbers (formatCompact) and localized percentages. Time labels follow the active calendar (Jalali or Gregorian).

Performance

  • Charts are only built when their container is on the page (initCharts works on [data-chart-key]).
  • When the window is resized, the chart rescales without being rebuilt.
  • On heavy pages, do not build charts inside hidden tabs; call initCharts(panel) after the tab is shown.
Tip: to remove a chart before rebuilding, call chartInstance.destroy(); charts.js keeps instances in a WeakMap so you do not leak memory
Warning: the vendor-charts bundle is about 540 KB and is only loaded on pages that have charts (code splitting with Vite)

Do not add it to pages without charts.

المخططات

جميع المخططات مبنية على ApexCharts ولها مظهر مشترك: ألوان من الرموز النشطة، وخط Vazirmatn، واتجاه من اليمين إلى اليسار تلقائي، وإعادة بناء عند تغيير السمة.

الاستخدام التصريحي

<div class="chart" data-chart-key="revenue" data-chart="area" data-chart-height="320"></div>

يجلب متحكم الصفحة البيانات من طبقة الخدمات ويمررها إلى initCharts(root). ولإنشاء مخطط يدوياً، مرّر data-chart-series بصيغة JSON:

<div class="chart"
     data-chart="column"
     data-chart-height="300"
     data-chart-series='[{"name":"المبيعات","data":[120,180,140,210]}]'
     data-chart-labels='["فروردين","أرديبهشت","خرداد","تير"]'></div>

الاستخدام البرمجي

// الخيار ١ — مباشرة على عنصر
import { createChart } from './js/core/charts.js';

await createChart(document.querySelector('#revenue'), {
  type: 'area',
  height: 320,
  series: [{ name: 'الإيراد', data: [42, 58, 51, 74] }],
  labels: ['فروردين', 'أرديبهشت', 'خرداد', 'تير'],
});

// الخيار ٢ — من داخل متحكم الصفحة بالمساعد `kit.chart`
import { chart } from './js/pages/kit.js';

container.innerHTML = chart({ key: 'revenue', type: 'area', height: 320, series: [{ name: 'الإيراد', data: [42, 58, 51, 74] }], labels: ['فروردين'] });
initCharts(container);

الأنواع المدعومة

النوعالاستخدام المقترح
areaاتجاه الإيراد والزيارات
lineمقارنة سلسلتين زمنيتين
columnمقارنة الفئات، المبيعات الشهرية
barترتيب أفقي (منتج، خبير)
donutالحصة (جهاز، خطة، مصدر زيارات)
pieتوزيع بسيط
radarمقارنة عدة مؤشرات
radialBarتقدّم مؤشر واحد
heatmapنمط ساعي/يومي
sparklineمخطط مصغّر داخل البطاقة الإحصائية

الألوان والسمة

تُقرأ اللوحة من الرموز --nv-chart-1…6؛ لذا تتغير المخططات أيضاً عند تغيير data-primary أو التبديل بين الفاتح والداكن.

import { refreshCharts } from './js/core/charts.js';
refreshCharts();   // بعد تغيير السمة أو اللغة

تلقائياً تُطلق الوحدة theme.js حدث تغيير السمة ويعيد charts.js بناء جميع مخططات الصفحة؛ ولا حاجة إلى شيفرة إضافية.

تنسيق الأعداد وتسميات التقويم

تستخدم المحاور والتلميحات numbers.js: فواصل آلاف محلية، وأعداداً مختصرة (formatCompact) ونسباً مئوية محلية. وتتبع التسميات الزمنية التقويم النشط (هجري شمسي أو ميلادي).

الأداء

  • لا تُنشأ المخططات إلا عندما تكون حاويتها في الصفحة (initCharts يعمل على [data-chart-key]).
  • عند تغيير حجم النافذة، يُعاد تحجيم المخطط دون إعادة بنائه.
  • في الصفحات الثقيلة، لا تنشئ المخططات داخل تبويبات مخفية؛ استدعِ initCharts(panel) بعد إظهار التبويب.
ملاحظة: لحذف مخطط قبل إعادة بنائه، استدعِ chartInstance.destroy()؛ يحتفظ charts.js بالنسخ في WeakMap لتجنّب تسرب الذاكرة
تحذير: حجم الحزمة vendor-charts نحو ٥٤٠ كيلوبايت ولا تُحمَّل إلا في الصفحات التي تحتوي على مخططات (تقسيم الشيفرة مع Vite)

لا تضفها إلى الصفحات الخالية من المخططات.