کارت مفهوم (ConceptCard)

کارت headline پایش برای کلاسترینگ نظرات — ترکیب وضعیت، شدت، توزیع گرایش، sentiment، sparkline، خلاصه AI، و چک‌باکس مقایسه

معرفی

ConceptCard کارت تک-مفهومی برای dashboardهای کلاسترینگ نظرات است: هر کارت یک خوشه (concept) از نظرات همگرا را نمایش می‌دهد. composition آن شامل شدت (severity)، توزیع گرایش مخاطب (5-class)، توزیع sentiment (3-class)، trend sparkline، و یک خلاصه‌ی AI است. مناسب grid 3-ستونه در صفحه‌ی کلاسترها.

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

  • صفحه‌ی کلاسترها/خوشه‌ها که ده‌ها concept را به‌صورت grid قابل-مقایسه نشان می‌دهد
  • خروجی تحلیل ML که برای هر cluster signalهای متنوع تولید می‌کند (flow، emotion، trend)
  • صفحه‌ی انتخاب چندتایی برای مقایسه — comparison prop checkbox header را اضافه می‌کند
  • کارت مسئله در صفحهٔ «مسائل رصدشده»: عنوان پیوند واقعی (href)، اقدام‌های کارت (actions)، دو خط خلاصه، عددهای برچسب‌دار (stats) و تغییر با دورهٔ مقایسهٔ نام‌برده (trendDelta) — بدون ساختن کارت دومی

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

  • یک concept تکی در detail view → از MetricCard + Charts جداگانه برای هر signal استفاده کنید (نمایش بزرگ‌تر)
  • لیست خبر/پست با کاربرد متفاوت → Post، و فهرستش EntityCollection با entity="post"
  • وقتی فقط نام و یک متریک می‌خواهید → Card پایه

رونمایی گوشی جدید

فوری

خوشه 4 — 1,240 پست

حجم نظرات منفی در 24 ساعت اخیر سه برابر شده. تمرکز روی شهرهای بزرگ.

حامی6٪منتقد سازنده26٪مخالف44٪مخالف جدی16٪خنثی8٪
مثبت10٪خنثی16٪منفی74٪
مجموع
1240

زمین بازی

زمین بازی

رونمایی گوشی جدید

فوری

خوشه 4 — 1,240 پست

حجم نظرات منفی در 24 ساعت اخیر سه برابر شده.

حامی6٪منتقد سازنده26٪مخالف44٪مخالف جدی16٪خنثی8٪
مثبت10٪خنثی16٪منفی74٪
مجموع
1240
تنظیمات
ظاهر
محتوا
حالت
کد این نمونه به‌صورت خودکار قابل تولید نیست — برای کد آماده‌ی copy/paste به بخش «استفاده» در بالای صفحه مراجعه کنید.

استفاده

import { ConceptCard } from '@partodata/ui'
;<ConceptCard
  title="رونمایی گوشی جدید"
  subtitle="خوشه 4 — 1,240 پست"
  severity="urgent"
  flow={{ 'pro-gov': 80, 'internal-critic': 320, 'internal-opponent': 540, 'external-opponent': 200, grey: 100 }}
  sentiment={{ positive: 120, negative: 920, neutral: 200 }}
  trend={[8, 12, 15, 22, 35, 48, 56, 78]}
  totalCount={1240}
  aiSummary="حجم نظرات منفی در 24 ساعت اخیر سه برابر شده."
/>

حالت‌ها

کارت مسئله در شبکهٔ صفحه‌کلیدی

از 7.9 ConceptCard همان کارت یک مسئله (یا موضوع) در صفحهٔ فهرست است: عنوان یک پیوند واقعی است که روی کل کارت کشیده می‌شود (کلیک وسط و «باز کردن در تب تازه» کار می‌کند)، actions در انتهای سربرگ بالای پیوند می‌نشیند و کلیک یا Enter روی آن‌ها کارت را باز نمی‌کند. EntityCollection entity="concept" کارت‌ها را در شبکه می‌چیند و همهٔ ناوبری صفحه‌کلید (یک توقف Tab، فلش‌ها، j/k، Home/End، Enter) را رایگان می‌دهد.

