nodalix 0.1.0 → 1.0.1
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 +274 -274
- package/dist/index.js +1 -27
- package/dist/index.mjs +1 -27
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,73 +1,73 @@
|
|
|
1
1
|
# Nodalix
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A React library for visualizing and analyzing network graphs with **vis-network**. Ideal for showing relationships between entities, data flows, or processes between main and intermediate nodes, with interactive edge information (value, time, supplementary text, and more).
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Created by:** Mohammad Salehi
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
##
|
|
10
|
-
|
|
11
|
-
- [
|
|
12
|
-
- [
|
|
13
|
-
- [
|
|
14
|
-
- [
|
|
15
|
-
- [
|
|
16
|
-
- [
|
|
17
|
-
- [
|
|
18
|
-
- [
|
|
19
|
-
- [
|
|
20
|
-
- [
|
|
21
|
-
- [
|
|
22
|
-
- [
|
|
23
|
-
- [
|
|
24
|
-
- [
|
|
9
|
+
## Table of Contents
|
|
10
|
+
|
|
11
|
+
- [Features](#features)
|
|
12
|
+
- [Prerequisites](#prerequisites)
|
|
13
|
+
- [Installation](#installation)
|
|
14
|
+
- [Quick Start](#quick-start)
|
|
15
|
+
- [Data Structure](#data-structure)
|
|
16
|
+
- [`Graph_Engine` Component](#graph_engine-component)
|
|
17
|
+
- [Dynamic Configuration](#dynamic-configuration)
|
|
18
|
+
- [UI Tools Configuration](#ui-tools-configuration-grid-drag-edges-language)
|
|
19
|
+
- [Imperative APIs](#imperative-apis)
|
|
20
|
+
- [Built-in UI Tools](#built-in-ui-tools)
|
|
21
|
+
- [Graph and Edge Logic](#graph-and-edge-logic)
|
|
22
|
+
- [Exports and Constants](#exports-and-constants)
|
|
23
|
+
- [Build and Development](#build-and-development)
|
|
24
|
+
- [Important Notes](#important-notes)
|
|
25
25
|
|
|
26
26
|
---
|
|
27
27
|
|
|
28
|
-
##
|
|
29
|
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
28
|
+
## Features
|
|
29
|
+
|
|
30
|
+
- Interactive graph rendering (drag, zoom, node/edge selection)
|
|
31
|
+
- Two node types: **main** (primary node) and **sub** (intermediate node)
|
|
32
|
+
- Edge information displayed on intermediate nodes (user-configurable or developer-fixed)
|
|
33
|
+
- Background grid (user-toggleable or developer-fixed)
|
|
34
|
+
- Draggable `main` nodes (user-toggleable or developer-fixed)
|
|
35
|
+
- Persian/English UI (bilingual or single-language, developer-controlled)
|
|
36
|
+
- Node border coloring based on **rate** and configurable ranges
|
|
37
|
+
- Automatic node layout (Auto Arrange)
|
|
38
|
+
- Live search, path highlighting, edge coloring
|
|
39
|
+
- Screenshot and Excel export
|
|
40
|
+
- Add nodes from outside the component with `AddNewNode`
|
|
41
|
+
- Light/dark theme support (based on the `dark` class on `<html>`)
|
|
42
42
|
|
|
43
43
|
---
|
|
44
44
|
|
|
45
|
-
##
|
|
45
|
+
## Prerequisites
|
|
46
46
|
|
|
47
|
-
|
|
|
48
|
-
|
|
47
|
+
| Dependency | Version |
|
|
48
|
+
|------------|---------|
|
|
49
49
|
| React | `>= 18` |
|
|
50
50
|
| React DOM | `>= 18` |
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
In **Next.js** projects, the component must be used inside a Client Component (`"use client"`).
|
|
53
53
|
|
|
54
54
|
---
|
|
55
55
|
|
|
56
|
-
##
|
|
56
|
+
## Installation
|
|
57
57
|
|
|
58
|
-
###
|
|
58
|
+
### From a local path (development)
|
|
59
59
|
|
|
60
60
|
```bash
|
|
61
|
-
#
|
|
61
|
+
# Build the library first
|
|
62
62
|
cd nodalix
|
|
63
63
|
npm install
|
|
64
64
|
npm run build
|
|
65
65
|
|
|
66
|
-
#
|
|
66
|
+
# In the consuming project
|
|
67
67
|
npm install file:../nodalix
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
-
###
|
|
70
|
+
### From npm (after publishing)
|
|
71
71
|
|
|
72
72
|
```bash
|
|
73
73
|
npm install nodalix
|
|
@@ -75,7 +75,7 @@ npm install nodalix
|
|
|
75
75
|
|
|
76
76
|
---
|
|
77
77
|
|
|
78
|
-
##
|
|
78
|
+
## Quick Start
|
|
79
79
|
|
|
80
80
|
```jsx
|
|
81
81
|
"use client";
|
|
@@ -90,9 +90,9 @@ const data = [
|
|
|
90
90
|
{
|
|
91
91
|
id: "node_a",
|
|
92
92
|
type: NODE_TYPE.MAIN,
|
|
93
|
-
text: "
|
|
94
|
-
label: "
|
|
95
|
-
entity: { name: "
|
|
93
|
+
text: "Source A",
|
|
94
|
+
label: "Origin Node",
|
|
95
|
+
entity: { name: "Team Alpha" },
|
|
96
96
|
rate: 12,
|
|
97
97
|
main: true,
|
|
98
98
|
metadata: null,
|
|
@@ -103,7 +103,7 @@ const data = [
|
|
|
103
103
|
{
|
|
104
104
|
id: "step_1",
|
|
105
105
|
value: 120,
|
|
106
|
-
subText: "
|
|
106
|
+
subText: "unit",
|
|
107
107
|
subValue: 4800,
|
|
108
108
|
time: 1717851000,
|
|
109
109
|
},
|
|
@@ -112,27 +112,27 @@ const data = [
|
|
|
112
112
|
{
|
|
113
113
|
id: "step_1",
|
|
114
114
|
type: NODE_TYPE.SUB,
|
|
115
|
-
text: "
|
|
115
|
+
text: "Step 1",
|
|
116
116
|
label: null,
|
|
117
117
|
entity: null,
|
|
118
118
|
rate: null,
|
|
119
119
|
main: false,
|
|
120
120
|
metadata: null,
|
|
121
|
-
subText: "
|
|
121
|
+
subText: "Processing",
|
|
122
122
|
x: -210,
|
|
123
123
|
y: 0,
|
|
124
124
|
inputs: [
|
|
125
|
-
{ id: "node_a", value: 120, subText: "
|
|
125
|
+
{ id: "node_a", value: 120, subText: "unit", subValue: 4800, time: 1717851000 },
|
|
126
126
|
],
|
|
127
127
|
outputs: [
|
|
128
|
-
{ id: "node_b", value: 120, subText: "
|
|
128
|
+
{ id: "node_b", value: 120, subText: "unit", subValue: 4800, time: 1717851000 },
|
|
129
129
|
],
|
|
130
130
|
},
|
|
131
131
|
{
|
|
132
132
|
id: "node_b",
|
|
133
133
|
type: NODE_TYPE.MAIN,
|
|
134
|
-
text: "
|
|
135
|
-
label: "
|
|
134
|
+
text: "Destination B",
|
|
135
|
+
label: "End Node",
|
|
136
136
|
entity: null,
|
|
137
137
|
rate: 45,
|
|
138
138
|
main: false,
|
|
@@ -140,7 +140,7 @@ const data = [
|
|
|
140
140
|
x: 0,
|
|
141
141
|
y: 0,
|
|
142
142
|
inputs: [
|
|
143
|
-
{ id: "step_1", value: 120, subText: "
|
|
143
|
+
{ id: "step_1", value: 120, subText: "unit", subValue: 4800, time: 1717851000 },
|
|
144
144
|
],
|
|
145
145
|
outputs: [],
|
|
146
146
|
},
|
|
@@ -168,98 +168,98 @@ export default function App() {
|
|
|
168
168
|
}
|
|
169
169
|
```
|
|
170
170
|
|
|
171
|
-
>
|
|
171
|
+
> **Note:** The parent container must have a defined height for the graph to render correctly.
|
|
172
172
|
|
|
173
173
|
---
|
|
174
174
|
|
|
175
|
-
##
|
|
176
|
-
|
|
177
|
-
###
|
|
178
|
-
|
|
179
|
-
|
|
|
180
|
-
|
|
181
|
-
| `id` | `string` |
|
|
182
|
-
| `type` | `"main"` \| `"sub"` | `main` =
|
|
183
|
-
| `text` | `string` |
|
|
184
|
-
| `label` | `string \| null` |
|
|
185
|
-
| `subText` | `string \| null` |
|
|
186
|
-
| `entity` | `object \| null` | `{ name, image?, metadata? }` —
|
|
187
|
-
| `rate` | `number \| null` |
|
|
188
|
-
| `main` | `boolean` |
|
|
189
|
-
| `metadata` | `string \| null` |
|
|
190
|
-
| `x`, `y` | `number` |
|
|
191
|
-
| `inputs` | `EdgeRef[]` |
|
|
192
|
-
| `outputs` | `EdgeRef[]` |
|
|
193
|
-
|
|
194
|
-
###
|
|
195
|
-
|
|
196
|
-
|
|
|
197
|
-
|
|
198
|
-
| `id` | `string` |
|
|
199
|
-
| `value` | `number` |
|
|
200
|
-
| `subText` | `string` |
|
|
201
|
-
| `subValue` | `number` |
|
|
202
|
-
| `time` | `number` |
|
|
203
|
-
|
|
204
|
-
###
|
|
175
|
+
## Data Structure
|
|
176
|
+
|
|
177
|
+
### Node (`GraphNode`)
|
|
178
|
+
|
|
179
|
+
| Field | Type | Description |
|
|
180
|
+
|-------|------|-------------|
|
|
181
|
+
| `id` | `string` | Unique identifier (required) |
|
|
182
|
+
| `type` | `"main"` \| `"sub"` | `main` = primary node, `sub` = intermediate node |
|
|
183
|
+
| `text` | `string` | Primary text (internal ID or short description) |
|
|
184
|
+
| `label` | `string \| null` | Display label for `main` nodes |
|
|
185
|
+
| `subText` | `string \| null` | Display label for `sub` nodes |
|
|
186
|
+
| `entity` | `object \| null` | `{ name, image?, metadata? }` — related entity info |
|
|
187
|
+
| `rate` | `number \| null` | Numeric score (e.g. 0–100) — determines border color |
|
|
188
|
+
| `main` | `boolean` | When `true`, shows arrow and special styling |
|
|
189
|
+
| `metadata` | `string \| null` | When set, shows a supplementary icon |
|
|
190
|
+
| `x`, `y` | `number` | Initial position on the canvas |
|
|
191
|
+
| `inputs` | `EdgeRef[]` | Incoming connections |
|
|
192
|
+
| `outputs` | `EdgeRef[]` | Outgoing connections |
|
|
193
|
+
|
|
194
|
+
### Edge Reference (`EdgeRef` — inside `inputs` / `outputs`)
|
|
195
|
+
|
|
196
|
+
| Field | Type | Description |
|
|
197
|
+
|-------|------|-------------|
|
|
198
|
+
| `id` | `string` | Connected node ID |
|
|
199
|
+
| `value` | `number` | Primary value |
|
|
200
|
+
| `subText` | `string` | Supplementary text (unit, category, short label, etc.) |
|
|
201
|
+
| `subValue` | `number` | Secondary value (e.g. converted amount or reference) |
|
|
202
|
+
| `time` | `number` | Unix timestamp (seconds) |
|
|
203
|
+
|
|
204
|
+
### Full Example
|
|
205
205
|
|
|
206
206
|
```js
|
|
207
207
|
{
|
|
208
208
|
id: "node_c",
|
|
209
209
|
type: "main",
|
|
210
|
-
text: "
|
|
211
|
-
label: "
|
|
212
|
-
entity: { name: "
|
|
210
|
+
text: "Node C-1042",
|
|
211
|
+
label: "Warehouse Zone 2",
|
|
212
|
+
entity: { name: "Logistics Unit" },
|
|
213
213
|
rate: 55,
|
|
214
214
|
main: false,
|
|
215
|
-
metadata: "
|
|
215
|
+
metadata: "Needs review",
|
|
216
216
|
x: 0,
|
|
217
217
|
y: 0,
|
|
218
218
|
inputs: [
|
|
219
|
-
{ id: "step_2", value: 48, subText: "
|
|
219
|
+
{ id: "step_2", value: 48, subText: "package", subValue: 960, time: 1717851200 },
|
|
220
220
|
],
|
|
221
221
|
outputs: [
|
|
222
|
-
{ id: "step_3", value: 48, subText: "
|
|
222
|
+
{ id: "step_3", value: 48, subText: "package", subValue: 960, time: 1717851300 },
|
|
223
223
|
],
|
|
224
224
|
}
|
|
225
225
|
```
|
|
226
226
|
|
|
227
227
|
---
|
|
228
228
|
|
|
229
|
-
##
|
|
229
|
+
## `Graph_Engine` Component
|
|
230
230
|
|
|
231
|
-
|
|
231
|
+
The main component and the only UI entry point of the library.
|
|
232
232
|
|
|
233
233
|
### Props
|
|
234
234
|
|
|
235
|
-
| Prop |
|
|
236
|
-
|
|
237
|
-
| `NewData` | `GraphNode[]` | `[]` |
|
|
238
|
-
| `onNodeClick` | `(node) => void` | — |
|
|
239
|
-
| `edgeLabelFields` | `string[]` | `["value","subText","time"]` |
|
|
240
|
-
| `rateColorRanges` | `RateColorRange[]` | [
|
|
241
|
-
| `showEdgeHoverInfo` | `boolean` | `false` |
|
|
242
|
-
| `showHelpButton` | `boolean` | `true` |
|
|
243
|
-
| `gridUserConfigurable` | `boolean` | `true` |
|
|
244
|
-
| `showGrid` | `boolean` | `true` |
|
|
245
|
-
| `nodesDraggableUserConfigurable` | `boolean` | `true` |
|
|
246
|
-
| `nodesDraggable` | `boolean` | `true` |
|
|
247
|
-
| `edgeInfoNodesUserConfigurable` | `boolean` | `true` |
|
|
248
|
-
| `showEdgeInfoNodes` | `boolean` | `true` |
|
|
249
|
-
| `languageUserConfigurable` | `boolean` | `true` |
|
|
250
|
-
| `language` | `"fa"` \| `"en"` | `"fa"` |
|
|
251
|
-
|
|
252
|
-
###
|
|
235
|
+
| Prop | Type | Default | Description |
|
|
236
|
+
|------|------|---------|-------------|
|
|
237
|
+
| `NewData` | `GraphNode[]` | `[]` | Array of graph nodes |
|
|
238
|
+
| `onNodeClick` | `(node) => void` | — | Callback when a node is clicked |
|
|
239
|
+
| `edgeLabelFields` | `string[]` | `["value","subText","time"]` | Fields shown on edge labels |
|
|
240
|
+
| `rateColorRanges` | `RateColorRange[]` | [default below](#rate-coloring-ratecolorranges) | Color ranges for `rate` |
|
|
241
|
+
| `showEdgeHoverInfo` | `boolean` | `false` | Show edge info on mouse hover |
|
|
242
|
+
| `showHelpButton` | `boolean` | `true` | Show the help button in the graph corner |
|
|
243
|
+
| `gridUserConfigurable` | `boolean` | `true` | When `false`, the user cannot toggle the grid |
|
|
244
|
+
| `showGrid` | `boolean` | `true` | Grid state (fixed or initial value when user-configurable) |
|
|
245
|
+
| `nodesDraggableUserConfigurable` | `boolean` | `true` | When `false`, the user cannot toggle node dragging |
|
|
246
|
+
| `nodesDraggable` | `boolean` | `true` | Whether `main` nodes are draggable |
|
|
247
|
+
| `edgeInfoNodesUserConfigurable` | `boolean` | `true` | When `false`, the user cannot toggle edge info nodes |
|
|
248
|
+
| `showEdgeInfoNodes` | `boolean` | `true` | Show intermediate edge info nodes |
|
|
249
|
+
| `languageUserConfigurable` | `boolean` | `true` | When `false`, the user cannot change the language |
|
|
250
|
+
| `language` | `"fa"` \| `"en"` | `"fa"` | Fixed or initial language (`GRAPH_LANGUAGE.FA` / `GRAPH_LANGUAGE.EN`) |
|
|
251
|
+
|
|
252
|
+
### `RateColorRange` Type
|
|
253
253
|
|
|
254
254
|
```ts
|
|
255
255
|
type RateColorRange = {
|
|
256
|
-
min: number; //
|
|
257
|
-
max: number; //
|
|
258
|
-
color: string; //
|
|
256
|
+
min: number; // Range minimum (inclusive)
|
|
257
|
+
max: number; // Range maximum (exclusive; use Infinity for the last range)
|
|
258
|
+
color: string; // CSS color name or code
|
|
259
259
|
};
|
|
260
260
|
```
|
|
261
261
|
|
|
262
|
-
|
|
262
|
+
**Default:**
|
|
263
263
|
|
|
264
264
|
```js
|
|
265
265
|
[
|
|
@@ -268,51 +268,51 @@ type RateColorRange = {
|
|
|
268
268
|
]
|
|
269
269
|
```
|
|
270
270
|
|
|
271
|
-
|
|
271
|
+
Nodes without a `rate` or outside all ranges use the theme's default border color.
|
|
272
272
|
|
|
273
273
|
---
|
|
274
274
|
|
|
275
|
-
##
|
|
275
|
+
## Dynamic Configuration
|
|
276
276
|
|
|
277
|
-
###
|
|
277
|
+
### Edge Label Fields (`edgeLabelFields`)
|
|
278
278
|
|
|
279
|
-
|
|
279
|
+
Allowed values (from `EDGE_LABEL_FIELDS`):
|
|
280
280
|
|
|
281
|
-
|
|
|
282
|
-
|
|
283
|
-
| `VALUE` | `"value"` |
|
|
284
|
-
| `SUB_TEXT` | `"subText"` |
|
|
285
|
-
| `SUB_VALUE` | `"subValue"` |
|
|
286
|
-
| `TIME` | `"time"` |
|
|
281
|
+
| Key | Value | Display |
|
|
282
|
+
|-----|-------|---------|
|
|
283
|
+
| `VALUE` | `"value"` | Primary numeric value |
|
|
284
|
+
| `SUB_TEXT` | `"subText"` | Supplementary text (alongside value) |
|
|
285
|
+
| `SUB_VALUE` | `"subValue"` | Secondary value (formatted numerically in the UI) |
|
|
286
|
+
| `TIME` | `"time"` | Gregorian date and time |
|
|
287
287
|
|
|
288
|
-
|
|
288
|
+
**Examples:**
|
|
289
289
|
|
|
290
290
|
```jsx
|
|
291
|
-
//
|
|
291
|
+
// value + supplementary text + time (default)
|
|
292
292
|
edgeLabelFields={["value", "subText", "time"]}
|
|
293
293
|
|
|
294
|
-
//
|
|
294
|
+
// secondary value and time only
|
|
295
295
|
edgeLabelFields={["subValue", "time"]}
|
|
296
296
|
|
|
297
|
-
//
|
|
297
|
+
// all fields
|
|
298
298
|
edgeLabelFields={["value", "subText", "subValue", "time"]}
|
|
299
299
|
```
|
|
300
300
|
|
|
301
|
-
###
|
|
301
|
+
### Rate Coloring (`rateColorRanges`)
|
|
302
302
|
|
|
303
303
|
```jsx
|
|
304
304
|
rateColorRanges={[
|
|
305
|
-
{ min: 0, max: 30, color: "#22c55e" }, //
|
|
306
|
-
{ min: 30, max: 60, color: "#eab308" }, //
|
|
307
|
-
{ min: 60, max: Infinity, color: "#ef4444" }, //
|
|
305
|
+
{ min: 0, max: 30, color: "#22c55e" }, // low score
|
|
306
|
+
{ min: 30, max: 60, color: "#eab308" }, // medium score
|
|
307
|
+
{ min: 60, max: Infinity, color: "#ef4444" }, // high score
|
|
308
308
|
]}
|
|
309
309
|
```
|
|
310
310
|
|
|
311
|
-
|
|
311
|
+
Ranges are checked in array order; the first matching range is applied.
|
|
312
312
|
|
|
313
|
-
###
|
|
313
|
+
### Edge Hover (`showEdgeHoverInfo`)
|
|
314
314
|
|
|
315
|
-
|
|
315
|
+
Disabled by default. When enabled, hovering over an edge shows source/target IDs and the fields selected in `edgeLabelFields`:
|
|
316
316
|
|
|
317
317
|
```jsx
|
|
318
318
|
<Graph_Engine
|
|
@@ -322,94 +322,94 @@ rateColorRanges={[
|
|
|
322
322
|
/>
|
|
323
323
|
```
|
|
324
324
|
|
|
325
|
-
###
|
|
325
|
+
### Help Button (`showHelpButton`)
|
|
326
326
|
|
|
327
|
-
|
|
327
|
+
Enabled by default. The `?` button in the bottom-right corner shows usage help in the language selected in the tools panel (Persian/English):
|
|
328
328
|
|
|
329
329
|
```jsx
|
|
330
330
|
<Graph_Engine NewData={data} showHelpButton />
|
|
331
331
|
```
|
|
332
332
|
|
|
333
|
-
|
|
333
|
+
To hide it: `showHelpButton={false}`
|
|
334
334
|
|
|
335
335
|
---
|
|
336
336
|
|
|
337
|
-
##
|
|
337
|
+
## UI Tools Configuration (Grid, Drag, Edges, Language)
|
|
338
338
|
|
|
339
|
-
|
|
339
|
+
Four sections of the **Graph Tools** panel can be controlled externally. Each has two modes:
|
|
340
340
|
|
|
341
|
-
|
|
|
342
|
-
|
|
343
|
-
|
|
|
344
|
-
|
|
|
341
|
+
| Mode | `*UserConfigurable` | Behavior |
|
|
342
|
+
|------|---------------------|----------|
|
|
343
|
+
| **User choice** | `true` (default) | Toggle/button shown in the panel; user can change it |
|
|
344
|
+
| **Developer-fixed** | `false` | Toggle hidden; value comes from the second prop |
|
|
345
345
|
|
|
346
|
-
###
|
|
346
|
+
### Props Summary
|
|
347
347
|
|
|
348
|
-
|
|
|
349
|
-
|
|
350
|
-
|
|
|
351
|
-
|
|
|
352
|
-
|
|
|
353
|
-
|
|
|
348
|
+
| Feature | User choice | Fixed / initial value | Default |
|
|
349
|
+
|---------|-------------|----------------------|---------|
|
|
350
|
+
| Background grid | `gridUserConfigurable` | `showGrid` | `true` / `true` |
|
|
351
|
+
| Node dragging | `nodesDraggableUserConfigurable` | `nodesDraggable` | `true` / `true` |
|
|
352
|
+
| Edge info nodes | `edgeInfoNodesUserConfigurable` | `showEdgeInfoNodes` | `true` / `true` |
|
|
353
|
+
| UI language | `languageUserConfigurable` | `language` (`"fa"` \| `"en"`) | `true` / `"fa"` |
|
|
354
354
|
|
|
355
|
-
>
|
|
356
|
-
>
|
|
355
|
+
> When `*UserConfigurable={true}`, the second prop is the **initial value** (the user can change it later).
|
|
356
|
+
> When `*UserConfigurable={false}`, the second prop is the **fixed value**.
|
|
357
357
|
|
|
358
|
-
###
|
|
358
|
+
### Grid (`showGrid` / `gridUserConfigurable`)
|
|
359
359
|
|
|
360
|
-
|
|
360
|
+
The background grid and node snapping during drag and Auto Arrange depend on the grid.
|
|
361
361
|
|
|
362
362
|
```jsx
|
|
363
|
-
//
|
|
363
|
+
// User can toggle the grid (default)
|
|
364
364
|
<Graph_Engine NewData={data} />
|
|
365
365
|
|
|
366
|
-
//
|
|
366
|
+
// Grid always off; no checkbox in the panel
|
|
367
367
|
<Graph_Engine NewData={data} gridUserConfigurable={false} showGrid={false} />
|
|
368
368
|
```
|
|
369
369
|
|
|
370
|
-
###
|
|
370
|
+
### Node Dragging (`nodesDraggable` / `nodesDraggableUserConfigurable`)
|
|
371
371
|
|
|
372
|
-
|
|
372
|
+
Only nodes with `type: "main"` are draggable; helper nodes (`_Arrow`, `hotWallet`, `Tr…`) always stay fixed. Pan and zoom are not affected by this setting.
|
|
373
373
|
|
|
374
374
|
```jsx
|
|
375
|
-
//
|
|
375
|
+
// Nodes always fixed; user cannot drag
|
|
376
376
|
<Graph_Engine NewData={data} nodesDraggableUserConfigurable={false} nodesDraggable={false} />
|
|
377
377
|
|
|
378
|
-
//
|
|
378
|
+
// Default: dragging enabled; user can toggle from the panel
|
|
379
379
|
<Graph_Engine NewData={data} nodesDraggableUserConfigurable nodesDraggable />
|
|
380
380
|
```
|
|
381
381
|
|
|
382
|
-
###
|
|
382
|
+
### Edge Info Nodes (`showEdgeInfoNodes` / `edgeInfoNodesUserConfigurable`)
|
|
383
383
|
|
|
384
|
-
|
|
384
|
+
Small nodes on edges that display `edgeLabelFields`. Separate from `showEdgeHoverInfo` (hover tooltip on the edge itself).
|
|
385
385
|
|
|
386
386
|
```jsx
|
|
387
|
-
//
|
|
387
|
+
// Edge info always visible
|
|
388
388
|
<Graph_Engine NewData={data} edgeInfoNodesUserConfigurable={false} showEdgeInfoNodes />
|
|
389
389
|
|
|
390
|
-
//
|
|
390
|
+
// Edge info always hidden
|
|
391
391
|
<Graph_Engine NewData={data} edgeInfoNodesUserConfigurable={false} showEdgeInfoNodes={false} />
|
|
392
392
|
```
|
|
393
393
|
|
|
394
|
-
###
|
|
394
|
+
### Language (`language` / `languageUserConfigurable`)
|
|
395
395
|
|
|
396
|
-
|
|
396
|
+
All panel text, tooltips, and help (`?`) are shown in the selected language. Use the `GRAPH_LANGUAGE` constant for a fixed value.
|
|
397
397
|
|
|
398
398
|
```jsx
|
|
399
399
|
import { Graph_Engine, GRAPH_LANGUAGE } from "nodalix";
|
|
400
400
|
|
|
401
|
-
//
|
|
401
|
+
// English only; no language toggle
|
|
402
402
|
<Graph_Engine
|
|
403
403
|
NewData={data}
|
|
404
404
|
languageUserConfigurable={false}
|
|
405
405
|
language={GRAPH_LANGUAGE.EN}
|
|
406
406
|
/>
|
|
407
407
|
|
|
408
|
-
//
|
|
408
|
+
// Bilingual; user switches between Persian and English (default)
|
|
409
409
|
<Graph_Engine NewData={data} languageUserConfigurable language="fa" />
|
|
410
410
|
```
|
|
411
411
|
|
|
412
|
-
###
|
|
412
|
+
### Combined Example
|
|
413
413
|
|
|
414
414
|
```jsx
|
|
415
415
|
import { Graph_Engine, GRAPH_LANGUAGE } from "nodalix";
|
|
@@ -427,17 +427,17 @@ import { Graph_Engine, GRAPH_LANGUAGE } from "nodalix";
|
|
|
427
427
|
/>
|
|
428
428
|
```
|
|
429
429
|
|
|
430
|
-
|
|
430
|
+
In this example: grid always on, dragging user-toggleable, edge info nodes always hidden, UI in Persian only.
|
|
431
431
|
|
|
432
432
|
---
|
|
433
433
|
|
|
434
|
-
##
|
|
434
|
+
## Imperative APIs
|
|
435
435
|
|
|
436
|
-
|
|
436
|
+
These functions work outside the React tree after `Graph_Engine` has mounted.
|
|
437
437
|
|
|
438
438
|
### `AddNewNode(rawNode, options?)`
|
|
439
439
|
|
|
440
|
-
|
|
440
|
+
Adds a new node with validation, safe position calculation, and bidirectional `inputs`/`outputs` sync.
|
|
441
441
|
|
|
442
442
|
```js
|
|
443
443
|
import { AddNewNode, NODE_TYPE } from "nodalix";
|
|
@@ -446,131 +446,131 @@ const result = AddNewNode(
|
|
|
446
446
|
{
|
|
447
447
|
id: "node_new",
|
|
448
448
|
type: NODE_TYPE.MAIN,
|
|
449
|
-
text: "
|
|
450
|
-
label: "
|
|
449
|
+
text: "New Node",
|
|
450
|
+
label: "Branch 3",
|
|
451
451
|
entity: null,
|
|
452
452
|
rate: 25,
|
|
453
453
|
main: false,
|
|
454
454
|
metadata: null,
|
|
455
455
|
inputs: [
|
|
456
|
-
{ id: "node_a", value: 30, subText: "
|
|
456
|
+
{ id: "node_a", value: 30, subText: "item", subValue: 150, time: 1717851000 },
|
|
457
457
|
],
|
|
458
458
|
outputs: [],
|
|
459
459
|
},
|
|
460
|
-
{ minGap: 100 } //
|
|
460
|
+
{ minGap: 100 } // minimum distance from other nodes (pixels)
|
|
461
461
|
);
|
|
462
462
|
|
|
463
463
|
if (result.success) {
|
|
464
|
-
console.log(result.node); //
|
|
465
|
-
console.log(result.data); //
|
|
464
|
+
console.log(result.node); // node with computed x, y
|
|
465
|
+
console.log(result.data); // full updated array
|
|
466
466
|
} else {
|
|
467
467
|
console.error(result.error);
|
|
468
468
|
}
|
|
469
469
|
```
|
|
470
470
|
|
|
471
|
-
|
|
471
|
+
**Response:**
|
|
472
472
|
|
|
473
473
|
```ts
|
|
474
|
-
//
|
|
474
|
+
// success
|
|
475
475
|
{ success: true, node: GraphNode, data: GraphNode[], length: number }
|
|
476
476
|
|
|
477
|
-
//
|
|
477
|
+
// failure
|
|
478
478
|
{ success: false, error: string }
|
|
479
479
|
```
|
|
480
480
|
|
|
481
481
|
### `GetSelectedNode()`
|
|
482
482
|
|
|
483
|
-
|
|
483
|
+
Returns the currently selected node (or `null`).
|
|
484
484
|
|
|
485
485
|
### `SetSelectedNode(node)`
|
|
486
486
|
|
|
487
|
-
|
|
487
|
+
Sets the selected node from outside.
|
|
488
488
|
|
|
489
489
|
```js
|
|
490
|
-
SetSelectedNode(null); //
|
|
490
|
+
SetSelectedNode(null); // clear selection
|
|
491
491
|
```
|
|
492
492
|
|
|
493
493
|
### `OnNodeClick(handler)`
|
|
494
494
|
|
|
495
|
-
|
|
495
|
+
Registers a global callback for node clicks (`handler` can be `null`).
|
|
496
496
|
|
|
497
497
|
### `getSafeNodePosition(params)`
|
|
498
498
|
|
|
499
|
-
|
|
499
|
+
Computes a safe position for a new node without adding it to the graph.
|
|
500
500
|
|
|
501
501
|
```js
|
|
502
502
|
const { x, y, width } = getSafeNodePosition({
|
|
503
503
|
node: rawNode,
|
|
504
504
|
nodes: existingNodes,
|
|
505
|
-
anchorIds: ["node_a", "node_b"], //
|
|
505
|
+
anchorIds: ["node_a", "node_b"], // related nodes
|
|
506
506
|
minGap: 100,
|
|
507
507
|
});
|
|
508
508
|
```
|
|
509
509
|
|
|
510
510
|
---
|
|
511
511
|
|
|
512
|
-
##
|
|
512
|
+
## Built-in UI Tools
|
|
513
513
|
|
|
514
|
-
|
|
514
|
+
After the graph renders, the **Graph Panel** is available (top-left). Export buttons (screenshot/Excel) sit in a separate bar (top-right). The four items below can be developer-fixed or left to the user (see [UI Tools Configuration](#ui-tools-configuration-grid-drag-edges-language)):
|
|
515
515
|
|
|
516
|
-
|
|
|
517
|
-
|
|
518
|
-
|
|
|
519
|
-
|
|
|
520
|
-
|
|
|
521
|
-
|
|
|
522
|
-
|
|
|
523
|
-
|
|
|
524
|
-
|
|
|
525
|
-
|
|
|
526
|
-
|
|
|
527
|
-
|
|
|
516
|
+
| Tool | Description | Related props |
|
|
517
|
+
|------|-------------|---------------|
|
|
518
|
+
| **Language** | Persian / English | `languageUserConfigurable`, `language` |
|
|
519
|
+
| **Search** | Highlight nodes by ID or label | — |
|
|
520
|
+
| **Edge info display** | Intermediate nodes on edges | `edgeInfoNodesUserConfigurable`, `showEdgeInfoNodes` |
|
|
521
|
+
| **Grid** | Background grid | `gridUserConfigurable`, `showGrid` |
|
|
522
|
+
| **Node dragging** | Drag `main` nodes | `nodesDraggableUserConfigurable`, `nodesDraggable` |
|
|
523
|
+
| **Edge color** | Color selected edges | — |
|
|
524
|
+
| **Arrange** | Automatic node layout | — |
|
|
525
|
+
| **Screenshot** | Save full graph image (top-right export bar) | — |
|
|
526
|
+
| **Excel export** | Export to `.xlsx` (top-right export bar) | — |
|
|
527
|
+
| **Path highlight** | Directed paths between two IDs | — |
|
|
528
528
|
|
|
529
|
-
|
|
529
|
+
**Interactions:**
|
|
530
530
|
|
|
531
|
-
- **Drag**
|
|
532
|
-
- **Pan / Zoom**
|
|
533
|
-
- **Hover**
|
|
534
|
-
- **Multi-select**
|
|
531
|
+
- **Drag** `main` nodes (can be disabled with `nodesDraggable`)
|
|
532
|
+
- **Pan / Zoom** with the mouse (always enabled)
|
|
533
|
+
- **Hover** for node info tooltips; edge hover with `showEdgeHoverInfo`
|
|
534
|
+
- **Multi-select** nodes and edges
|
|
535
535
|
|
|
536
536
|
---
|
|
537
537
|
|
|
538
|
-
##
|
|
538
|
+
## Graph and Edge Logic
|
|
539
539
|
|
|
540
|
-
###
|
|
540
|
+
### Node Types
|
|
541
541
|
|
|
542
542
|
```
|
|
543
|
-
NODE_TYPE.MAIN → "main"
|
|
544
|
-
NODE_TYPE.SUB → "sub"
|
|
543
|
+
NODE_TYPE.MAIN → "main" primary node (with image/icon)
|
|
544
|
+
NODE_TYPE.SUB → "sub" intermediate node (small dot)
|
|
545
545
|
```
|
|
546
546
|
|
|
547
|
-
###
|
|
547
|
+
### Edge Construction
|
|
548
548
|
|
|
549
|
-
|
|
549
|
+
vis-network edges are built **only from nodes with `type: "main"`**:
|
|
550
550
|
|
|
551
|
-
-
|
|
552
|
-
-
|
|
551
|
+
- Each item in `outputs` → edge from this node to the target `id`
|
|
552
|
+
- Each item in `inputs` → edge from the source `id` to this node
|
|
553
553
|
|
|
554
|
-
|
|
554
|
+
`sub` nodes act as intermediaries in the topology; actual connections are defined through `inputs`/`outputs` on `main` nodes.
|
|
555
555
|
|
|
556
|
-
###
|
|
556
|
+
### Helper Nodes (automatic)
|
|
557
557
|
|
|
558
|
-
|
|
|
559
|
-
|
|
560
|
-
| `Tr..._in` / `Tr..._out` |
|
|
561
|
-
| `hotWallet` |
|
|
562
|
-
| `_Arrow` |
|
|
558
|
+
| ID suffix | Role |
|
|
559
|
+
|-----------|------|
|
|
560
|
+
| `Tr..._in` / `Tr..._out` | Edge info node (middle label) |
|
|
561
|
+
| `hotWallet` | Metadata icon |
|
|
562
|
+
| `_Arrow` | Arrow for nodes with `main: true` |
|
|
563
563
|
|
|
564
|
-
###
|
|
564
|
+
### Node Display Label
|
|
565
565
|
|
|
566
|
-
|
|
|
567
|
-
|
|
566
|
+
| Type | Label source |
|
|
567
|
+
|------|--------------|
|
|
568
568
|
| `sub` | `subText` |
|
|
569
|
-
| `main` | `label` → `entity.name` → `...` +
|
|
569
|
+
| `main` | `label` → `entity.name` → `...` + first 7 chars of `text` |
|
|
570
570
|
|
|
571
571
|
---
|
|
572
572
|
|
|
573
|
-
##
|
|
573
|
+
## Exports and Constants
|
|
574
574
|
|
|
575
575
|
```js
|
|
576
576
|
import {
|
|
@@ -581,14 +581,14 @@ import {
|
|
|
581
581
|
OnNodeClick,
|
|
582
582
|
getSafeNodePosition,
|
|
583
583
|
|
|
584
|
-
//
|
|
584
|
+
// constants
|
|
585
585
|
NODE_TYPE,
|
|
586
586
|
EDGE_LABEL_FIELDS,
|
|
587
587
|
DEFAULT_EDGE_LABEL_FIELDS,
|
|
588
588
|
DEFAULT_RATE_COLOR_RANGES,
|
|
589
589
|
GRAPH_LANGUAGE,
|
|
590
590
|
|
|
591
|
-
//
|
|
591
|
+
// helpers
|
|
592
592
|
normalizeEdgeLabelFields,
|
|
593
593
|
normalizeRateColorRanges,
|
|
594
594
|
normalizeGraphLanguage,
|
|
@@ -598,7 +598,7 @@ import {
|
|
|
598
598
|
getNodeEntityImage,
|
|
599
599
|
getGraphGuide,
|
|
600
600
|
|
|
601
|
-
// edition
|
|
601
|
+
// edition and node counting
|
|
602
602
|
NODALIX_EDITION,
|
|
603
603
|
NODALIX_MAX_NODES,
|
|
604
604
|
isBasicEdition,
|
|
@@ -609,118 +609,118 @@ import {
|
|
|
609
609
|
} from "nodalix";
|
|
610
610
|
```
|
|
611
611
|
|
|
612
|
-
|
|
612
|
+
Edition constants in the current build:
|
|
613
613
|
|
|
614
614
|
```js
|
|
615
615
|
NODALIX_EDITION; // "full"
|
|
616
|
-
NODALIX_MAX_NODES; // Infinity (
|
|
616
|
+
NODALIX_MAX_NODES; // Infinity (no node limit)
|
|
617
617
|
```
|
|
618
618
|
|
|
619
|
-
|
|
619
|
+
Language constants:
|
|
620
620
|
|
|
621
621
|
```js
|
|
622
622
|
GRAPH_LANGUAGE.FA // "fa"
|
|
623
623
|
GRAPH_LANGUAGE.EN // "en"
|
|
624
624
|
```
|
|
625
625
|
|
|
626
|
-
|
|
626
|
+
The `normalizeGraphLanguage(value)` function normalizes input to `"fa"` or `"en"`.
|
|
627
627
|
|
|
628
628
|
---
|
|
629
629
|
|
|
630
|
-
##
|
|
630
|
+
## Build and Development
|
|
631
631
|
|
|
632
632
|
```bash
|
|
633
|
-
#
|
|
633
|
+
# Install dependencies
|
|
634
634
|
npm install
|
|
635
635
|
|
|
636
|
-
#
|
|
636
|
+
# Production build (output in dist/)
|
|
637
637
|
npm run build
|
|
638
638
|
|
|
639
|
-
#
|
|
639
|
+
# Watch build
|
|
640
640
|
npm run dev
|
|
641
641
|
|
|
642
|
-
#
|
|
642
|
+
# Run tests
|
|
643
643
|
npm test
|
|
644
644
|
```
|
|
645
645
|
|
|
646
646
|
### TypeScript Support
|
|
647
647
|
|
|
648
|
-
|
|
648
|
+
The package includes type declarations:
|
|
649
649
|
|
|
650
650
|
```ts
|
|
651
651
|
import { Graph_Engine, type GraphNode, EDGE_LINE_STYLE } from "nodalix";
|
|
652
652
|
```
|
|
653
653
|
|
|
654
|
-
|
|
654
|
+
CI also runs build/test on push and pull request (see `.github/workflows/ci.yml`).
|
|
655
655
|
|
|
656
|
-
###
|
|
656
|
+
### Project Structure
|
|
657
657
|
|
|
658
658
|
```
|
|
659
659
|
nodalix/
|
|
660
660
|
├── src/
|
|
661
|
-
│ ├── index.js #
|
|
662
|
-
│ ├── edition.js #
|
|
663
|
-
│ ├── graphNodeLimits.js #
|
|
664
|
-
│ ├── graphConfig.js #
|
|
661
|
+
│ ├── index.js # entry point and public API
|
|
662
|
+
│ ├── edition.js # build edition metadata
|
|
663
|
+
│ ├── graphNodeLimits.js # node counting and limits (internal)
|
|
664
|
+
│ ├── graphConfig.js # constants and config helpers
|
|
665
665
|
│ └── Components/
|
|
666
|
-
│ ├── Graph.js #
|
|
667
|
-
│ ├── SetEdgesData.js #
|
|
668
|
-
│ ├── Options.js #
|
|
669
|
-
│ └── miladiCalendar.js #
|
|
670
|
-
├── dist/ #
|
|
666
|
+
│ ├── Graph.js # graph engine and UI
|
|
667
|
+
│ ├── SetEdgesData.js # build edges from inputs/outputs
|
|
668
|
+
│ ├── Options.js # vis-network options
|
|
669
|
+
│ └── miladiCalendar.js # timestamp to date conversion
|
|
670
|
+
├── dist/ # build output
|
|
671
671
|
├── package.json
|
|
672
672
|
└── tsup.config.js
|
|
673
673
|
```
|
|
674
674
|
|
|
675
|
-
|
|
675
|
+
Only one package is published: **nodalix** (full edition, no node limit).
|
|
676
676
|
|
|
677
677
|
```bash
|
|
678
|
-
npm run build #
|
|
678
|
+
npm run build # output in dist/
|
|
679
679
|
```
|
|
680
680
|
|
|
681
681
|
---
|
|
682
682
|
|
|
683
|
-
###
|
|
683
|
+
### Test Project
|
|
684
684
|
|
|
685
|
-
|
|
685
|
+
The `nodalix-test` folder (sibling directory) is a Next.js sample app showing how to use the library, including UI tool configuration (`gridUserConfigurable`, `nodesDraggable`, `showEdgeInfoNodes`, `language`, etc.).
|
|
686
686
|
|
|
687
687
|
---
|
|
688
688
|
|
|
689
|
-
##
|
|
689
|
+
## Important Notes
|
|
690
690
|
|
|
691
|
-
###
|
|
691
|
+
### Images
|
|
692
692
|
|
|
693
|
-
|
|
693
|
+
`main` nodes use the following paths. These files must exist in the consuming project's `public/` folder:
|
|
694
694
|
|
|
695
695
|
```
|
|
696
|
-
/images/location.png —
|
|
697
|
-
/images/fire.png —
|
|
696
|
+
/images/location.png — default node image
|
|
697
|
+
/images/fire.png — metadata icon
|
|
698
698
|
```
|
|
699
699
|
|
|
700
|
-
|
|
700
|
+
Or set `entity.image` / `entity.metadata.image` in your data.
|
|
701
701
|
|
|
702
702
|
### Client Component
|
|
703
703
|
|
|
704
|
-
`Graph_Engine`
|
|
704
|
+
`Graph_Engine` is marked with `"use client"`. In the Next.js App Router, always import it inside a client component.
|
|
705
705
|
|
|
706
|
-
###
|
|
706
|
+
### State Synchronization
|
|
707
707
|
|
|
708
|
-
- `NewData`
|
|
709
|
-
-
|
|
710
|
-
-
|
|
708
|
+
- `NewData` syncs only on mount and when the prop changes.
|
|
709
|
+
- Use `AddNewNode` to add nodes at runtime (it updates internal state itself).
|
|
710
|
+
- If you change `NewData` from the parent, internal state is overwritten.
|
|
711
711
|
|
|
712
|
-
###
|
|
712
|
+
### Dark Theme
|
|
713
713
|
|
|
714
|
-
|
|
714
|
+
If `<html>` has the `dark` class, the graph automatically uses the dark theme.
|
|
715
715
|
|
|
716
|
-
###
|
|
716
|
+
### Limitations
|
|
717
717
|
|
|
718
|
-
-
|
|
719
|
-
- `AddNewNode`
|
|
720
|
-
-
|
|
718
|
+
- Graph physics is always off (deterministic layout).
|
|
719
|
+
- `AddNewNode` and `GetSelectedNode` only work when `Graph_Engine` is mounted.
|
|
720
|
+
- For very large graphs (thousands of nodes), Auto Arrange may take several seconds.
|
|
721
721
|
|
|
722
722
|
---
|
|
723
723
|
|
|
724
|
-
##
|
|
724
|
+
## License
|
|
725
725
|
|
|
726
726
|
MIT
|
package/dist/index.js
CHANGED
|
@@ -658,9 +658,6 @@ function getGraphGuide(isFa) {
|
|
|
658
658
|
};
|
|
659
659
|
}
|
|
660
660
|
|
|
661
|
-
// src/branding.js
|
|
662
|
-
var FOOTER_TEXT = "powered by nodalix";
|
|
663
|
-
|
|
664
661
|
// src/edition.js
|
|
665
662
|
var NODALIX_EDITION = "full";
|
|
666
663
|
var NODALIX_MAX_NODES = Infinity;
|
|
@@ -893,7 +890,7 @@ var Nodalix_graph_engine = ({
|
|
|
893
890
|
summary: ""
|
|
894
891
|
});
|
|
895
892
|
const [showGuide, setShowGuide] = (0, import_react2.useState)(false);
|
|
896
|
-
const [panelOpen, setPanelOpen] = (0, import_react2.useState)(
|
|
893
|
+
const [panelOpen, setPanelOpen] = (0, import_react2.useState)(false);
|
|
897
894
|
const showEdgeHoverInfoRef = (0, import_react2.useRef)(!!showEdgeHoverInfo);
|
|
898
895
|
const edgeLabelFieldsRef = (0, import_react2.useRef)(resolvedEdgeLabelFields);
|
|
899
896
|
const containerRef = (0, import_react2.useRef)(null);
|
|
@@ -3469,29 +3466,6 @@ var Nodalix_graph_engine = ({
|
|
|
3469
3466
|
)))
|
|
3470
3467
|
)
|
|
3471
3468
|
) : null,
|
|
3472
|
-
/* @__PURE__ */ import_react2.default.createElement(
|
|
3473
|
-
"div",
|
|
3474
|
-
{
|
|
3475
|
-
style: {
|
|
3476
|
-
position: "absolute",
|
|
3477
|
-
left: "50%",
|
|
3478
|
-
bottom: 8,
|
|
3479
|
-
transform: "translateX(-50%)",
|
|
3480
|
-
zIndex: 99990,
|
|
3481
|
-
pointerEvents: "none",
|
|
3482
|
-
fontSize: 11,
|
|
3483
|
-
fontWeight: 700,
|
|
3484
|
-
letterSpacing: 0.4,
|
|
3485
|
-
color: isDarkMode ? "rgba(148,163,184,.95)" : "rgba(15,23,42,.75)",
|
|
3486
|
-
background: isDarkMode ? "rgba(2,6,23,.45)" : "rgba(255,255,255,.72)",
|
|
3487
|
-
border: `1px solid ${isDarkMode ? "rgba(71,85,105,.45)" : "rgba(148,163,184,.45)"}`,
|
|
3488
|
-
borderRadius: 999,
|
|
3489
|
-
padding: "4px 10px",
|
|
3490
|
-
backdropFilter: "blur(4px)"
|
|
3491
|
-
}
|
|
3492
|
-
},
|
|
3493
|
-
FOOTER_TEXT
|
|
3494
|
-
),
|
|
3495
3469
|
hoverInfo.visible && hoverInfo.node && /* @__PURE__ */ import_react2.default.createElement(
|
|
3496
3470
|
"div",
|
|
3497
3471
|
{
|
package/dist/index.mjs
CHANGED
|
@@ -594,9 +594,6 @@ function getGraphGuide(isFa) {
|
|
|
594
594
|
};
|
|
595
595
|
}
|
|
596
596
|
|
|
597
|
-
// src/branding.js
|
|
598
|
-
var FOOTER_TEXT = "powered by nodalix";
|
|
599
|
-
|
|
600
597
|
// src/edition.js
|
|
601
598
|
var NODALIX_EDITION = "full";
|
|
602
599
|
var NODALIX_MAX_NODES = Infinity;
|
|
@@ -829,7 +826,7 @@ var Nodalix_graph_engine = ({
|
|
|
829
826
|
summary: ""
|
|
830
827
|
});
|
|
831
828
|
const [showGuide, setShowGuide] = useState(false);
|
|
832
|
-
const [panelOpen, setPanelOpen] = useState(
|
|
829
|
+
const [panelOpen, setPanelOpen] = useState(false);
|
|
833
830
|
const showEdgeHoverInfoRef = useRef(!!showEdgeHoverInfo);
|
|
834
831
|
const edgeLabelFieldsRef = useRef(resolvedEdgeLabelFields);
|
|
835
832
|
const containerRef = useRef(null);
|
|
@@ -3405,29 +3402,6 @@ var Nodalix_graph_engine = ({
|
|
|
3405
3402
|
)))
|
|
3406
3403
|
)
|
|
3407
3404
|
) : null,
|
|
3408
|
-
/* @__PURE__ */ React2.createElement(
|
|
3409
|
-
"div",
|
|
3410
|
-
{
|
|
3411
|
-
style: {
|
|
3412
|
-
position: "absolute",
|
|
3413
|
-
left: "50%",
|
|
3414
|
-
bottom: 8,
|
|
3415
|
-
transform: "translateX(-50%)",
|
|
3416
|
-
zIndex: 99990,
|
|
3417
|
-
pointerEvents: "none",
|
|
3418
|
-
fontSize: 11,
|
|
3419
|
-
fontWeight: 700,
|
|
3420
|
-
letterSpacing: 0.4,
|
|
3421
|
-
color: isDarkMode ? "rgba(148,163,184,.95)" : "rgba(15,23,42,.75)",
|
|
3422
|
-
background: isDarkMode ? "rgba(2,6,23,.45)" : "rgba(255,255,255,.72)",
|
|
3423
|
-
border: `1px solid ${isDarkMode ? "rgba(71,85,105,.45)" : "rgba(148,163,184,.45)"}`,
|
|
3424
|
-
borderRadius: 999,
|
|
3425
|
-
padding: "4px 10px",
|
|
3426
|
-
backdropFilter: "blur(4px)"
|
|
3427
|
-
}
|
|
3428
|
-
},
|
|
3429
|
-
FOOTER_TEXT
|
|
3430
|
-
),
|
|
3431
3405
|
hoverInfo.visible && hoverInfo.node && /* @__PURE__ */ React2.createElement(
|
|
3432
3406
|
"div",
|
|
3433
3407
|
{
|