nodalix 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +726 -0
- package/dist/index.d.ts +184 -0
- package/dist/index.js +3905 -0
- package/dist/index.mjs +3840 -0
- package/package.json +60 -0
package/README.md
ADDED
|
@@ -0,0 +1,726 @@
|
|
|
1
|
+
# Nodalix
|
|
2
|
+
|
|
3
|
+
کتابخانهٔ React برای نمایش و تحلیل گرافهای شبکهای با **vis-network**. مناسب برای نمایش روابط بین موجودیتها، جریان داده یا فرایند بین گرههای اصلی و واسط، و نمایش اطلاعات یالها (مقدار، زمان، متن تکمیلی و …) بهصورت تعاملی.
|
|
4
|
+
|
|
5
|
+
**سازنده:** محمد صالحی
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## فهرست
|
|
10
|
+
|
|
11
|
+
- [ویژگیها](#ویژگیها)
|
|
12
|
+
- [پیشنیازها](#پیشنیازها)
|
|
13
|
+
- [نصب](#نصب)
|
|
14
|
+
- [شروع سریع](#شروع-سریع)
|
|
15
|
+
- [ساختار داده](#ساختار-داده)
|
|
16
|
+
- [کامپوننت `Graph_Engine`](#کامپوننت-graph_engine)
|
|
17
|
+
- [پیکربندی داینامیک](#پیکربندی-داینامیک)
|
|
18
|
+
- [پیکربندی ابزارهای UI](#پیکربندی-ابزارهای-ui-گرید-جابهجایی-یال-زبان)
|
|
19
|
+
- [APIهای برنامهنویسی (Imperative)](#apiهای-برنامهنویسی-imperative)
|
|
20
|
+
- [ابزارهای داخلی UI](#ابزارهای-داخلی-ui)
|
|
21
|
+
- [منطق گراف و یالها](#منطق-گراف-و-یالها)
|
|
22
|
+
- [Exportها و ثابتها](#exportها-و-ثابتها)
|
|
23
|
+
- [ساخت و توسعه](#ساخت-و-توسعه)
|
|
24
|
+
- [نکات مهم](#نکات-مهم)
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## ویژگیها
|
|
29
|
+
|
|
30
|
+
- رندر گراف تعاملی (جابهجایی، زوم، انتخاب گره/یال)
|
|
31
|
+
- دو نوع گره: **main** (گره اصلی) و **sub** (گره واسط/میانی)
|
|
32
|
+
- نمایش اطلاعات یال روی گرههای میانی (قابل تنظیم توسط کاربر یا ثابت توسط توسعهدهنده)
|
|
33
|
+
- گرید پسزمینه (قابل تغییر توسط کاربر یا ثابت توسط توسعهدهنده)
|
|
34
|
+
- جابهجایی گرههای `main` (قابل تغییر توسط کاربر یا ثابت توسط توسعهدهنده)
|
|
35
|
+
- رابط فارسی/انگلیسی (دوزبانه یا تکزبانه با انتخاب توسعهدهنده)
|
|
36
|
+
- رنگبندی border گرهها بر اساس **rate** و بازههای قابل تنظیم
|
|
37
|
+
- چیدمان خودکار گرهها (Auto Arrange)
|
|
38
|
+
- جستجوی زنده، هایلایت مسیر، رنگآمیزی یالها
|
|
39
|
+
- خروجی اسکرینشات و Excel
|
|
40
|
+
- افزودن گره از بیرون کامپوننت با `AddNewNode`
|
|
41
|
+
- پشتیبانی از تم روشن/تاریک (بر اساس کلاس `dark` روی `<html>`)
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## پیشنیازها
|
|
46
|
+
|
|
47
|
+
| وابستگی | نسخه |
|
|
48
|
+
|---------|------|
|
|
49
|
+
| React | `>= 18` |
|
|
50
|
+
| React DOM | `>= 18` |
|
|
51
|
+
|
|
52
|
+
در پروژههای **Next.js** کامپوننت باید در فایل Client Component استفاده شود (`"use client"`).
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## نصب
|
|
57
|
+
|
|
58
|
+
### از مسیر محلی (توسعه)
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# ابتدا کتابخانه را بیلد کنید
|
|
62
|
+
cd nodalix
|
|
63
|
+
npm install
|
|
64
|
+
npm run build
|
|
65
|
+
|
|
66
|
+
# در پروژه مصرفکننده
|
|
67
|
+
npm install file:../nodalix
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### از npm (پس از انتشار)
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npm install nodalix
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## شروع سریع
|
|
79
|
+
|
|
80
|
+
```jsx
|
|
81
|
+
"use client";
|
|
82
|
+
|
|
83
|
+
import {
|
|
84
|
+
Graph_Engine,
|
|
85
|
+
NODE_TYPE,
|
|
86
|
+
EDGE_LABEL_FIELDS,
|
|
87
|
+
} from "nodalix";
|
|
88
|
+
|
|
89
|
+
const data = [
|
|
90
|
+
{
|
|
91
|
+
id: "node_a",
|
|
92
|
+
type: NODE_TYPE.MAIN,
|
|
93
|
+
text: "منبع A",
|
|
94
|
+
label: "گره مبدأ",
|
|
95
|
+
entity: { name: "تیم الف" },
|
|
96
|
+
rate: 12,
|
|
97
|
+
main: true,
|
|
98
|
+
metadata: null,
|
|
99
|
+
x: -420,
|
|
100
|
+
y: 0,
|
|
101
|
+
inputs: [],
|
|
102
|
+
outputs: [
|
|
103
|
+
{
|
|
104
|
+
id: "step_1",
|
|
105
|
+
value: 120,
|
|
106
|
+
subText: "واحد",
|
|
107
|
+
subValue: 4800,
|
|
108
|
+
time: 1717851000,
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: "step_1",
|
|
114
|
+
type: NODE_TYPE.SUB,
|
|
115
|
+
text: "مرحله ۱",
|
|
116
|
+
label: null,
|
|
117
|
+
entity: null,
|
|
118
|
+
rate: null,
|
|
119
|
+
main: false,
|
|
120
|
+
metadata: null,
|
|
121
|
+
subText: "پردازش",
|
|
122
|
+
x: -210,
|
|
123
|
+
y: 0,
|
|
124
|
+
inputs: [
|
|
125
|
+
{ id: "node_a", value: 120, subText: "واحد", subValue: 4800, time: 1717851000 },
|
|
126
|
+
],
|
|
127
|
+
outputs: [
|
|
128
|
+
{ id: "node_b", value: 120, subText: "واحد", subValue: 4800, time: 1717851000 },
|
|
129
|
+
],
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
id: "node_b",
|
|
133
|
+
type: NODE_TYPE.MAIN,
|
|
134
|
+
text: "مقصد B",
|
|
135
|
+
label: "گره پایانی",
|
|
136
|
+
entity: null,
|
|
137
|
+
rate: 45,
|
|
138
|
+
main: false,
|
|
139
|
+
metadata: null,
|
|
140
|
+
x: 0,
|
|
141
|
+
y: 0,
|
|
142
|
+
inputs: [
|
|
143
|
+
{ id: "step_1", value: 120, subText: "واحد", subValue: 4800, time: 1717851000 },
|
|
144
|
+
],
|
|
145
|
+
outputs: [],
|
|
146
|
+
},
|
|
147
|
+
];
|
|
148
|
+
|
|
149
|
+
export default function App() {
|
|
150
|
+
return (
|
|
151
|
+
<div style={{ width: "100%", height: "600px" }}>
|
|
152
|
+
<Graph_Engine
|
|
153
|
+
NewData={data}
|
|
154
|
+
onNodeClick={(node) => console.log("clicked:", node)}
|
|
155
|
+
edgeLabelFields={[
|
|
156
|
+
EDGE_LABEL_FIELDS.VALUE,
|
|
157
|
+
EDGE_LABEL_FIELDS.SUB_TEXT,
|
|
158
|
+
EDGE_LABEL_FIELDS.SUB_VALUE,
|
|
159
|
+
EDGE_LABEL_FIELDS.TIME,
|
|
160
|
+
]}
|
|
161
|
+
rateColorRanges={[
|
|
162
|
+
{ min: 70, max: Infinity, color: "red" },
|
|
163
|
+
{ min: 50, max: 70, color: "orange" },
|
|
164
|
+
]}
|
|
165
|
+
/>
|
|
166
|
+
</div>
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
> **نکته:** کانتینر والد باید ارتفاع مشخص داشته باشد تا گراف بهدرستی نمایش داده شود.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## ساختار داده
|
|
176
|
+
|
|
177
|
+
### گره (`GraphNode`)
|
|
178
|
+
|
|
179
|
+
| فیلد | نوع | توضیح |
|
|
180
|
+
|------|-----|--------|
|
|
181
|
+
| `id` | `string` | شناسه یکتا (الزامی) |
|
|
182
|
+
| `type` | `"main"` \| `"sub"` | `main` = گره اصلی، `sub` = گره واسط/میانی |
|
|
183
|
+
| `text` | `string` | متن اصلی (شناسه داخلی یا توضیح کوتاه) |
|
|
184
|
+
| `label` | `string \| null` | برچسب نمایشی برای گرههای `main` |
|
|
185
|
+
| `subText` | `string \| null` | برچسب نمایشی برای گرههای `sub` |
|
|
186
|
+
| `entity` | `object \| null` | `{ name, image?, metadata? }` — اطلاعات موجودیت مرتبط |
|
|
187
|
+
| `rate` | `number \| null` | امتیاز عددی (مثلاً ۰–۱۰۰) — رنگ border را تعیین میکند |
|
|
188
|
+
| `main` | `boolean` | اگر `true` باشد فلش و استایل ویژه نمایش داده میشود |
|
|
189
|
+
| `metadata` | `string \| null` | اگر مقدار داشته باشد آیکون تکمیلی نمایش داده میشود |
|
|
190
|
+
| `x`, `y` | `number` | موقعیت اولیه در بوم |
|
|
191
|
+
| `inputs` | `EdgeRef[]` | اتصالات ورودی |
|
|
192
|
+
| `outputs` | `EdgeRef[]` | اتصالات خروجی |
|
|
193
|
+
|
|
194
|
+
### مرجع یال (`EdgeRef` — داخل `inputs` / `outputs`)
|
|
195
|
+
|
|
196
|
+
| فیلد | نوع | توضیح |
|
|
197
|
+
|------|-----|--------|
|
|
198
|
+
| `id` | `string` | شناسه گره مقابل |
|
|
199
|
+
| `value` | `number` | مقدار اصلی |
|
|
200
|
+
| `subText` | `string` | متن تکمیلی (واحد، دسته، برچسب کوتاه و …) |
|
|
201
|
+
| `subValue` | `number` | مقدار ثانویه (مثلاً مقدار تبدیلشده یا مرجع) |
|
|
202
|
+
| `time` | `number` | زمان یونیکس (ثانیه) |
|
|
203
|
+
|
|
204
|
+
### مثال کامل
|
|
205
|
+
|
|
206
|
+
```js
|
|
207
|
+
{
|
|
208
|
+
id: "node_c",
|
|
209
|
+
type: "main",
|
|
210
|
+
text: "گره C-1042",
|
|
211
|
+
label: "انبار منطقه ۲",
|
|
212
|
+
entity: { name: "واحد لجستیک" },
|
|
213
|
+
rate: 55,
|
|
214
|
+
main: false,
|
|
215
|
+
metadata: "نیاز به بررسی",
|
|
216
|
+
x: 0,
|
|
217
|
+
y: 0,
|
|
218
|
+
inputs: [
|
|
219
|
+
{ id: "step_2", value: 48, subText: "بسته", subValue: 960, time: 1717851200 },
|
|
220
|
+
],
|
|
221
|
+
outputs: [
|
|
222
|
+
{ id: "step_3", value: 48, subText: "بسته", subValue: 960, time: 1717851300 },
|
|
223
|
+
],
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## کامپوننت `Graph_Engine`
|
|
230
|
+
|
|
231
|
+
کامپوننت اصلی و تنها نقطهٔ ورود UI کتابخانه.
|
|
232
|
+
|
|
233
|
+
### Props
|
|
234
|
+
|
|
235
|
+
| Prop | نوع | پیشفرض | توضیح |
|
|
236
|
+
|------|-----|---------|--------|
|
|
237
|
+
| `NewData` | `GraphNode[]` | `[]` | آرایهٔ گرههای گراف |
|
|
238
|
+
| `onNodeClick` | `(node) => void` | — | callback هنگام کلیک روی گره |
|
|
239
|
+
| `edgeLabelFields` | `string[]` | `["value","subText","time"]` | فیلدهایی که روی لیبل یال نمایش داده میشوند |
|
|
240
|
+
| `rateColorRanges` | `RateColorRange[]` | [پیشفرض زیر](#رنگبندی-rate-ratecolorranges) | بازههای رنگ برای `rate` |
|
|
241
|
+
| `showEdgeHoverInfo` | `boolean` | `false` | نمایش اطلاعات یال هنگام هاور موس |
|
|
242
|
+
| `showHelpButton` | `boolean` | `true` | نمایش دکمهٔ راهنما در گوشهٔ گراف |
|
|
243
|
+
| `gridUserConfigurable` | `boolean` | `true` | اگر `false` باشد، کاربر نمیتواند گرید را تغییر دهد |
|
|
244
|
+
| `showGrid` | `boolean` | `true` | وضعیت گرید (ثابت یا مقدار اولیه وقتی کاربر قابل انتخاب است) |
|
|
245
|
+
| `nodesDraggableUserConfigurable` | `boolean` | `true` | اگر `false` باشد، کاربر نمیتواند جابهجایی گره را تغییر دهد |
|
|
246
|
+
| `nodesDraggable` | `boolean` | `true` | گرههای main قابل جابهجایی باشند یا ثابت |
|
|
247
|
+
| `edgeInfoNodesUserConfigurable` | `boolean` | `true` | اگر `false` باشد، کاربر نمیتواند نمایش گرههای میانی یال را تغییر دهد |
|
|
248
|
+
| `showEdgeInfoNodes` | `boolean` | `true` | نمایش گرههای میانی اطلاعات یال |
|
|
249
|
+
| `languageUserConfigurable` | `boolean` | `true` | اگر `false` باشد، کاربر نمیتواند زبان را عوض کند |
|
|
250
|
+
| `language` | `"fa"` \| `"en"` | `"fa"` | زبان ثابت یا مقدار اولیه (`GRAPH_LANGUAGE.FA` / `GRAPH_LANGUAGE.EN`) |
|
|
251
|
+
|
|
252
|
+
### نوع `RateColorRange`
|
|
253
|
+
|
|
254
|
+
```ts
|
|
255
|
+
type RateColorRange = {
|
|
256
|
+
min: number; // حداقل بازه (شامل)
|
|
257
|
+
max: number; // حداکثر بازه (غیرشامل؛ برای آخرین بازه از Infinity استفاده کنید)
|
|
258
|
+
color: string; // نام یا کد رنگ CSS
|
|
259
|
+
};
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
**پیشفرض:**
|
|
263
|
+
|
|
264
|
+
```js
|
|
265
|
+
[
|
|
266
|
+
{ min: 70, max: Infinity, color: "red" },
|
|
267
|
+
{ min: 50, max: 70, color: "orange" },
|
|
268
|
+
]
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
گرههایی که `rate` ندارند یا در هیچ بازهای نیفتند، رنگ border پیشفرض تم را میگیرند.
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## پیکربندی داینامیک
|
|
276
|
+
|
|
277
|
+
### فیلدهای لیبل یال (`edgeLabelFields`)
|
|
278
|
+
|
|
279
|
+
مقادیر مجاز (از `EDGE_LABEL_FIELDS`):
|
|
280
|
+
|
|
281
|
+
| کلید | مقدار | نمایش |
|
|
282
|
+
|------|-------|--------|
|
|
283
|
+
| `VALUE` | `"value"` | مقدار عددی اصلی |
|
|
284
|
+
| `SUB_TEXT` | `"subText"` | متن تکمیلی (در کنار value) |
|
|
285
|
+
| `SUB_VALUE` | `"subValue"` | مقدار ثانویه (با فرمت عددی در UI) |
|
|
286
|
+
| `TIME` | `"time"` | تاریخ و ساعت میلادی |
|
|
287
|
+
|
|
288
|
+
**مثالها:**
|
|
289
|
+
|
|
290
|
+
```jsx
|
|
291
|
+
// مقدار + متن تکمیلی + زمان (پیشفرض)
|
|
292
|
+
edgeLabelFields={["value", "subText", "time"]}
|
|
293
|
+
|
|
294
|
+
// فقط مقدار ثانویه و زمان
|
|
295
|
+
edgeLabelFields={["subValue", "time"]}
|
|
296
|
+
|
|
297
|
+
// همه فیلدها
|
|
298
|
+
edgeLabelFields={["value", "subText", "subValue", "time"]}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### رنگبندی rate (`rateColorRanges`)
|
|
302
|
+
|
|
303
|
+
```jsx
|
|
304
|
+
rateColorRanges={[
|
|
305
|
+
{ min: 0, max: 30, color: "#22c55e" }, // امتیاز پایین
|
|
306
|
+
{ min: 30, max: 60, color: "#eab308" }, // امتیاز متوسط
|
|
307
|
+
{ min: 60, max: Infinity, color: "#ef4444" }, // امتیاز بالا
|
|
308
|
+
]}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
بازهها به ترتیب آرایه بررسی میشوند؛ اولین بازهٔ منطبق اعمال میشود.
|
|
312
|
+
|
|
313
|
+
### هاور روی یال (`showEdgeHoverInfo`)
|
|
314
|
+
|
|
315
|
+
بهصورت پیشفرض خاموش است. با فعال کردن آن، هنگام قرار دادن موس روی یال، شناسه مبدأ/مقصد و فیلدهای انتخابشده در `edgeLabelFields` نمایش داده میشود:
|
|
316
|
+
|
|
317
|
+
```jsx
|
|
318
|
+
<Graph_Engine
|
|
319
|
+
NewData={data}
|
|
320
|
+
showEdgeHoverInfo
|
|
321
|
+
edgeLabelFields={["value", "subText", "time"]}
|
|
322
|
+
/>
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### دکمهٔ راهنما (`showHelpButton`)
|
|
326
|
+
|
|
327
|
+
بهصورت پیشفرض فعال است. دکمهٔ `?` در گوشهٔ پایین-راست گراف راهنمای استفاده را به زبان انتخابشده در پنل ابزار (فارسی/انگلیسی) نشان میدهد:
|
|
328
|
+
|
|
329
|
+
```jsx
|
|
330
|
+
<Graph_Engine NewData={data} showHelpButton />
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
برای مخفی کردن: `showHelpButton={false}`
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## پیکربندی ابزارهای UI (گرید، جابهجایی، یال، زبان)
|
|
338
|
+
|
|
339
|
+
چهار بخش از پنل **Graph Tools** را میتوان از بیرون کنترل کرد. برای هر کدام دو حالت وجود دارد:
|
|
340
|
+
|
|
341
|
+
| حالت | `*UserConfigurable` | رفتار |
|
|
342
|
+
|------|---------------------|--------|
|
|
343
|
+
| **انتخاب کاربر** | `true` (پیشفرض) | سوئیچ/دکمه در پنل نمایش داده میشود و کاربر میتواند تغییر دهد |
|
|
344
|
+
| **ثابت توسعهدهنده** | `false` | سوئیچ مخفی است و مقدار از prop دوم اعمال میشود |
|
|
345
|
+
|
|
346
|
+
### خلاصهٔ props
|
|
347
|
+
|
|
348
|
+
| ویژگی | انتخاب کاربر | مقدار ثابت / اولیه | پیشفرض |
|
|
349
|
+
|--------|----------------|---------------------|---------|
|
|
350
|
+
| گرید پسزمینه | `gridUserConfigurable` | `showGrid` | `true` / `true` |
|
|
351
|
+
| جابهجایی گره | `nodesDraggableUserConfigurable` | `nodesDraggable` | `true` / `true` |
|
|
352
|
+
| گرههای میانی یال | `edgeInfoNodesUserConfigurable` | `showEdgeInfoNodes` | `true` / `true` |
|
|
353
|
+
| زبان UI | `languageUserConfigurable` | `language` (`"fa"` \| `"en"`) | `true` / `"fa"` |
|
|
354
|
+
|
|
355
|
+
> وقتی `*UserConfigurable={true}` است، prop دوم **مقدار اولیه** است (کاربر بعداً میتواند عوض کند).
|
|
356
|
+
> وقتی `*UserConfigurable={false}` است، prop دوم **مقدار ثابت** است.
|
|
357
|
+
|
|
358
|
+
### گرید (`showGrid` / `gridUserConfigurable`)
|
|
359
|
+
|
|
360
|
+
شبکهٔ پسزمینه و snap گرهها هنگام جابهجایی و Auto Arrange به گرید وابسته است.
|
|
361
|
+
|
|
362
|
+
```jsx
|
|
363
|
+
// کاربر میتواند گرید را روشن/خاموش کند (پیشفرض)
|
|
364
|
+
<Graph_Engine NewData={data} />
|
|
365
|
+
|
|
366
|
+
// گرید همیشه خاموش؛ بدون چکباکس در پنل
|
|
367
|
+
<Graph_Engine NewData={data} gridUserConfigurable={false} showGrid={false} />
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### جابهجایی گره (`nodesDraggable` / `nodesDraggableUserConfigurable`)
|
|
371
|
+
|
|
372
|
+
فقط گرههای `type: "main"` قابل جابهجایی هستند؛ گرههای کمکی (`_Arrow`, `hotWallet`, `Tr…`) همیشه ثابت میمانند. Pan و Zoom تحت تأثیر این تنظیم نیستند.
|
|
373
|
+
|
|
374
|
+
```jsx
|
|
375
|
+
// گرهها همیشه ثابت؛ کاربر نمیتواند جابهجا کند
|
|
376
|
+
<Graph_Engine NewData={data} nodesDraggableUserConfigurable={false} nodesDraggable={false} />
|
|
377
|
+
|
|
378
|
+
// پیشفرض: جابهجایی فعال و کاربر میتواند از پنل خاموش/روشن کند
|
|
379
|
+
<Graph_Engine NewData={data} nodesDraggableUserConfigurable nodesDraggable />
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### گرههای میانی یال (`showEdgeInfoNodes` / `edgeInfoNodesUserConfigurable`)
|
|
383
|
+
|
|
384
|
+
گرههای کوچک روی یالها که فیلدهای `edgeLabelFields` را نشان میدهند. این گزینه جدا از `showEdgeHoverInfo` است (هاور tooltip روی خود یال).
|
|
385
|
+
|
|
386
|
+
```jsx
|
|
387
|
+
// اطلاعات یال همیشه نمایش داده میشود
|
|
388
|
+
<Graph_Engine NewData={data} edgeInfoNodesUserConfigurable={false} showEdgeInfoNodes />
|
|
389
|
+
|
|
390
|
+
// اطلاعات یال همیشه مخفی
|
|
391
|
+
<Graph_Engine NewData={data} edgeInfoNodesUserConfigurable={false} showEdgeInfoNodes={false} />
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### زبان (`language` / `languageUserConfigurable`)
|
|
395
|
+
|
|
396
|
+
تمام متنهای پنل ابزار، tooltipها و راهنما (`?`) به زبان انتخابشده نمایش داده میشوند. برای مقدار ثابت از ثابت `GRAPH_LANGUAGE` استفاده کنید.
|
|
397
|
+
|
|
398
|
+
```jsx
|
|
399
|
+
import { Graph_Engine, GRAPH_LANGUAGE } from "nodalix";
|
|
400
|
+
|
|
401
|
+
// فقط انگلیسی؛ بدون دکمهٔ تغییر زبان
|
|
402
|
+
<Graph_Engine
|
|
403
|
+
NewData={data}
|
|
404
|
+
languageUserConfigurable={false}
|
|
405
|
+
language={GRAPH_LANGUAGE.EN}
|
|
406
|
+
/>
|
|
407
|
+
|
|
408
|
+
// دوزبانه؛ کاربر بین فارسی و انگلیسی انتخاب میکند (پیشفرض)
|
|
409
|
+
<Graph_Engine NewData={data} languageUserConfigurable language="fa" />
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### مثال ترکیبی
|
|
413
|
+
|
|
414
|
+
```jsx
|
|
415
|
+
import { Graph_Engine, GRAPH_LANGUAGE } from "nodalix";
|
|
416
|
+
|
|
417
|
+
<Graph_Engine
|
|
418
|
+
NewData={data}
|
|
419
|
+
gridUserConfigurable={false}
|
|
420
|
+
showGrid
|
|
421
|
+
nodesDraggableUserConfigurable
|
|
422
|
+
nodesDraggable
|
|
423
|
+
edgeInfoNodesUserConfigurable={false}
|
|
424
|
+
showEdgeInfoNodes={false}
|
|
425
|
+
languageUserConfigurable={false}
|
|
426
|
+
language={GRAPH_LANGUAGE.FA}
|
|
427
|
+
/>
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
در این مثال: گرید همیشه روشن، جابهجایی قابل تغییر توسط کاربر، گرههای میانی یال همیشه مخفی، UI فقط فارسی.
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
## APIهای برنامهنویسی (Imperative)
|
|
435
|
+
|
|
436
|
+
این توابع خارج از درخت React و پس از mount شدن `Graph_Engine` قابل استفادهاند.
|
|
437
|
+
|
|
438
|
+
### `AddNewNode(rawNode, options?)`
|
|
439
|
+
|
|
440
|
+
گره جدید را با اعتبارسنجی، محاسبه موقعیت امن، و همگامسازی دوطرفه `inputs`/`outputs` اضافه میکند.
|
|
441
|
+
|
|
442
|
+
```js
|
|
443
|
+
import { AddNewNode, NODE_TYPE } from "nodalix";
|
|
444
|
+
|
|
445
|
+
const result = AddNewNode(
|
|
446
|
+
{
|
|
447
|
+
id: "node_new",
|
|
448
|
+
type: NODE_TYPE.MAIN,
|
|
449
|
+
text: "گره جدید",
|
|
450
|
+
label: "شعبه ۳",
|
|
451
|
+
entity: null,
|
|
452
|
+
rate: 25,
|
|
453
|
+
main: false,
|
|
454
|
+
metadata: null,
|
|
455
|
+
inputs: [
|
|
456
|
+
{ id: "node_a", value: 30, subText: "قلم", subValue: 150, time: 1717851000 },
|
|
457
|
+
],
|
|
458
|
+
outputs: [],
|
|
459
|
+
},
|
|
460
|
+
{ minGap: 100 } // حداقل فاصله از سایر گرهها (پیکسل)
|
|
461
|
+
);
|
|
462
|
+
|
|
463
|
+
if (result.success) {
|
|
464
|
+
console.log(result.node); // گره با x,y محاسبهشده
|
|
465
|
+
console.log(result.data); // کل آرایه بهروز
|
|
466
|
+
} else {
|
|
467
|
+
console.error(result.error);
|
|
468
|
+
}
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
**پاسخ:**
|
|
472
|
+
|
|
473
|
+
```ts
|
|
474
|
+
// موفق
|
|
475
|
+
{ success: true, node: GraphNode, data: GraphNode[], length: number }
|
|
476
|
+
|
|
477
|
+
// ناموفق
|
|
478
|
+
{ success: false, error: string }
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
### `GetSelectedNode()`
|
|
482
|
+
|
|
483
|
+
گره انتخابشده فعلی را برمیگرداند (یا `null`).
|
|
484
|
+
|
|
485
|
+
### `SetSelectedNode(node)`
|
|
486
|
+
|
|
487
|
+
گره انتخابشده را از بیرون تنظیم میکند.
|
|
488
|
+
|
|
489
|
+
```js
|
|
490
|
+
SetSelectedNode(null); // پاک کردن انتخاب
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
### `OnNodeClick(handler)`
|
|
494
|
+
|
|
495
|
+
ثبت callback سراسری برای کلیک روی گره (`handler` میتواند `null` باشد).
|
|
496
|
+
|
|
497
|
+
### `getSafeNodePosition(params)`
|
|
498
|
+
|
|
499
|
+
موقعیت امن برای گره جدید را بدون افزودن به گراف محاسبه میکند.
|
|
500
|
+
|
|
501
|
+
```js
|
|
502
|
+
const { x, y, width } = getSafeNodePosition({
|
|
503
|
+
node: rawNode,
|
|
504
|
+
nodes: existingNodes,
|
|
505
|
+
anchorIds: ["node_a", "node_b"], // گرههای مرتبط
|
|
506
|
+
minGap: 100,
|
|
507
|
+
});
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
---
|
|
511
|
+
|
|
512
|
+
## ابزارهای داخلی UI
|
|
513
|
+
|
|
514
|
+
پس از رندر گراف، پنل **Graph Panel** در دسترس است (بالا-چپ). دکمههای خروجی (اسکرینشات/اکسل) در نوار جداگانه بالا-راست قرار میگیرند. چهار مورد زیر میتوانند توسط توسعهدهنده ثابت یا در اختیار کاربر گذاشته شوند (جزئیات در [پیکربندی ابزارهای UI](#پیکربندی-ابزارهای-ui-گرید-جابهجایی-یال-زبان)):
|
|
515
|
+
|
|
516
|
+
| ابزار | توضیح | props مرتبط |
|
|
517
|
+
|--------|--------|-------------|
|
|
518
|
+
| **زبان** | فارسی / انگلیسی | `languageUserConfigurable`, `language` |
|
|
519
|
+
| **جستجو** | هایلایت گره بر اساس ID یا Label | — |
|
|
520
|
+
| **نمایش اطلاعات یال** | گرههای میانی روی یالها | `edgeInfoNodesUserConfigurable`, `showEdgeInfoNodes` |
|
|
521
|
+
| **گرید** | شبکهٔ پسزمینه | `gridUserConfigurable`, `showGrid` |
|
|
522
|
+
| **جابهجایی گره** | drag گرههای `main` | `nodesDraggableUserConfigurable`, `nodesDraggable` |
|
|
523
|
+
| **رنگ یال** | رنگآمیزی یالهای انتخابشده | — |
|
|
524
|
+
| **مرتبسازی (Arrange)** | چیدمان خودکار گرهها | — |
|
|
525
|
+
| **اسکرینشات** | ذخیره تصویر کل گراف (نوار خروجی بالا-راست) | — |
|
|
526
|
+
| **خروجی Excel** | export به `.xlsx` (نوار خروجی بالا-راست) | — |
|
|
527
|
+
| **هایلایت مسیرها** | مسیرهای جهتدار بین دو ID | — |
|
|
528
|
+
|
|
529
|
+
**تعاملات:**
|
|
530
|
+
|
|
531
|
+
- **Drag** گرههای `main` (قابل غیرفعالسازی با `nodesDraggable`)
|
|
532
|
+
- **Pan / Zoom** با ماوس (همیشه فعال)
|
|
533
|
+
- **Hover** برای tooltip اطلاعات گره؛ هاور یال با `showEdgeHoverInfo`
|
|
534
|
+
- **Multi-select** گرهها و یالها
|
|
535
|
+
|
|
536
|
+
---
|
|
537
|
+
|
|
538
|
+
## منطق گراف و یالها
|
|
539
|
+
|
|
540
|
+
### انواع گره
|
|
541
|
+
|
|
542
|
+
```
|
|
543
|
+
NODE_TYPE.MAIN → "main" گره اصلی (با تصویر/آیکون)
|
|
544
|
+
NODE_TYPE.SUB → "sub" گره واسط (نقطه کوچک)
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
### ساخت یالها
|
|
548
|
+
|
|
549
|
+
یالهای vis-network **فقط از گرههای `type: "main"`** ساخته میشوند:
|
|
550
|
+
|
|
551
|
+
- هر آیتم در `outputs` → یال از این گره به `id` مقصد
|
|
552
|
+
- هر آیتم در `inputs` → یال از `id` مبدأ به این گره
|
|
553
|
+
|
|
554
|
+
گرههای `sub` در توپولوژی نقش واسطه دارند؛ اتصال واقعی از طریق `inputs`/`outputs` گرههای `main` تعریف میشود.
|
|
555
|
+
|
|
556
|
+
### گرههای کمکی (خودکار)
|
|
557
|
+
|
|
558
|
+
| پسوند ID | نقش |
|
|
559
|
+
|----------|-----|
|
|
560
|
+
| `Tr..._in` / `Tr..._out` | گره اطلاعات یال (لیبل میانی) |
|
|
561
|
+
| `hotWallet` | آیکون متادیتا |
|
|
562
|
+
| `_Arrow` | فلش برای گرههای `main: true` |
|
|
563
|
+
|
|
564
|
+
### برچسب نمایشی گره
|
|
565
|
+
|
|
566
|
+
| نوع | منبع برچسب |
|
|
567
|
+
|-----|------------|
|
|
568
|
+
| `sub` | `subText` |
|
|
569
|
+
| `main` | `label` → `entity.name` → `...` + ۷ کاراکتر اول `text` |
|
|
570
|
+
|
|
571
|
+
---
|
|
572
|
+
|
|
573
|
+
## Exportها و ثابتها
|
|
574
|
+
|
|
575
|
+
```js
|
|
576
|
+
import {
|
|
577
|
+
Graph_Engine,
|
|
578
|
+
AddNewNode,
|
|
579
|
+
GetSelectedNode,
|
|
580
|
+
SetSelectedNode,
|
|
581
|
+
OnNodeClick,
|
|
582
|
+
getSafeNodePosition,
|
|
583
|
+
|
|
584
|
+
// ثابتها
|
|
585
|
+
NODE_TYPE,
|
|
586
|
+
EDGE_LABEL_FIELDS,
|
|
587
|
+
DEFAULT_EDGE_LABEL_FIELDS,
|
|
588
|
+
DEFAULT_RATE_COLOR_RANGES,
|
|
589
|
+
GRAPH_LANGUAGE,
|
|
590
|
+
|
|
591
|
+
// توابع کمکی
|
|
592
|
+
normalizeEdgeLabelFields,
|
|
593
|
+
normalizeRateColorRanges,
|
|
594
|
+
normalizeGraphLanguage,
|
|
595
|
+
getRateBorderColor,
|
|
596
|
+
buildEdgeInfoLabel,
|
|
597
|
+
getNodeDisplayLabel,
|
|
598
|
+
getNodeEntityImage,
|
|
599
|
+
getGraphGuide,
|
|
600
|
+
|
|
601
|
+
// edition و شمارش گره
|
|
602
|
+
NODALIX_EDITION,
|
|
603
|
+
NODALIX_MAX_NODES,
|
|
604
|
+
isBasicEdition,
|
|
605
|
+
isFullEdition,
|
|
606
|
+
hasNodeLimit,
|
|
607
|
+
countGraphNodes,
|
|
608
|
+
enforceNodeLimit,
|
|
609
|
+
} from "nodalix";
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
ثابتهای edition در بیلد فعلی:
|
|
613
|
+
|
|
614
|
+
```js
|
|
615
|
+
NODALIX_EDITION; // "full"
|
|
616
|
+
NODALIX_MAX_NODES; // Infinity (بدون محدودیت تعداد گره)
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
ثابتهای زبان:
|
|
620
|
+
|
|
621
|
+
```js
|
|
622
|
+
GRAPH_LANGUAGE.FA // "fa"
|
|
623
|
+
GRAPH_LANGUAGE.EN // "en"
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
تابع `normalizeGraphLanguage(value)` مقدار ورودی را به `"fa"` یا `"en"` نرمال میکند.
|
|
627
|
+
|
|
628
|
+
---
|
|
629
|
+
|
|
630
|
+
## ساخت و توسعه
|
|
631
|
+
|
|
632
|
+
```bash
|
|
633
|
+
# نصب وابستگیها
|
|
634
|
+
npm install
|
|
635
|
+
|
|
636
|
+
# بیلد production (خروجی در dist/)
|
|
637
|
+
npm run build
|
|
638
|
+
|
|
639
|
+
# بیلد با watch
|
|
640
|
+
npm run dev
|
|
641
|
+
|
|
642
|
+
# اجرای تستها
|
|
643
|
+
npm test
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
### TypeScript Support
|
|
647
|
+
|
|
648
|
+
پکیج خروجی دارای فایل type declaration است:
|
|
649
|
+
|
|
650
|
+
```ts
|
|
651
|
+
import { Graph_Engine, type GraphNode, EDGE_LINE_STYLE } from "nodalix";
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
در CI نیز build/test روی push و pull request اجرا میشود (فایل: `.github/workflows/ci.yml`).
|
|
655
|
+
|
|
656
|
+
### ساختار پروژه
|
|
657
|
+
|
|
658
|
+
```
|
|
659
|
+
nodalix/
|
|
660
|
+
├── src/
|
|
661
|
+
│ ├── index.js # نقطه ورود و API عمومی
|
|
662
|
+
│ ├── edition.js # متادیتای edition بیلد
|
|
663
|
+
│ ├── graphNodeLimits.js # شمارش و محدودیت گره (ابزار داخلی)
|
|
664
|
+
│ ├── graphConfig.js # ثابتها و helperهای پیکربندی
|
|
665
|
+
│ └── Components/
|
|
666
|
+
│ ├── Graph.js # موتور گراف و UI
|
|
667
|
+
│ ├── SetEdgesData.js # ساخت یال از inputs/outputs
|
|
668
|
+
│ ├── Options.js # تنظیمات vis-network
|
|
669
|
+
│ └── miladiCalendar.js # تبدیل timestamp به تاریخ
|
|
670
|
+
├── dist/ # خروجی بیلد
|
|
671
|
+
├── package.json
|
|
672
|
+
└── tsup.config.js
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
در حال حاضر فقط یک بسته منتشر میشود: **nodalix** (نسخهٔ کامل، بدون محدودیت تعداد گره).
|
|
676
|
+
|
|
677
|
+
```bash
|
|
678
|
+
npm run build # خروجی در dist/
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
---
|
|
682
|
+
|
|
683
|
+
### پروژه تست
|
|
684
|
+
|
|
685
|
+
پوشهٔ `nodalix-test` (همسطح) نمونهٔ استفاده از کتابخانه با Next.js است و شامل مثال پیکربندی ابزارهای UI (`gridUserConfigurable`, `nodesDraggable`, `showEdgeInfoNodes`, `language` و …) میشود.
|
|
686
|
+
|
|
687
|
+
---
|
|
688
|
+
|
|
689
|
+
## نکات مهم
|
|
690
|
+
|
|
691
|
+
### تصاویر
|
|
692
|
+
|
|
693
|
+
گرههای `main` از مسیرهای زیر استفاده میکنند. این فایلها باید در `public/` پروژهٔ مصرفکننده باشند:
|
|
694
|
+
|
|
695
|
+
```
|
|
696
|
+
/images/location.png — تصویر پیشفرض گره
|
|
697
|
+
/images/fire.png — آیکون متادیتا
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
یا `entity.image` / `entity.metadata.image` را در داده تنظیم کنید.
|
|
701
|
+
|
|
702
|
+
### Client Component
|
|
703
|
+
|
|
704
|
+
`Graph_Engine` با `"use client"` علامتگذاری شده. در Next.js App Router حتماً در کامپوننت کلاینت import کنید.
|
|
705
|
+
|
|
706
|
+
### همگامسازی state
|
|
707
|
+
|
|
708
|
+
- `NewData` فقط در mount و تغییر prop همگام میشود.
|
|
709
|
+
- برای افزودن گره در runtime از `AddNewNode` استفاده کنید (state داخلی را خودش بهروز میکند).
|
|
710
|
+
- اگر `NewData` را از والد تغییر دهید، state داخلی بازنویسی میشود.
|
|
711
|
+
|
|
712
|
+
### تم تاریک
|
|
713
|
+
|
|
714
|
+
اگر روی `<html>` کلاس `dark` باشد، گراف بهصورت خودکار تم تاریک میگیرد.
|
|
715
|
+
|
|
716
|
+
### محدودیتها
|
|
717
|
+
|
|
718
|
+
- فیزیک گراف همیشه خاموش است (چیدمان قطعی).
|
|
719
|
+
- `AddNewNode` و `GetSelectedNode` فقط وقتی `Graph_Engine` mount است کار میکنند.
|
|
720
|
+
- برای گرافهای بسیار بزرگ (هزاران گره)، Auto Arrange ممکن است چند ثانیه طول بکشد.
|
|
721
|
+
|
|
722
|
+
---
|
|
723
|
+
|
|
724
|
+
## مجوز
|
|
725
|
+
|
|
726
|
+
MIT
|