زیرساختی · در حال پردازش

گزارش‌های مردمی دربارهٔ افت فشار آب افزایش یافته و گفتمان به انتقاد از زمان‌بندی اطلاع‌رسانی رفته است.

مثبت12٪خنثی18٪منفی70٪
+24٪در برابر 7 روز قبل
محتوا در بازه
5,800
امتیاز بحران
72

زیرساختی · در حال پردازش

گزارش‌های مردمی دربارهٔ افت فشار آب افزایش یافته و گفتمان به انتقاد از زمان‌بندی اطلاع‌رسانی رفته است.

مثبت12٪خنثی18٪منفی70٪
+6٪در برابر 7 روز قبل
محتوا در بازه
5,800
امتیاز بحران
72

زیرساختی · در حال پردازش

گزارش‌های مردمی دربارهٔ افت فشار آب افزایش یافته و گفتمان به انتقاد از زمان‌بندی اطلاع‌رسانی رفته است.

مثبت12٪خنثی18٪منفی70٪
-3٪در برابر 7 روز قبل
محتوا در بازه
5,800
امتیاز بحران
72
<EntityCollection
  entity="concept"
  label="مسائل"
  items={issues}
  getId={(issue) => issue.id}
  renderItem={(issue, item) => (
    <ConceptCard
      {...item}
      title={issue.title}
      href={`/issues/${issue.id}`}
      severity={issue.severity}
      eyebrow="زیرساختی · در حال پردازش"
      aiSummary={issue.summary}
      summaryLines={2}
      sentiment={issue.sentiment}
      trend={issue.trend}
      trendTone="neutral"
      trendDelta={{ value: issue.delta, comparisonLabel: 'در برابر 7 روز قبل', tone: 'negative' }}
      stats={[{ label: 'محتوا در بازه', value: issue.count }]}
      actions={<FollowButton issue={issue} />}
    />
  )}
/>
  • trendTone: رنگ نمودار کوچک بر پایهٔ قطبیت. حجم قطبیت ندارد، پس neutral؛ نمودار شکل است و عدد کنارش مقدار را می‌رساند.
  • trendDelta همیشه با comparisonLabel می‌آید («در برابر 7 روز قبل»)، و tone آن به‌طور پیش‌فرض neutral است؛ برای مسئله‌ای که رشدش خبر بد است tone: 'negative' بدهید.
  • stats عددهای برچسب‌دار با جداکنندهٔ هزارگان (ارقام ASCII) است و جای totalCount را می‌گیرد: «مجموع» بدون «از چه و در کدام بازه» نیم‌حرف است.
  • summaryLines ارتفاع کارت‌های یک شبکه را یکی می‌کند.

مقایسه

بازخورد بسته‌بندی جدید

بالا
حامی7٪منتقد سازنده42٪مخالف28٪مخالف جدی14٪خنثی9٪

با تنظیم comparison، یک checkbox در هدر کارت ظاهر می‌شود. checkbox خواهرِ کنترلِ فعال‌سازی کارت است، نه فرزندِ آن؛ بنابراین نقش و وضعیت انتخاب‌شدنش برای screen reader کاملاً نمایان می‌ماند. هندلر کلیکِ کارت هر کلیکی را که از داخل یک کنترل تودرتو (از جمله همین checkbox) شروع شده باشد نادیده می‌گیرد تا کلیک روی checkbox باعث activate شدن کل کارت نشود.

وقتی comparison.selected برابر true باشد، خودِ کارت هم data-selected می‌گیرد و border/background آن با رنگ برند تغییر می‌کند — نه فقط چک‌باکس 16 پیکسلی. در یک grid 3-ستونه‌ی مقایسه، این یعنی کارت‌های انتخاب‌شده بدون نیاز به شکار کردن چک‌باکس‌ها قابل تشخیصند.

