نمودار شبکه (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
زمین بازی
با تغییر تنظیمات زیر، پیشنمایش زنده را مشاهده کنید.
- الف: ب، د
- ب: الف، ج
- ج: ب، د
- د: ج، الف
استفاده
'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
NetworkNode / NetworkLink
دسترسیپذیری
- wrapper با
aria-labellocalized. نقش آن بهonNodeClickبستگی دارد: بدون آنrole="img"(یک تصویر یکپارچه) و با آنrole="group"— چون زیرشاخههای یکimgpresentational هستند و دکمههای گره از درخت دسترسی حذف میشدند. - وقتی
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 استفاده کنید.
کامپوننتهای مرتبط
- PartoSankeyChart — برای جریان یکطرفه بین لایهها
- EmptyChart — state خالی
نمودار Sankey (PartoSankeyChart)
نمودار جریان (flow) بین گرهها — ضخامت اتصال نشاندهنده میزان جریان است. مناسب برای نمایش مسیر داده در افکارسنجی.
نمودار نبض مفهوم (ConceptPulseChart)
نمودار scatter دامنهای افکارسنجی — هر نقطه یک «مفهوم» با حلقه ترکیب جریان/احساس دور آن، نمایشدهنده اینکه «این مفهوم از چه ساخته شده».