نقشه گرمایی (PartoHeatMap)

کامپوننت نقشه گرمایی سفارشی بر پایه SVG و Visx برای نمایش الگوی شدت فعالیت

معرفی

کامپوننت PartoHeatMap یک نقشه گرمایی سفارشی بر پایه SVG خالص و کتابخانه Visx ارائه می‌دهد. این کامپوننت برای نمایش الگوی شدت داده‌ها در دو بعد طراحی شده است؛ مانند فعالیت کاربران در طول روزهای هفته و ساعات شبانه‌روز. از دو زبان فارسی و انگلیسی پشتیبانی می‌کند.

چه زمانی استفاده کنیم:

  • برای نمایش الگوی فعالیت در ماتریس دو بُعدی (مثلاً روز × ساعت)
  • برای شناسایی نقاط اوج و فرود در داده‌های grid-based
  • برای نمایش ماتریس همبستگی یا توزیع شدت

چه زمانی استفاده نکنیم:

  • برای داده‌های غیر matrix — HeatMap برای داده دو بُعدی (X × Y) است
  • برای کمتر از 3×3 نقطه داده — از BarChart استفاده کنید

زمین بازی

با تغییر تنظیمات زیر، پیش‌نمایش زنده را مشاهده کنید.

زمین بازی
تنظیمات
محتوا
حالت
کد این نمونه به‌صورت خودکار قابل تولید نیست — برای کد آماده‌ی copy/paste به بخش «استفاده» در بالای صفحه مراجعه کنید.

استفاده پایه

import { PartoHeatMap } from '@partodata/ui'

const persianWeekdays = ['شنبه', 'یکشنبه', 'دوشنبه', 'سه‌شنبه', 'چهارشنبه', 'پنج‌شنبه', 'جمعه']

const data = persianWeekdays.map((day) => ({
  id: day,
  data: Array.from({ length: 24 }, (_, hour) => ({
    x: `${String(hour).padStart(2, '0')}:00`, // فونت آن را «00:00» نشان می‌دهد
    y: Math.floor(Math.random() * 100),
  })),
}))

<div className="h-[400px]">
  <PartoHeatMap
    data={data}
    locale="fa"
    margin={{ top: 60, right: 50, bottom: 60, left: 150 }}
    xTickFilter={(_, i) => i % 3 === 0}
  />
</div>

نمونه‌های کاربردی

پشتیبانی از زبان فارسی

<PartoHeatMap
  data={dataFa}
  locale="fa"
  yAxisLabel="روز هفته"
  xAxisLabel="ساعات"
  margin={{ top: 60, right: 50, bottom: 60, left: 150 }}
  xTickFilter={(_, i) => i % 3 === 0}
/>

پشتیبانی از زبان انگلیسی

<PartoHeatMap
  data={dataEn}
  locale="en"
  yAxisLabel="Day of Week"
  xAxisLabel="Hours"
  margin={{ top: 60, right: 50, bottom: 60, left: 150 }}
  xTickFilter={(_, i) => i % 3 === 0}
/>

فیلتر تیک‌های محور X

برای جلوگیری از شلوغی برچسب‌ها، از xTickFilter استفاده کنید تا فقط برخی تیک‌ها نمایش داده شوند.

{
  /* نمایش هر 3 ساعت یک‌بار */
}
;<PartoHeatMap data={data} xTickFilter={(_, index) => index % 3 === 0} />

{
  /* نمایش فقط ساعات زوج */
}
;<PartoHeatMap data={data} xTickFilter={(value, _) => parseInt(value) % 2 === 0} />

سفارشی‌سازی رنگ‌ها

به‌طور پیش‌فرض از رنگ برند (تیل) استفاده می‌شود. می‌توانید تابع رنگ سفارشی ارائه دهید.

<PartoHeatMap
  data={data}
  colorScale={(value, max) => {
    const intensity = value / max
    return `hsl(280, 70%, ${90 - intensity * 60}%)`
  }}
/>

تنظیم شعاع و فاصله سلول‌ها

<PartoHeatMap data={data} cellRadius={8} cellGap={4} />

Tooltip سفارشی

<PartoHeatMap
  data={data}
  renderTooltip={(cell) => (
    <div className="bg-popover text-popover-foreground rounded-md shadow-lg px-3 py-2 border border-border">
      <div className="font-medium">
        {cell.rowId} - {cell.x}
      </div>
      <div>
        فعالیت: <span className="font-medium">{cell.value}</span>
      </div>
    </div>
  )}