const [selected, setSelected] = React.useState(false)
<ConceptCard
  title="کمپین تخفیف فصلی"
  comparison={{ selected, onSelectionChange: setSelected, label: 'مقایسه' }}
  ...
/>

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

بکنید

  • برای کلاسترهای فوری severity="urgent" بدهید — نشان شعله و رنگ قرمز سیگنال قوی می‌سازند - aiSummary را به 1-2 جمله محدود کنید — کارت clamp خودکار ندارد و متن بلند به‌طور کامل رندر می‌شود - trend را با 8-14 نقطه پاس بدهید — sparkline ضد-noise است

نکنید

  • بیش از 9 کارت در یک ردیف نگذارید — grid شلوغ و غیر-قابل‌اسکن می‌شود - flow را وقتی فقط 2 گرایش غالب دارید پاس ندهید — distribution flat می‌شود و ارزش بصری ندارد

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

Prop

Type

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

  • ریشه‌ی کارت همیشه role="article" است و با aria-labelledby به عنوان کارت گره می‌خورد؛ هیچ‌وقت role="button" نمی‌گیرد. نقش button فرزندانش را presentational می‌کند و همین باعث می‌شد checkbox comparison و badgeها برای screen reader تخت شوند.
  • وقتی interactive=true (یا onClick) پاس شود، تنها تب‌استاپ کارت یک <button data-slot="concept-card-trigger"> روی عنوان است؛ با Enter/Space فعال می‌شود و ring فوکوس روی همان دکمه می‌نشیند. کلیک روی کل سطح کارت هم کار می‌کند، ولی صرفاً یک میان‌بر ماوس است.
  • هندلر کلیکِ کارت هر کلیکی را که از داخل یک کنترل تودرتو (a، button، input، select، textarea یا هر عنصر با role تعاملی) شروع شده باشد نادیده می‌گیرد، مگر آنکه خودِ trigger کارت باشد؛ بنابراین کلیک روی checkbox comparison کارت را فعال نمی‌کند و ترتیب فوکوس مستقل می‌ماند.
  • سطح اولویت با SeverityBadge نشان داده می‌شود (5.0: status در آن ادغام شد) و معنا از رنگ + آیکون + برچسب سطح منتقل می‌شود.
  • توزیع flow و sentiment به‌صورت segmentهای رنگی نمایش داده می‌شوند ولی متن جداگانه (مثل subtitle یا total count) معنا را منتقل می‌کند تا کاربر color-blind محروم نماند.
  • aiSummary به‌طور پیش‌فرض clamp ندارد؛ برای شبکهٔ هم‌ارتفاع summaryLines بدهید.
  • با href، عنوان یک <a> است و همان تنها هدف کارت؛ حلقهٔ فوکوس دور کل کارت می‌نشیند. در EntityCollection (که tabIndex می‌دهد) خود کارت توقف Tab است، پیوند عنوان از ترتیب Tab بیرون می‌رود و Enter روی کارت آن را باز می‌کند، Space انتخاب را عوض می‌کند و فلش‌ها بین کارت‌ها می‌روند؛ Tab وارد actions همان کارت می‌شود.
  • جهت trendDelta با پیکان و علامت چاپی نمایش داده می‌شود، نه با رنگ تنها.

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

  • شمارِ شاخص که به فهرست مسائل می‌رود → MetricCard با href؛ شمار روی کارت با شمار فهرست مقصد برابر باشد
  • برای حساب/پیج به‌جای مفهوم → Account
  • برای یک پست تکی → Post
  • توزیع گرایش به‌صورت standalone → Distribution kind="flow"
  • برای ترکیب چندتا کارت در یک گزارش → ReportComposer + ConceptCard به‌عنوان children