نمای مقایسه جدولی (TableComparisonView)

نمای مقایسه‌ای از چند ردیف انتخاب‌شده — pivot 90° با metrics-as-rows × entities-as-columns + highlight اختلافات

معرفی

TableComparisonView نمایی پیوت 90° از یک DataTable است: ستون‌های اصلی به سطرهای مقایسه تبدیل می‌شوند، و ردیف‌های انتخاب‌شده به ستون. مناسب الگوی «2-4 آیتم را انتخاب کن، با هم مقایسه کن» که در dashboardهای influence/افکارسنجی متداول است.

5 از 5 معیار بین ردیف‌های انتخاب‌شده متفاوت است
معیارسارا احمدیمحمد رضاییاستودیو روشن
نامسارا احمدی (متفاوت)محمد رضایی (متفاوت)استودیو روشن (متفاوت)
پلتفرمinstagram (متفاوت)twitter (متفاوت)telegram (متفاوت)
دنبال‌کننده124 هزار (متفاوت)98 هزار (متفاوت)210 هزار (متفاوت)
نرخ تعامل4.8٪4.8٪2.1٪ (متفاوت)
پوشش82,000 (متفاوت)64,000 (متفاوت)145,000 (متفاوت)

زمین بازی

زمین بازی
3 از 3 معیار بین ردیف‌های انتخاب‌شده متفاوت است
معیارپروفایل الفپروفایل بپروفایل ج
پلتفرماینستاگرام (متفاوت)توییتر (متفاوت)تلگرام (متفاوت)
دنبال‌کننده12,400 (متفاوت)8,800 (متفاوت)24,000 (متفاوت)
نرخ تعامل4.2٪ (متفاوت)6.1٪ (متفاوت)2.8٪ (متفاوت)
تنظیمات
داده
3
ظاهر
محتوا
کد این نمونه به‌صورت خودکار قابل تولید نیست — برای کد آماده‌ی copy/paste به بخش «استفاده» در بالای صفحه مراجعه کنید.

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

  • کاربر 2-4 کانسپت/پیج/کلاستر را انتخاب کرده و می‌خواهد کنار هم ببیند
  • compare-modal بعد از کلیک «مقایسه‌ی انتخاب‌شده‌ها»
  • خروجی side-by-side در یک bulletin section

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

  • بیش از 4 ردیف → جدول معمولی scrollable
  • داده‌ی time-series → از PartoLineChart چندخطی استفاده کنید
  • وقتی فقط 2 آیتم با 2-3 متریک دارید → grid 2-ستونه ساده کافی است

استفاده

import { DataTable, TableComparisonView } from '@partodata/ui'

const [selected, setSelected] = React.useState<Set<number>>(new Set())
const selectedRows = data.filter((_, i) => selected.has(i))

<DataTable
  columns={columns}
  data={data}
  selection={{ selectedRows: selected, onSelectionChange: setSelected }}
/>