/>

حالت بارگذاری

<PartoHeatMap data={[]} isLoading={true} />

جدول ویژگی‌ها

Prop

Type

حالت‌ها و انواع

زبان (locale)

مقدارتوضیح
faفارسی (پیش‌فرض) — اعداد فارسی، فونت فارسی
enانگلیسی — اعداد لاتین، فونت لاتین

حالت بارگذاری (isLoading)

با isLoading={true} یک Skeleton متحرک به‌جای نمودار نمایش داده می‌شود.

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

بکنید

  • همیشه xAxisLabel و yAxisLabel را تعریف کنید تا محورها برای کاربر قابل فهم باشند - از xTickFilter استفاده کنید تا برچسب‌های محور X شلوغ نشوند - برای داده‌های فارسی، locale="fa" را تنظیم کنید تا اعداد به فارسی نمایش داده شوند

نکنید

  • از اعداد به‌عنوان id ردیف‌ها استفاده نکنید — از نام‌های توصیفی استفاده کنید - بدون margin کافی نمودار را رندر نکنید — برچسب‌های فارسی فضای بیشتری نیاز دارند - تعداد ستون‌ها را بیش از 30 قرار ندهید — سلول‌ها بسیار کوچک و غیرقابل خواندن می‌شوند

ساختار داده‌ها

مقدار id در هر ردیف باید نام توصیفی باشد (نه عدد). مقدار x در هر سلول برچسب ستون و y مقدار عددی شدت است.

// درست
const data = [
  { id: 'شنبه', data: [{ x: '00:00', y: 45 }, { x: '01:00', y: 30 }] },
  { id: 'یکشنبه', data: [{ x: '00:00', y: 20 }, { x: '01:00', y: 55 }] },
]

// اشتباه — از عدد به‌عنوان id استفاده نکنید
const data = [
  { id: 1, data: [...] },
  { id: 2, data: [...] },
]

تم‌بندی خودکار

این کامپوننت به‌طور خودکار از متغیرهای CSS سیستم طراحی استفاده می‌کند:

  • رنگ پیش‌فرض سلول‌ها از رنگ برند (تیل) مشتق می‌شود
  • با هر دو تم (روشن و تاریک) سازگار است
  • محورها و برچسب‌ها با رنگ‌های foreground و muted-foreground هماهنگ هستند

کاربردها

  • نمایش الگوی فعالیت کاربران در طول روز و هفته
  • تحلیل داده‌های سری زمانی
  • نمایش ماتریس همبستگی
  • تحلیل توزیع داده‌های دوبعدی با شدت متفاوت

دسترسی‌پذیری

  • ریشه‌ی کامپوننت یک ناحیه‌ی نام‌دار با role="group" است؛ اگر ariaLabel ندهید، نامی مانند «نقشه حرارتی، 7 ردیف در 24 ستون» از خود داده ساخته می‌شود. (نقش img استفاده نمی‌شود، چون کل زیردرخت را از دید صفحه‌خوان حذف می‌کند و برچسب سلول‌ها را از بین می‌برد.)
  • هر سلول برچسب دسترسی‌پذیر خودش را دارد: «ردیف، ستون: مقدار» — پس مقدار عددی فقط با رنگ منتقل نمی‌شود
  • سلول‌ها با کیبورد قابل پیمایش‌اند: یک سلول در ترتیب Tab قرار دارد و کلیدهای جهت‌دار (و Home/End) فوکوس را بین سلول‌ها جابه‌جا می‌کنند؛ Escape تولتیپ را می‌بندد
  • تولتیپ با فوکوس کیبورد، حرکت ماوس و لمس (tap) فعال می‌شود و اطلاعات دقیق هر سلول را نشان می‌دهد
  • در حالت بارگذاری از role="status" استفاده می‌شود
  • برچسب‌های محورها (xAxisLabel و yAxisLabel) به درک محتوای نمودار کمک می‌کنند

کامپوننت‌های مرتبط

  • BarChart — اگر داده‌های شما یک بُعدی هستند و نیاز به مقایسه categorical دارید، BarChart مناسب‌تر است
  • RadarChart — اگر می‌خواهید چند بُعد را برای یک موجودیت واحد مقایسه کنید، RadarChart انتخاب بهتری است
  • LineChart — اگر یک بُعد شما زمان است و فقط یک سری داده دارید، LineChart ساده‌تر است
  • داده‌نمایی — راهنمای کامل رنگ‌بندی و تم نمودارها