نقشه‌حرارتی استان‌ها (IranProvinceHeat)

لیست عمودی 31 استان ایران با heat-bar متناسب با مقدار — توزیع جغرافیایی نظرات، شکایات، احساسات و معیارهای دیگر

معرفی

IranProvinceHeat یک لیست عمودی است که هر سطر آن یک استان ایران را با heat-bar افقی نشان می‌دهد؛ شدت رنگ پس‌زمینه با نسبت value / max رشد می‌کند. این الگو جایگزین سبک، قابل دسترس و تماماً RTL برای SVG-map نقشه ایران است — برای 90٪ موارد توزیع per-province در dashboardهای افکارسنجی کافی است و بدون نیاز به topojson یا نقشه برداری دستی روی هر اندازه‌ی صفحه واکنش می‌دهد.

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

  • توزیع جغرافیایی نظرات، شکایات، اخبار منتشره، یا هر متریک شمارشی per-province
  • مقایسه‌ی سطح رضایت یا سطح ریسک بین استان‌ها (با scale معنا‌دار: sentiment / severity / flow)
  • صفحه‌ی مقایسه‌ی استان‌ها با قابلیت کلیک برای drill-down
  • بخش‌های report و bulletin که SVG-map سنگین نیست

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

  • وقتی معنای geometry مهم است (همسایگی استان‌ها، فاصله، مرزها) — به نقشه‌ی واقعی نیاز دارید
  • وقتی داده‌ای per-province نیست (مثلاً city-level یا national aggregate) — PartoBarChart افقی یا MetricCard بهتر است
  • بیش از یک متریک هم‌زمان روی یک ردیف — DataTable با ستون‌های sparkline و progress استفاده کنید
1تهران4.8 هزار نظر
2اصفهان2.1 هزار نظر
3خراسان رضوی2 هزار نظر
4فارس1.5 هزار نظر
5آذربایجان شرقی1.3 هزار نظر
6خوزستان1.2 هزار نظر
7مازندران920 نظر
8گیلان880 نظر

زمین بازی

زمین بازی
1تهران4.8 هزار نظر
2اصفهان2.1 هزار نظر
3خراسان رضوی2 هزار نظر
4فارس1.5 هزار نظر
5آذربایجان شرقی1.3 هزار نظر
6خوزستان1.2 هزار نظر
7مازندران920 نظر
8گیلان880 نظر
+2 استان دیگر
تنظیمات
ظاهر
محتوا
داده
کد این نمونه به‌صورت خودکار قابل تولید نیست — برای کد آماده‌ی copy/paste به بخش «استفاده» در بالای صفحه مراجعه کنید.

استفاده

import { IranProvinceHeat } from '@partodata/ui'

export function ProvinceCommentsCard() {
  return (
    <IranProvinceHeat
      data={{
        tehran: 4820,
        isfahan: 2140,
        'razavi-khorasan': 1965,
      }}
      valueSuffix=" نظر"
      topN={8}
      hideMissing
      showRank
    />
  )
}

می‌توانید data را به دو شکل پاس بدهید: یک Record<string, number> یا آرایه‌ی { code, value }[]. کد می‌تواند slug انگلیسی باشد (مثل tehran) یا کد ISO 3166-2:IR (مثل IR-07). استان‌های ناشناس به‌سادگی نادیده گرفته می‌شوند (و در صورت وجود onUnknownCode گزارش می‌شوند).

scale — انتخاب توکن رنگ معنا‌دار

scale پیش‌فرض brand است؛ ولی بسته به نوع داده، یک scale معنایی انتخاب کنید:

sentiment-positive — رضایت / امتیاز خوب

1تهران78 %
2اصفهان65 %
3خراسان رضوی60 %
4فارس52 %
5آذربایجان شرقی47 %

برای داده‌ای که «بزرگ‌تر = مثبت‌تر» است: نرخ رضایت، نمره NPS، درصد رشد مثبت.

severity-urgent — هشدار / گزارش بحرانی

خوزستان142 گزارش
سیستان و بلوچستان98 گزارش
کردستان76 گزارش
تهران58 گزارش
کهگیلویه و بویراحمد42 گزارش

برای داده‌ای که «بزرگ‌تر = خطرناک‌تر» است: تعداد گزارش‌های فوری، حوادث، پیک شکایات. scale قرمز/نارنجی به سرعت توجه ایجاد می‌کند.