{selectedRows.length >= 2 && (
  <Dialog open onOpenChange={() => setSelected(new Set())}>
    <DialogContent className="max-w-3xl">
      <DialogTitle>مقایسه</DialogTitle>
      <TableComparisonView
        columns={columns}
        rows={selectedRows}
        onRemoveRow={(_row, i) => {
          const next = new Set(selected)
          next.delete(i)
          setSelected(next)
        }}
      />
    </DialogContent>
  </Dialog>
)}

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

  • استفاده‌ی مجدد از همان cell() رندررهایی که در DataTable تعریف کرده‌اید — هیچ کد مضاعف
  • highlight در سطح سلول، نه سطر — برای هر معیار، فقط سلول‌هایی که از مقدار غالب بین ردیف‌ها فاصله دارند علامت‌گذاری می‌شوند (data-cell-differs="true")، نه همه‌ی سلول‌های آن سطر — پس مشخص است کدام ردیف فرد است
  • getCompareKey?: (row, column) => string | number — مقایسه را مستقیماً از داده انجام می‌دهد؛ برای cell rendererهایی که متن ساده برنمی‌گردانند (SparklineCell، TrendCell، …) لازم است
  • بیش از یک کانال — سلول‌های متفاوت هم‌زمان با رنگ، وزن فونت پررنگ و متن مخفی برای screen reader علامت می‌خورند؛ خلاصه‌ی تعداد معیارهای متفاوت هم در <caption> جدول می‌آید
  • Cap 4 ردیف پیش‌فرض — اگر rows بیشتر بدهید، ردیف‌های اضافه چاپ نمی‌شوند
  • onRemoveRow?: (row, index) => void — وقتی تنظیم شد، یک دکمهٔ فقط‌آیکون xs (مربع 26 پیکسلی) در هر header column رندر می‌شود
  • هم‌تراکم با جدول — از TableHead و TableCell خود Table ساخته شده: سرِ جدول 40، ردیف حداقل 44 و متن 14، با size="compact" 36 / 36 / 13؛ همهٔ سرستون‌ها نقش meta (13 / 500) دارند و تراکم به cell()ها هم می‌رسد (مثلاً SentimentCell در compact فقط نوار است)
  • سلول‌ها نمی‌شکنند — مثل DataTable، مقدار بلند نما را افقی اسکرول می‌کند؛ cell()ی که باید چندخطی شود یک <span className="whitespace-normal"> برگرداند

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

بکنید

  • معمولاً این نما را در Dialog یا Sheet پاپ کنید — هم تمرکز ایجاد می‌کند هم escape برای کاربر سهل است - وقتی فقط 1 ردیف انتخاب است، کامپوننت را نمایش ندهید (مقایسه‌ی تک نفره معنا ندارد) - cell rendererهایی که متن یا عدد ساده برمی‌گردانند خودکار برای highlight هم مقایسه می‌شوند؛ برای رندررهایی مثل SparklineCell یا FlowCell که مقدار را در JSX پیچیده‌تر نشان می‌دهند، getCompareKey را ست کنید تا مقایسه از روی داده انجام شود، نه از روی خروجی رندرشده

نکنید

  • بیش از 4 ردیف نگذارید — column header overflow دستی fix نمی‌شود - برای metric textی که خود "اختلاف" را نشان می‌دهد (مثل +12 vs prev)، اگر highlight هم اعمال شود redundant است → از data-cell-differs در CSS برای style پویا استفاده کنید نه default highlight

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

Prop

Type

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

  • جدول از یک <table> semantic استفاده می‌کند، پس screen reader navigation سطر/ستون استاندارد را پشتیبانی می‌کند.
  • header columnها از <th scope="col"> استفاده می‌کنند تا ارتباط cell-to-header در screen reader درست اعلام شود.
  • دکمه‌ی X روی هر header (وقتی onRemoveRow ست شود) aria-label با مفهوم «حذف از مقایسه» دارد و با Enter/Space قابل فعال‌سازی است.
  • highlight اختلاف روی سه کانال هم‌زمان اعمال می‌شود، نه فقط رنگ: پس‌زمینه‌ی هشدار، وزن فونت پررنگ‌تر، و متن مخفی «(متفاوت)» که فقط برای screen reader خوانده می‌شود (data-cell-differs="true" هم روی همان سلول ست است، برای استایل‌دهی سفارشی).
  • یک <caption> در بالای جدول تعداد معیارهایی که بین ردیف‌های انتخاب‌شده متفاوت‌اند را خلاصه می‌کند — هم برای کاربر بینا و هم برای screen reader.
  • هنگام نمایش در Dialog، focus trap به‌صورت خودکار توسط Dialog مدیریت می‌شود و Escape modal را می‌بندد.

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

  • خود جدول و selection → DataTable
  • مقایسه‌ی Influencer/Concept به‌صورت radar → ComparisonRadar
  • مقایسه‌ی دو entity در grid → MetricCard با previous