نمودار شبکه (PartoNetworkChart)

نمودار گره‌ای با force-directed layout برای نمایش ارتباطات بین entity ها. بدون وابستگی به d3-force؛ شبیه‌سازی داخلی سبک.

معرفی

PartoNetworkChart یک گراف node/link است که با شبیه‌سازی داخلی (repulsion + link attraction + centering) layout خودکار تولید می‌کند. مناسب برای نمایش ارتباطات آزاد (غیر-acyclic) که Sankey به آن پاسخ نمی‌دهد.

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

  • ارتباط بین افراد/رسانه‌ها در یک مکالمه افکارسنجی
  • شبکه retweet/mention
  • graph کلاسترهای clustering
  • influencer → پیج‌های ارجاع‌دهنده

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

  • جریان یک‌طرفه بین لایه‌ها — از PartoSankeyChart استفاده کنید
  • گراف خیلی بزرگ (بیشتر از ~300 گره) — شبیه‌سازی ما فقط O(n²) است؛ برای هزار گره از force-graph تخصصی استفاده کنید
  • سلسله مراتبی (tree) — از component درختی استفاده کنید
  • رسانه مرکزی، core: تحلیل‌گر 1، تحلیل‌گر 2، تحلیل‌گر 3
  • تحلیل‌گر 1، analyst: رسانه مرکزی، پیج الف، پیج ب
  • تحلیل‌گر 2، analyst: رسانه مرکزی، پیج ب، پیج ج
  • تحلیل‌گر 3، analyst: رسانه مرکزی، پیج ج، پیج د
  • پیج الف، page: تحلیل‌گر 1، پیج ب
  • پیج ب، page: تحلیل‌گر 1، تحلیل‌گر 2، پیج الف
  • پیج ج، page: تحلیل‌گر 2، تحلیل‌گر 3
  • پیج د، page: تحلیل‌گر 3

زمین بازی

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

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

استفاده

'use client'
import { PartoNetworkChart } from '@partodata/ui'

const nodes = [
  { id: 'hub', label: 'رسانه مرکزی', group: 'core', weight: 5 },
  { id: 'p1', label: 'پیج الف', group: 'page', weight: 3 },
  { id: 'p2', label: 'پیج ب', group: 'page', weight: 2 },
]

const links = [
  { source: 'hub', target: 'p1', value: 3 },
  { source: 'hub', target: 'p2', value: 2 },
  { source: 'p1', target: 'p2', value: 1 },
]

<div style={{ height: 360 }}>
  <PartoNetworkChart nodes={nodes} links={links} />
</div>

موقعیت ثابت (fx/fy)

// Pin a node to a specific position; simulation skips it
const nodes = [
  { id: 'center', label: 'مرکز', fx: 400, fy: 200 },
  { id: 'n1', label: 'گره 1' }, // simulation-positioned
]

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

force-directed پیش‌فرض — هم‌رخدادی هشتگ‌ها

ساده‌ترین حالت؛ همه گره‌ها با شبیه‌سازی repulsion + link attraction به‌صورت خودکار جای‌گذاری می‌شوند. مناسب برای کلاسترینگ هشتگ‌های پرتکرار در یک مکالمه افکارسنجی.

const nodes = [
  { id: 'product', label: '#محصول' },
  { id: 'discount', label: '#تخفیف' },
  { id: 'eqtesad', label: '#اقتصاد' },
  { id: 'brand', label: '#برند' },
]
const links = [
  { source: 'product', target: 'discount', value: 12 },
  { source: 'discount', target: 'eqtesad', value: 9 },
  { source: 'eqtesad', target: 'brand', value: 6 },
  { source: 'product', target: 'brand', value: 3 },
]

<div style={{ height: 360 }}>
  <PartoNetworkChart nodes={nodes} links={links} />
</div>

چیدمان hub-pinned — رسانه مرکزی ثابت

با تعیین fx/fy روی گره‌های کلیدی، آن‌ها از شبیه‌سازی خارج می‌شوند و layout پایدار می‌ماند. برای زمانی که می‌خواهید رسانه مرکزی همیشه در مرکز کادر باشد استفاده کنید.

const nodes = [
  { id: 'hub', label: 'حساب مرکزی برند', fx: 420, fy: 180, weight: 8 },
  { id: 'p1', label: 'پیج الف', weight: 3 },
  { id: 'p2', label: 'پیج ب', weight: 2 },
  { id: 'p3', label: 'پیج ج', weight: 4 },
]
const links = [
  { source: 'hub', target: 'p1', value: 5 },
  { source: 'hub', target: 'p2', value: 3 },
  { source: 'hub', target: 'p3', value: 6 },
]

<PartoNetworkChart nodes={nodes} links={links} />

palette رنگی بر اساس group — کلاسترهای دسته‌بندی شده