scaleهای موجود:

  • brand (پیش‌فرض)
  • sentiment-positive / sentiment-negative
  • destructive / warning
  • severity-urgent / severity-high
  • flow-pro-gov / flow-internal-critic (توکن‌های گرایش مخاطب — «حامی» / «منتقد سازنده»)

قابلیت کلیک برای drill-down

انتخاب: —

با تنظیم onProvinceClick، هر سطر به <button> تبدیل می‌شود (با focus ring + keyboard activation). callback یک object { slug, iso, value } دریافت می‌کند که برای navigation یا filter setup ایده‌آل است.

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

با isLoading لیست skeleton نمایش داده می‌شود (با role="status" برای screen readerها). الگوی Suspense-friendly — اول این، سپس داده.

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

بکنید

  • برای dashboardهای reporting افکارسنجی، topN={10} با hideMissing بگذارید تا فهرست از 31 ردیف به 10 سطر کلیدی + سطر «+N استان دیگر» جمع شود - scale معنایی انتخاب کنید: shrinking از مقادیر «خنثی» به sentiment-positive یا severity-urgent، signal سریع‌تری به کاربر می‌دهد - برای استفاده در print / bulletin، density="compact" بگذارید — ارتفاع 28px روی صفحه A4 جا می‌شود - با valueSuffix معنای واحد را در ردیف پیدا کنید (" نظر", " %", " گزارش") به جای نوشتن caption مجزا

نکنید

  • این کامپوننت را به‌عنوان فیلتر سراسری استفاده نکنید — برای آن از RegionPicker استفاده کنید؛ این صرفاً یک نمایش‌گر است - مقادیر منفی پاس ندهید — heat scale با نسبت value/max کار می‌کند و مقدار منفی شکستن انتظارات بصری است - بیش از یک متریک per-row نگذارید (مثلاً مقدار + درصد + delta) — به جای آن از DataTable با ستون‌های جداگانه استفاده کنید - رنگ scale را با style override نکنید — token-driven است، با تم Light/Dark خود تطبیق می‌یابد

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

Prop

Type

توابع کمکی

علاوه بر کامپوننت، lib این utilityها را هم export می‌کند:

  • IRAN_PROVINCES — آرایه‌ی readonly از 31 استان با labels (fa/ar/en) و کد ISO
  • findProvince(codeOrSlug) — جستجو بر اساس slug یا ISO، undefined برای ناشناس
  • getProvinceLabel(codeOrSlug, locale) — برچسب locale-appropriate یا fallback به slug
import { IRAN_PROVINCES, findProvince, getProvinceLabel } from '@partodata/ui'

// ساختن لیست استان‌ها برای یک <Select>
const options = IRAN_PROVINCES.map((p) => ({
  value: p.slug,
  label: p.labels.fa,
}))

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

  • ریشه role="list" است و هر سطر داخل یک wrapper با role="listitem" قرار می‌گیرد — screen reader آن را به‌عنوان لیست با تعداد آیتم درست می‌خواند
  • در حالت تعاملی، خودِ سطر <button type="button"> با aria-label="نام استان: مقدار" است. نقش listitem روی wrapper می‌نشیند نه روی button، چون یک role صریح، نقش ضمنی button را از بین می‌برد و دیگر چیزی «قابل فعال‌سازی بودن» سطر را اعلام نمی‌کند
  • در حالت غیرتعاملی سطر aria-label ندارد؛ برچسب و مقدارِ قابل‌مشاهده‌ی خودش خوانده می‌شود
  • focus-visible:ring-2 ring-brand برای navigation کلیدی Tab/Enter/Space
  • data-rank روی هر سطر برای CSS hooks یا تله‌متری
  • skeleton حالت role="status" aria-label="در حال بارگذاری" می‌گیرد
  • بدون hardcoded color — تطبیق با Light/Dark theme خودکار

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

  • برای انتخاب استان به‌عنوان فیلتر → RegionPicker. این کامپوننت صرفاً نمایش‌گر است.
  • اگر داده‌ی شما per-city یا per-county است → PartoBarChart افقی یا DataTable با ستون مقدار
  • اگر می‌خواهید به‌عنوان heat-bar تک‌سطری در یک card نمایش دهید → Sparkline با variant bars کوچک‌تر است
  • اگر می‌خواهید توزیع چند-دسته‌ای روی provinces نشان دهید (مثلاً flow distribution per-province) → DataTable با ستون FlowCell بسازید