با مقداردهی group روی هر گره، palette رنگی خودکار اعمال می‌شود. برای متمایز کردن دسته‌های مختلف (رسانه، برند، اینفلوئنسر) به یک نگاه استفاده کنید.

const nodes = [
  { id: 'm1', label: 'پیج خبری', group: 'media' },
  { id: 'm2', label: 'وب‌سایت رسانه‌ای', group: 'media' },
  { id: 'b1', label: 'حساب رسمی برند', group: 'brand' },
  { id: 'b2', label: 'پیج محصول', group: 'brand' },
  { id: 'i1', label: 'اینفلوئنسر', group: 'influencer' },
]
const links = [
  { source: 'm1', target: 'b1', value: 4 },
  { source: 'm2', target: 'b2', value: 3 },
  { source: 'i1', target: 'm1', value: 2 },
  { source: 'i1', target: 'b1', value: 1 },
]

<PartoNetworkChart nodes={nodes} links={links} />

اندازه گره‌ها بر اساس وزن نفوذ

با weight روی هر گره و تنظیم maxNodeRadius، گره‌های پرنفوذتر بزرگ‌تر رندر می‌شوند. مناسب برای زمانی که اهمیت یا تعداد دنبال‌کننده باید در یک نگاه قابل تشخیص باشد.

<PartoNetworkChart
  nodes={[
    { id: 'mega', label: 'پیج مگا', weight: 10 },
    { id: 'macro', label: 'پیج کلان', weight: 5 },
    { id: 'micro', label: 'پیج خرد', weight: 1 },
  ]}
  links={[
    { source: 'mega', target: 'macro', value: 4 },
    { source: 'macro', target: 'micro', value: 2 },
  ]}
  nodeRadius={10}
  maxNodeRadius={32}
/>

حالت خالی

اگر nodes خالی باشد، کامپوننت EmptyChart را به‌جای SVG رندر می‌کند تا کاربر بداند داده‌ای برای نمایش وجود ندارد. (آرایه‌ی links خالی با گره‌های موجود همچنان SVG را رندر می‌کند — گره‌ها بدون خط.)

<PartoNetworkChart nodes={[]} links={[]} />

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

بکنید

  • برای نمایش روابط آزاد بین entity‌ها استفاده کنید — گراف mention، co-occurrence هشتگ، یا کلاسترهای follower. - گره‌های مهم (hub، رسانه مرکزی) را با fx/fy در موقعیت ثابت pin کنید تا layout پایدار بماند. - برای متمایز‌سازی دسته گره‌ها از group استفاده کنید تا palette رنگی خودکار اعمال شود.

نکنید

  • بیشتر از 200 گره روی یک نمودار قرار ندهید — خوانایی از دست می‌رود و شبیه‌سازی O(n²) کند می‌شود. - برای داده‌های سلسله‌مراتبی (tree) استفاده نکنید — از یک کامپوننت درختی استفاده کنید. - برای جریان یک‌طرفه بین لایه‌ها از PartoSankeyChart استفاده کنید، نه network.

Props

Prop

Type

Prop

Type

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

  • wrapper با aria-label localized. نقش آن به onNodeClick بستگی دارد: بدون آن role="img" (یک تصویر یکپارچه) و با آن role="group" — چون زیرشاخه‌های یک img presentational هستند و دکمه‌های گره از درخت دسترسی حذف می‌شدند.
  • وقتی onNodeClick تنظیم شده باشد، هر گره یک role="button" با aria-label شامل برچسب، گروه و وزن است؛ رنگ و اندازه به‌تنهایی این اطلاعات را منتقل نمی‌کنند.
  • گره‌ها یک tab stop مشترک دارند (roving tabindex): با Tab وارد نمودار می‌شوید، با کلیدهای جهت‌دار (و Home/End) بین گره‌ها حرکت می‌کنید و با Enter یا Space گره را فعال می‌کنید. ترتیب حرکت همان ترتیب آرایه nodes است و چون بوم نمودار همیشه dir="ltr" است، در صفحه RTL هم جابه‌جا نمی‌شود.
  • حلقه فوکوس با outline کشیده می‌شود، نه ring — چون ring یک box-shadow است و روی عناصر SVG رندر نمی‌شود.
  • فوکوس کیبورد همان حالت hover را روشن می‌کند، بنابراین tooltip گره فقط با ماوس در دسترس نیست.
  • hover یک link باعث highlight گره‌های دو سر می‌شود؛ بقیه dim می‌شوند.

محدودیت‌ها

  • شبیه‌سازی O(n²) است — برای کمتر از 100 گره عالی کار می‌کند؛ بیشتر از 300 گره کند می‌شود.
  • layout non-deterministic است — hash id برای seed اولیه استفاده می‌شود تا re-render پایدار باشد.
  • بدون zoom/pan — برای تعامل پیچیده از react-flow یا d3-zoom استفاده کنید.

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