@krainovsd/graph 0.7.0 → 0.8.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/lib/cjs/index.cjs +945 -165
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/esm/index.js +3 -0
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/lib/draw-time.js +25 -0
- package/lib/esm/lib/draw-time.js.map +1 -0
- package/lib/esm/lib/get-controls-info.js +541 -0
- package/lib/esm/lib/get-controls-info.js.map +1 -0
- package/lib/esm/module/GraphCanvas/GraphCanvas.js +218 -67
- package/lib/esm/module/GraphCanvas/GraphCanvas.js.map +1 -1
- package/lib/esm/module/GraphCanvas/constants/settings.js +26 -7
- package/lib/esm/module/GraphCanvas/constants/settings.js.map +1 -1
- package/lib/esm/module/GraphCanvas/lib/settings/link-settings-getter.js +7 -4
- package/lib/esm/module/GraphCanvas/lib/settings/link-settings-getter.js.map +1 -1
- package/lib/esm/module/GraphCanvas/lib/settings/node-settings-getter.js +6 -5
- package/lib/esm/module/GraphCanvas/lib/settings/node-settings-getter.js.map +1 -1
- package/lib/esm/module/GraphCanvas/lib/utils/animation-by-progress.js +12 -0
- package/lib/esm/module/GraphCanvas/lib/utils/animation-by-progress.js.map +1 -0
- package/lib/esm/module/GraphCanvas/lib/utils/calculate-link-position-by-radius.js +2 -2
- package/lib/esm/module/GraphCanvas/lib/utils/calculate-link-position-by-radius.js.map +1 -1
- package/lib/esm/module/GraphCanvas/lib/utils/get-particle-position.js +24 -0
- package/lib/esm/module/GraphCanvas/lib/utils/get-particle-position.js.map +1 -0
- package/lib/esm/module/GraphCanvas/lib/utils/is-node-visible.js +14 -0
- package/lib/esm/module/GraphCanvas/lib/utils/is-node-visible.js.map +1 -0
- package/lib/esm/module/GraphCanvas/lib/utils/link-iteration-extractor.js +1 -0
- package/lib/esm/module/GraphCanvas/lib/utils/link-iteration-extractor.js.map +1 -1
- package/lib/esm/module/GraphCanvas/lib/utils/node-iteration-extractor.js +1 -0
- package/lib/esm/module/GraphCanvas/lib/utils/node-iteration-extractor.js.map +1 -1
- package/lib/index.d.ts +72 -3
- package/package.json +4 -2
package/lib/cjs/index.cjs
CHANGED
|
@@ -87,95 +87,6 @@ function rgbAnimationByProgress(start, end, progress) {
|
|
|
87
87
|
};
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
const FORCE_SETTINGS = {
|
|
91
|
-
centerPosition: {},
|
|
92
|
-
centerStrength: 1,
|
|
93
|
-
collideStrength: 0.1,
|
|
94
|
-
collideAdditionalRadius: 4,
|
|
95
|
-
collideIterations: 2,
|
|
96
|
-
collideOffMax: { links: 0, nodes: 0 },
|
|
97
|
-
collideOn: true,
|
|
98
|
-
chargeStrength: -40,
|
|
99
|
-
chargeDistanceMax: Infinity,
|
|
100
|
-
chargeDistanceMin: 1,
|
|
101
|
-
xForce: 0,
|
|
102
|
-
xStrength: 0.1,
|
|
103
|
-
yForce: 0,
|
|
104
|
-
yStrength: 0.1,
|
|
105
|
-
linkDistance: 30,
|
|
106
|
-
linkIterations: 1,
|
|
107
|
-
linkStrength: 1,
|
|
108
|
-
collideRadius: null,
|
|
109
|
-
};
|
|
110
|
-
const GRAPH_SETTINGS = {
|
|
111
|
-
zoomExtent: [0.1, 20],
|
|
112
|
-
translateExtent: [[], []],
|
|
113
|
-
translateExtentEnable: true,
|
|
114
|
-
translateExtentCoefficient: [1.2, 1.1],
|
|
115
|
-
highlightSizingAdditional: 0.5,
|
|
116
|
-
highlightColorFadingMin: 0.15,
|
|
117
|
-
highlightTextShiftXAdditional: 0,
|
|
118
|
-
highlightTextShiftYAdditional: 2,
|
|
119
|
-
highlightTextSizingAdditional: 1,
|
|
120
|
-
highlightTextWeightAdditional: 0,
|
|
121
|
-
highlightTextWidthAdditional: 10,
|
|
122
|
-
highlightOnlyRoot: true,
|
|
123
|
-
stickAfterDrag: false,
|
|
124
|
-
highlightByHover: false,
|
|
125
|
-
highlightLinkFadingMin: 0.21,
|
|
126
|
-
highlightFadingMin: 0.21,
|
|
127
|
-
highlightTextFadingMin: 0.21,
|
|
128
|
-
highlightDownStep: 0.2,
|
|
129
|
-
highlightUpStep: 0.2,
|
|
130
|
-
dragPlaceCoefficient: dragPlaceCoefficientGetter,
|
|
131
|
-
nodeRadiusInitial: 4,
|
|
132
|
-
nodeRadiusCoefficient: 5,
|
|
133
|
-
nodeRadiusFactor: 1,
|
|
134
|
-
nodeRadiusFlexible: true,
|
|
135
|
-
zoomInitial: null,
|
|
136
|
-
};
|
|
137
|
-
const NODE_SETTINGS = {
|
|
138
|
-
alpha: 1,
|
|
139
|
-
textAlpha: 1,
|
|
140
|
-
borderColor: "#000000FF",
|
|
141
|
-
borderWidth: 0.1,
|
|
142
|
-
textWidth: 20,
|
|
143
|
-
textShiftX: 0,
|
|
144
|
-
textFont: "Arial",
|
|
145
|
-
textAlign: "center",
|
|
146
|
-
textColor: "#333",
|
|
147
|
-
width: 1,
|
|
148
|
-
radius: 4,
|
|
149
|
-
textStyle: "normal",
|
|
150
|
-
textWeight: 500,
|
|
151
|
-
textGap: 1,
|
|
152
|
-
highlightFading: false,
|
|
153
|
-
highlightColor: true,
|
|
154
|
-
highlightSizing: true,
|
|
155
|
-
highlightTextFading: true,
|
|
156
|
-
highlightTextSizing: true,
|
|
157
|
-
};
|
|
158
|
-
const LINK_SETTINGS = {
|
|
159
|
-
alpha: 1,
|
|
160
|
-
highlightFading: true,
|
|
161
|
-
pretty: true,
|
|
162
|
-
};
|
|
163
|
-
const COMMON_SETTINGS = {
|
|
164
|
-
linkColorZoomFar: "#999",
|
|
165
|
-
linkColorZoomNear: "#000000FF",
|
|
166
|
-
linkWidthZoomFar: 1,
|
|
167
|
-
linkWidthZoomNear: 0.1,
|
|
168
|
-
linkWidthZoomBorder: 1,
|
|
169
|
-
linkColorZoomBorder: 1,
|
|
170
|
-
nodeTextScaleMin: 1.5,
|
|
171
|
-
nodeTextScaleMax: 20,
|
|
172
|
-
nodeTextSizeMin: 1.5,
|
|
173
|
-
nodeTextSizeMax: 3.5,
|
|
174
|
-
nodeTextShiftYMin: 2.5,
|
|
175
|
-
nodeTextShiftYMax: 4,
|
|
176
|
-
nodeTextChangeStepCount: 200,
|
|
177
|
-
};
|
|
178
|
-
|
|
179
90
|
function forceSettingsGetter(settings, prevSettings) {
|
|
180
91
|
return {
|
|
181
92
|
...(prevSettings ?? FORCE_SETTINGS),
|
|
@@ -190,17 +101,20 @@ function graphSettingsGetter(settings, prevSettings) {
|
|
|
190
101
|
};
|
|
191
102
|
}
|
|
192
103
|
|
|
193
|
-
function linkSettingsGetter(settings) {
|
|
194
|
-
return {
|
|
104
|
+
function linkSettingsGetter(settings, prevSettings) {
|
|
105
|
+
return { ...(prevSettings ?? LINK_SETTINGS), ...settings };
|
|
195
106
|
}
|
|
196
107
|
function linkOptionsGetter(_, __, ___, state) {
|
|
197
108
|
return {
|
|
198
|
-
...
|
|
109
|
+
...LINK_OPTIONS,
|
|
199
110
|
drawExtraLink: null,
|
|
200
111
|
drawLink: null,
|
|
201
112
|
color: state?.areaTransform && state?.areaTransform.k > COMMON_SETTINGS.linkColorZoomBorder
|
|
202
113
|
? COMMON_SETTINGS.linkColorZoomNear
|
|
203
114
|
: COMMON_SETTINGS.linkColorZoomFar,
|
|
115
|
+
arrowColor: state?.areaTransform && state?.areaTransform.k > COMMON_SETTINGS.linkColorZoomBorder
|
|
116
|
+
? COMMON_SETTINGS.linkColorZoomNear
|
|
117
|
+
: COMMON_SETTINGS.linkColorZoomFar,
|
|
204
118
|
width: state?.areaTransform && state?.areaTransform.k > COMMON_SETTINGS.linkWidthZoomBorder
|
|
205
119
|
? COMMON_SETTINGS.linkWidthZoomNear
|
|
206
120
|
: COMMON_SETTINGS.linkWidthZoomFar,
|
|
@@ -211,17 +125,18 @@ function listenersGetter(settings) {
|
|
|
211
125
|
return settings ?? {};
|
|
212
126
|
}
|
|
213
127
|
|
|
214
|
-
function nodeSettingsGetter(settings) {
|
|
128
|
+
function nodeSettingsGetter(settings, prevNodeSettings) {
|
|
215
129
|
return {
|
|
216
|
-
|
|
217
|
-
|
|
130
|
+
...(prevNodeSettings ?? NODE_SETTINGS),
|
|
131
|
+
idGetter: nodeIdGetter,
|
|
132
|
+
...settings,
|
|
218
133
|
};
|
|
219
134
|
}
|
|
220
135
|
const color = colorGetter();
|
|
221
136
|
function nodeOptionsGetter(node, _, __, state) {
|
|
222
137
|
const { textShiftY, textSize } = nodeTextSizeGetter(state?.areaTransform);
|
|
223
138
|
return {
|
|
224
|
-
...
|
|
139
|
+
...NODE_OPTIONS,
|
|
225
140
|
nodeDraw: null,
|
|
226
141
|
nodeExtraDraw: null,
|
|
227
142
|
textDraw: null,
|
|
@@ -410,7 +325,7 @@ function drawText({ context, id, textAlign, textColor, textFont, textStyle, text
|
|
|
410
325
|
});
|
|
411
326
|
}
|
|
412
327
|
|
|
413
|
-
function calculateLinkPositionByRadius(link) {
|
|
328
|
+
function calculateLinkPositionByRadius(link, arrowSize = 0) {
|
|
414
329
|
const source = link.source;
|
|
415
330
|
const target = link.target;
|
|
416
331
|
if (typeof source != "object" || typeof target != "object")
|
|
@@ -419,7 +334,7 @@ function calculateLinkPositionByRadius(link) {
|
|
|
419
334
|
const dy = (target.y ?? 0) - (source.y ?? 0);
|
|
420
335
|
const dr = Math.sqrt(dx * dx + dy * dy);
|
|
421
336
|
const sourceRadius = source._radius ?? 0;
|
|
422
|
-
const targetRadius = target._radius ?? 0;
|
|
337
|
+
const targetRadius = (target._radius ?? 0) + (arrowSize > 0 ? arrowSize * 0.85 : 0);
|
|
423
338
|
return {
|
|
424
339
|
x1: (source.x ?? 0) + (dx * sourceRadius) / dr,
|
|
425
340
|
y1: (source.y ?? 0) + (dy * sourceRadius) / dr,
|
|
@@ -428,10 +343,723 @@ function calculateLinkPositionByRadius(link) {
|
|
|
428
343
|
};
|
|
429
344
|
}
|
|
430
345
|
|
|
346
|
+
function animationByProgress(initial, additional, progress) {
|
|
347
|
+
const max = initial + additional;
|
|
348
|
+
let current = initial + (max - initial) * progress;
|
|
349
|
+
if (current > max)
|
|
350
|
+
current = max;
|
|
351
|
+
if (current < initial)
|
|
352
|
+
current = initial;
|
|
353
|
+
return current;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
const ADDITIONAL_VIEWPORT = 10;
|
|
357
|
+
function isNodeVisible(opts) {
|
|
358
|
+
const left = -opts.transform.x / opts.transform.k;
|
|
359
|
+
const right = (opts.width - opts.transform.x) / opts.transform.k;
|
|
360
|
+
const top = -opts.transform.y / opts.transform.k;
|
|
361
|
+
const bottom = (opts.height - opts.transform.y) / opts.transform.k;
|
|
362
|
+
return (left < opts.x + opts.radius + ADDITIONAL_VIEWPORT &&
|
|
363
|
+
opts.x - opts.radius - ADDITIONAL_VIEWPORT < right &&
|
|
364
|
+
top < opts.y + opts.radius + ADDITIONAL_VIEWPORT &&
|
|
365
|
+
opts.y - opts.radius - ADDITIONAL_VIEWPORT < bottom);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
function getParticlePosition(opts) {
|
|
369
|
+
if (opts.particle.wait > 0) {
|
|
370
|
+
opts.particle.wait--;
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
const remainingSteps = opts.totalSteps - opts.particle.step;
|
|
374
|
+
const progress = opts.particle.step / opts.totalSteps;
|
|
375
|
+
if (remainingSteps === 0) {
|
|
376
|
+
opts.particle.x = opts.xEnd;
|
|
377
|
+
opts.particle.y = opts.yEnd;
|
|
378
|
+
opts.particle.step = 0;
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
const dx = opts.xEnd - opts.xStart;
|
|
382
|
+
const dy = opts.yEnd - opts.yStart;
|
|
383
|
+
const newX = opts.xStart + dx * progress;
|
|
384
|
+
const newY = opts.yStart + dy * progress;
|
|
385
|
+
opts.particle.x = newX;
|
|
386
|
+
opts.particle.y = newY;
|
|
387
|
+
opts.particle.step++;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
const FORCE_SETTINGS = {
|
|
391
|
+
centerPosition: {},
|
|
392
|
+
centerStrength: 1,
|
|
393
|
+
collideStrength: 0.1,
|
|
394
|
+
collideAdditionalRadius: 4,
|
|
395
|
+
collideIterations: 2,
|
|
396
|
+
collideOffMax: { links: 0, nodes: 0 },
|
|
397
|
+
collideOn: true,
|
|
398
|
+
chargeStrength: -40,
|
|
399
|
+
chargeDistanceMax: Infinity,
|
|
400
|
+
chargeDistanceMin: 1,
|
|
401
|
+
xForce: 0,
|
|
402
|
+
xStrength: 0.1,
|
|
403
|
+
yForce: 0,
|
|
404
|
+
yStrength: 0.1,
|
|
405
|
+
linkDistance: 30,
|
|
406
|
+
linkIterations: 1,
|
|
407
|
+
linkStrength: 1,
|
|
408
|
+
collideRadius: null,
|
|
409
|
+
};
|
|
410
|
+
const GRAPH_SETTINGS = {
|
|
411
|
+
zoomExtent: [0.3, 10],
|
|
412
|
+
translateExtent: [[], []],
|
|
413
|
+
translateExtentEnable: true,
|
|
414
|
+
translateExtentCoefficient: [3, 3],
|
|
415
|
+
highlightSizingAdditional: 0.5,
|
|
416
|
+
highlightColorFadingMin: 0.15,
|
|
417
|
+
highlightTextShiftXAdditional: 0,
|
|
418
|
+
highlightTextShiftYAdditional: 2,
|
|
419
|
+
highlightTextSizingAdditional: 1,
|
|
420
|
+
highlightTextWeightAdditional: 0,
|
|
421
|
+
highlightTextWidthAdditional: 10,
|
|
422
|
+
highlightOnlyRoot: true,
|
|
423
|
+
stickAfterDrag: false,
|
|
424
|
+
highlightByHover: true,
|
|
425
|
+
highlightLinkFadingMin: 0.21,
|
|
426
|
+
highlightFadingMin: 0.21,
|
|
427
|
+
highlightTextFadingMin: 0.21,
|
|
428
|
+
highlightArrowFadingMin: 0.21,
|
|
429
|
+
highlightDownStep: 0.2,
|
|
430
|
+
highlightUpStep: 0.2,
|
|
431
|
+
dragPlaceCoefficient: dragPlaceCoefficientGetter,
|
|
432
|
+
nodeRadiusInitial: 4,
|
|
433
|
+
nodeRadiusCoefficient: 5,
|
|
434
|
+
nodeRadiusFactor: 1,
|
|
435
|
+
nodeRadiusFlexible: true,
|
|
436
|
+
zoomInitial: null,
|
|
437
|
+
showDrawTime: true,
|
|
438
|
+
showDrawTimeEveryTick: false,
|
|
439
|
+
};
|
|
440
|
+
const NODE_SETTINGS = {
|
|
441
|
+
cache: false,
|
|
442
|
+
};
|
|
443
|
+
const NODE_OPTIONS = {
|
|
444
|
+
alpha: 1,
|
|
445
|
+
textAlpha: 1,
|
|
446
|
+
borderColor: "#000000FF",
|
|
447
|
+
borderWidth: 0.1,
|
|
448
|
+
textWidth: 20,
|
|
449
|
+
textShiftX: 0,
|
|
450
|
+
textFont: "Arial",
|
|
451
|
+
textAlign: "center",
|
|
452
|
+
textColor: "#333",
|
|
453
|
+
radius: 4,
|
|
454
|
+
textStyle: "normal",
|
|
455
|
+
textWeight: 500,
|
|
456
|
+
textGap: 1,
|
|
457
|
+
highlightFading: true,
|
|
458
|
+
highlightColor: false,
|
|
459
|
+
highlightSizing: true,
|
|
460
|
+
highlightTextFading: true,
|
|
461
|
+
highlightTextSizing: true,
|
|
462
|
+
};
|
|
463
|
+
const LINK_SETTINGS = {
|
|
464
|
+
cache: false,
|
|
465
|
+
particles: true,
|
|
466
|
+
};
|
|
467
|
+
const LINK_OPTIONS = {
|
|
468
|
+
alpha: 1,
|
|
469
|
+
highlightFading: true,
|
|
470
|
+
pretty: true,
|
|
471
|
+
arrow: true,
|
|
472
|
+
arrowAlpha: 1,
|
|
473
|
+
arrowSize: 2,
|
|
474
|
+
arrowHighlightFading: true,
|
|
475
|
+
arrowReverseAppear: true,
|
|
476
|
+
particleAlpha: 1,
|
|
477
|
+
particleColor: "#000000FF",
|
|
478
|
+
particleCount: 2,
|
|
479
|
+
particleRadius: 0.5,
|
|
480
|
+
particleSteps: 60,
|
|
481
|
+
};
|
|
482
|
+
const COMMON_SETTINGS = {
|
|
483
|
+
linkColorZoomFar: "#999",
|
|
484
|
+
linkColorZoomNear: "#000000FF",
|
|
485
|
+
linkWidthZoomFar: 1,
|
|
486
|
+
linkWidthZoomNear: 0.1,
|
|
487
|
+
linkWidthZoomBorder: 1,
|
|
488
|
+
linkColorZoomBorder: 1,
|
|
489
|
+
nodeTextScaleMin: 1.5,
|
|
490
|
+
nodeTextScaleMax: 20,
|
|
491
|
+
nodeTextSizeMin: 1.5,
|
|
492
|
+
nodeTextSizeMax: 3.5,
|
|
493
|
+
nodeTextShiftYMin: 2.5,
|
|
494
|
+
nodeTextShiftYMax: 4,
|
|
495
|
+
nodeTextChangeStepCount: 200,
|
|
496
|
+
};
|
|
497
|
+
|
|
498
|
+
function getForceControls(keys) {
|
|
499
|
+
const FORCE_CONTROLS = [
|
|
500
|
+
{
|
|
501
|
+
id: "centerStrength",
|
|
502
|
+
initialValue: FORCE_SETTINGS.centerStrength,
|
|
503
|
+
label: "Граница центра",
|
|
504
|
+
max: 1,
|
|
505
|
+
min: 0,
|
|
506
|
+
step: 0.01,
|
|
507
|
+
type: "range",
|
|
508
|
+
},
|
|
509
|
+
{
|
|
510
|
+
id: "collideStrength",
|
|
511
|
+
initialValue: FORCE_SETTINGS.collideStrength,
|
|
512
|
+
label: "Сила отталкивания",
|
|
513
|
+
max: 1,
|
|
514
|
+
min: 0,
|
|
515
|
+
step: 0.01,
|
|
516
|
+
type: "range",
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
id: "collideAdditionalRadius",
|
|
520
|
+
initialValue: FORCE_SETTINGS.collideAdditionalRadius,
|
|
521
|
+
label: "Радиус отталкивания",
|
|
522
|
+
max: 300,
|
|
523
|
+
min: 0,
|
|
524
|
+
step: 0.1,
|
|
525
|
+
type: "range",
|
|
526
|
+
},
|
|
527
|
+
{
|
|
528
|
+
id: "collideIterations",
|
|
529
|
+
initialValue: FORCE_SETTINGS.collideIterations,
|
|
530
|
+
label: "Итерации отталкивания",
|
|
531
|
+
max: 10,
|
|
532
|
+
min: 0,
|
|
533
|
+
step: 1,
|
|
534
|
+
type: "range",
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
id: "chargeStrength",
|
|
538
|
+
initialValue: FORCE_SETTINGS.chargeStrength ,
|
|
539
|
+
label: "Гравитация",
|
|
540
|
+
max: 0,
|
|
541
|
+
min: -300,
|
|
542
|
+
step: 0.1,
|
|
543
|
+
type: "range",
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
type: "range",
|
|
547
|
+
id: "xForce",
|
|
548
|
+
min: 0,
|
|
549
|
+
max: 1,
|
|
550
|
+
step: 0.01,
|
|
551
|
+
label: "Граница X",
|
|
552
|
+
initialValue: FORCE_SETTINGS.xForce ,
|
|
553
|
+
},
|
|
554
|
+
{
|
|
555
|
+
type: "range",
|
|
556
|
+
id: "yForce",
|
|
557
|
+
min: 0,
|
|
558
|
+
max: 1,
|
|
559
|
+
step: 0.01,
|
|
560
|
+
label: "Граница Y",
|
|
561
|
+
initialValue: FORCE_SETTINGS.yForce ,
|
|
562
|
+
},
|
|
563
|
+
{
|
|
564
|
+
type: "range",
|
|
565
|
+
id: "xStrength",
|
|
566
|
+
min: 0,
|
|
567
|
+
max: 1,
|
|
568
|
+
step: 0.01,
|
|
569
|
+
label: "Гравитация X",
|
|
570
|
+
initialValue: FORCE_SETTINGS.xStrength ,
|
|
571
|
+
},
|
|
572
|
+
{
|
|
573
|
+
type: "range",
|
|
574
|
+
id: "yStrength",
|
|
575
|
+
min: 0,
|
|
576
|
+
max: 1,
|
|
577
|
+
step: 0.01,
|
|
578
|
+
label: "Гравитация Y",
|
|
579
|
+
initialValue: FORCE_SETTINGS.yStrength ,
|
|
580
|
+
},
|
|
581
|
+
{
|
|
582
|
+
type: "range",
|
|
583
|
+
id: "linkStrength",
|
|
584
|
+
min: 0,
|
|
585
|
+
max: 1,
|
|
586
|
+
step: 0.01,
|
|
587
|
+
label: "Натяжение связей",
|
|
588
|
+
initialValue: FORCE_SETTINGS.linkStrength ,
|
|
589
|
+
},
|
|
590
|
+
{
|
|
591
|
+
type: "range",
|
|
592
|
+
id: "linkDistance",
|
|
593
|
+
min: 0,
|
|
594
|
+
max: 300,
|
|
595
|
+
step: 0.1,
|
|
596
|
+
label: "Расстояние связей",
|
|
597
|
+
initialValue: FORCE_SETTINGS.linkDistance ,
|
|
598
|
+
},
|
|
599
|
+
{
|
|
600
|
+
id: "collideOn",
|
|
601
|
+
type: "checkbox",
|
|
602
|
+
initialValue: FORCE_SETTINGS.collideOn,
|
|
603
|
+
label: "Отталкивание",
|
|
604
|
+
},
|
|
605
|
+
];
|
|
606
|
+
return keys ? FORCE_CONTROLS.filter((control) => keys.includes(control.id)) : FORCE_CONTROLS;
|
|
607
|
+
}
|
|
608
|
+
function getGraphControls(keys) {
|
|
609
|
+
const GRAPH_CONTROLS = [
|
|
610
|
+
{
|
|
611
|
+
id: "highlightSizingAdditional",
|
|
612
|
+
initialValue: GRAPH_SETTINGS.highlightSizingAdditional,
|
|
613
|
+
max: 10,
|
|
614
|
+
min: 0.1,
|
|
615
|
+
step: 0.01,
|
|
616
|
+
type: "range",
|
|
617
|
+
label: "Дополнительный размер при анимации",
|
|
618
|
+
},
|
|
619
|
+
{
|
|
620
|
+
id: "highlightColorFadingMin",
|
|
621
|
+
initialValue: GRAPH_SETTINGS.highlightColorFadingMin,
|
|
622
|
+
max: 1,
|
|
623
|
+
min: 0.01,
|
|
624
|
+
step: 0.01,
|
|
625
|
+
type: "range",
|
|
626
|
+
label: "Граница затухания цвета",
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
id: "highlightTextShiftXAdditional",
|
|
630
|
+
initialValue: GRAPH_SETTINGS.highlightTextShiftXAdditional,
|
|
631
|
+
max: 50,
|
|
632
|
+
min: 0,
|
|
633
|
+
step: 0.1,
|
|
634
|
+
type: "range",
|
|
635
|
+
label: "Смещение текста по X при анимации",
|
|
636
|
+
},
|
|
637
|
+
{
|
|
638
|
+
id: "highlightTextShiftYAdditional",
|
|
639
|
+
initialValue: GRAPH_SETTINGS.highlightTextShiftYAdditional,
|
|
640
|
+
max: 50,
|
|
641
|
+
min: 0,
|
|
642
|
+
step: 0.1,
|
|
643
|
+
type: "range",
|
|
644
|
+
label: "Смещение текста по Y при анимации",
|
|
645
|
+
},
|
|
646
|
+
{
|
|
647
|
+
id: "highlightTextSizingAdditional",
|
|
648
|
+
initialValue: GRAPH_SETTINGS.highlightTextSizingAdditional,
|
|
649
|
+
max: 10,
|
|
650
|
+
min: 0.1,
|
|
651
|
+
step: 0.1,
|
|
652
|
+
type: "range",
|
|
653
|
+
label: "Увеличение текста при анимации",
|
|
654
|
+
},
|
|
655
|
+
{
|
|
656
|
+
id: "highlightTextWeightAdditional",
|
|
657
|
+
initialValue: GRAPH_SETTINGS.highlightTextWeightAdditional,
|
|
658
|
+
max: 1000,
|
|
659
|
+
min: 0,
|
|
660
|
+
step: 100,
|
|
661
|
+
type: "range",
|
|
662
|
+
label: "Увеличение жирности текста при анимации",
|
|
663
|
+
},
|
|
664
|
+
{
|
|
665
|
+
id: "highlightTextWidthAdditional",
|
|
666
|
+
initialValue: GRAPH_SETTINGS.highlightTextWidthAdditional,
|
|
667
|
+
max: 100,
|
|
668
|
+
min: 0,
|
|
669
|
+
step: 0.1,
|
|
670
|
+
type: "range",
|
|
671
|
+
label: "Увеличение ширины текста при анимации",
|
|
672
|
+
},
|
|
673
|
+
{
|
|
674
|
+
id: "highlightTextFadingMin",
|
|
675
|
+
initialValue: GRAPH_SETTINGS.highlightTextFadingMin,
|
|
676
|
+
max: 1,
|
|
677
|
+
min: 0,
|
|
678
|
+
step: 0.01,
|
|
679
|
+
type: "range",
|
|
680
|
+
label: "Граница затухания текста при анимации",
|
|
681
|
+
},
|
|
682
|
+
{
|
|
683
|
+
id: "highlightLinkFadingMin",
|
|
684
|
+
initialValue: GRAPH_SETTINGS.highlightLinkFadingMin,
|
|
685
|
+
max: 1,
|
|
686
|
+
min: 0,
|
|
687
|
+
step: 0.01,
|
|
688
|
+
type: "range",
|
|
689
|
+
label: "Граница затухания связи при анимации",
|
|
690
|
+
},
|
|
691
|
+
{
|
|
692
|
+
id: "highlightFadingMin",
|
|
693
|
+
initialValue: GRAPH_SETTINGS.highlightFadingMin,
|
|
694
|
+
max: 1,
|
|
695
|
+
min: 0,
|
|
696
|
+
step: 0.01,
|
|
697
|
+
type: "range",
|
|
698
|
+
label: "Граница затухания ноды при анимации",
|
|
699
|
+
},
|
|
700
|
+
{
|
|
701
|
+
id: "highlightArrowFadingMin",
|
|
702
|
+
initialValue: GRAPH_SETTINGS.highlightArrowFadingMin,
|
|
703
|
+
max: 1,
|
|
704
|
+
min: 0,
|
|
705
|
+
step: 0.01,
|
|
706
|
+
type: "range",
|
|
707
|
+
label: "Граница затухания стрелки при анимации",
|
|
708
|
+
},
|
|
709
|
+
{
|
|
710
|
+
id: "highlightDownStep",
|
|
711
|
+
initialValue: GRAPH_SETTINGS.highlightDownStep,
|
|
712
|
+
max: 1,
|
|
713
|
+
min: 0.01,
|
|
714
|
+
step: 0.01,
|
|
715
|
+
type: "range",
|
|
716
|
+
label: "Скорость отмены анимации",
|
|
717
|
+
},
|
|
718
|
+
{
|
|
719
|
+
id: "highlightUpStep",
|
|
720
|
+
initialValue: GRAPH_SETTINGS.highlightUpStep,
|
|
721
|
+
max: 1,
|
|
722
|
+
min: 0.01,
|
|
723
|
+
step: 0.01,
|
|
724
|
+
type: "range",
|
|
725
|
+
label: "Скорость применения анимации",
|
|
726
|
+
},
|
|
727
|
+
{
|
|
728
|
+
id: "nodeRadiusInitial",
|
|
729
|
+
initialValue: GRAPH_SETTINGS.nodeRadiusInitial,
|
|
730
|
+
max: 50,
|
|
731
|
+
min: 0.1,
|
|
732
|
+
step: 0.1,
|
|
733
|
+
type: "range",
|
|
734
|
+
label: "Изначальный радиус ноды",
|
|
735
|
+
},
|
|
736
|
+
{
|
|
737
|
+
id: "nodeRadiusCoefficient",
|
|
738
|
+
initialValue: GRAPH_SETTINGS.nodeRadiusCoefficient,
|
|
739
|
+
max: 100,
|
|
740
|
+
min: 0.1,
|
|
741
|
+
step: 0.1,
|
|
742
|
+
type: "range",
|
|
743
|
+
label: "Количество связей для увеличения радиуса",
|
|
744
|
+
},
|
|
745
|
+
{
|
|
746
|
+
id: "nodeRadiusFactor",
|
|
747
|
+
initialValue: GRAPH_SETTINGS.nodeRadiusFactor,
|
|
748
|
+
max: 50,
|
|
749
|
+
min: 0.1,
|
|
750
|
+
step: 0.1,
|
|
751
|
+
type: "range",
|
|
752
|
+
label: "Коэффициент увеличения радиуса",
|
|
753
|
+
},
|
|
754
|
+
{
|
|
755
|
+
id: "highlightOnlyRoot",
|
|
756
|
+
type: "checkbox",
|
|
757
|
+
initialValue: GRAPH_SETTINGS.highlightOnlyRoot,
|
|
758
|
+
label: "Дополнительная анимация только главное цели",
|
|
759
|
+
},
|
|
760
|
+
{
|
|
761
|
+
id: "stickAfterDrag",
|
|
762
|
+
type: "checkbox",
|
|
763
|
+
initialValue: GRAPH_SETTINGS.stickAfterDrag,
|
|
764
|
+
label: "Фиксировании ноды после перетаскивания",
|
|
765
|
+
},
|
|
766
|
+
{
|
|
767
|
+
id: "highlightByHover",
|
|
768
|
+
type: "checkbox",
|
|
769
|
+
initialValue: GRAPH_SETTINGS.highlightByHover,
|
|
770
|
+
label: "Анимации при наведении",
|
|
771
|
+
},
|
|
772
|
+
{
|
|
773
|
+
id: "nodeRadiusFlexible",
|
|
774
|
+
type: "checkbox",
|
|
775
|
+
initialValue: GRAPH_SETTINGS.nodeRadiusFlexible,
|
|
776
|
+
label: "Гибкий радиус ноды",
|
|
777
|
+
},
|
|
778
|
+
];
|
|
779
|
+
return keys ? GRAPH_CONTROLS.filter((control) => keys.includes(control.id)) : GRAPH_CONTROLS;
|
|
780
|
+
}
|
|
781
|
+
function getNodeControls(keys) {
|
|
782
|
+
const NODE_CONTROLS = [
|
|
783
|
+
{
|
|
784
|
+
id: "alpha",
|
|
785
|
+
type: "range",
|
|
786
|
+
max: 1,
|
|
787
|
+
min: 0,
|
|
788
|
+
step: 0.1,
|
|
789
|
+
label: "Прозрачность",
|
|
790
|
+
initialValue: NODE_OPTIONS.alpha,
|
|
791
|
+
},
|
|
792
|
+
{
|
|
793
|
+
id: "radius",
|
|
794
|
+
type: "range",
|
|
795
|
+
max: 50,
|
|
796
|
+
min: 1,
|
|
797
|
+
step: 1,
|
|
798
|
+
label: "Радиус",
|
|
799
|
+
initialValue: NODE_OPTIONS.radius,
|
|
800
|
+
},
|
|
801
|
+
{
|
|
802
|
+
id: "borderWidth",
|
|
803
|
+
type: "range",
|
|
804
|
+
max: 5,
|
|
805
|
+
min: 0,
|
|
806
|
+
step: 0.1,
|
|
807
|
+
label: "Толщина границы",
|
|
808
|
+
initialValue: NODE_OPTIONS.borderWidth,
|
|
809
|
+
},
|
|
810
|
+
{
|
|
811
|
+
id: "borderColor",
|
|
812
|
+
type: "color",
|
|
813
|
+
initialValue: "#000000FF",
|
|
814
|
+
label: "Цвет границы",
|
|
815
|
+
},
|
|
816
|
+
{
|
|
817
|
+
id: "color",
|
|
818
|
+
type: "color",
|
|
819
|
+
initialValue: "#000000FF",
|
|
820
|
+
label: "Цвет",
|
|
821
|
+
},
|
|
822
|
+
{
|
|
823
|
+
id: "textAlpha",
|
|
824
|
+
type: "range",
|
|
825
|
+
max: 1,
|
|
826
|
+
min: 0,
|
|
827
|
+
step: 0.1,
|
|
828
|
+
label: "Прозрачность текста",
|
|
829
|
+
initialValue: NODE_OPTIONS.textAlpha,
|
|
830
|
+
},
|
|
831
|
+
{
|
|
832
|
+
id: "textWidth",
|
|
833
|
+
type: "range",
|
|
834
|
+
max: 200,
|
|
835
|
+
min: 5,
|
|
836
|
+
step: 1,
|
|
837
|
+
label: "Ширина текста",
|
|
838
|
+
initialValue: NODE_OPTIONS.textWidth,
|
|
839
|
+
},
|
|
840
|
+
{
|
|
841
|
+
id: "textShiftX",
|
|
842
|
+
type: "range",
|
|
843
|
+
max: 100,
|
|
844
|
+
min: 0,
|
|
845
|
+
step: 0.1,
|
|
846
|
+
label: "Смещение X текста",
|
|
847
|
+
initialValue: NODE_OPTIONS.textShiftX,
|
|
848
|
+
},
|
|
849
|
+
{
|
|
850
|
+
id: "textShiftY",
|
|
851
|
+
type: "range",
|
|
852
|
+
max: 100,
|
|
853
|
+
min: 0,
|
|
854
|
+
step: 0.1,
|
|
855
|
+
label: "Смещение Y текста",
|
|
856
|
+
initialValue: 4,
|
|
857
|
+
},
|
|
858
|
+
{
|
|
859
|
+
id: "textWeight",
|
|
860
|
+
type: "range",
|
|
861
|
+
max: 1000,
|
|
862
|
+
min: 100,
|
|
863
|
+
step: 100,
|
|
864
|
+
label: "Жирность текста",
|
|
865
|
+
initialValue: NODE_OPTIONS.textWeight,
|
|
866
|
+
},
|
|
867
|
+
{
|
|
868
|
+
id: "textGap",
|
|
869
|
+
type: "range",
|
|
870
|
+
max: 30,
|
|
871
|
+
min: 0,
|
|
872
|
+
step: 0.1,
|
|
873
|
+
label: "Расстояние между строками",
|
|
874
|
+
initialValue: NODE_OPTIONS.textGap,
|
|
875
|
+
},
|
|
876
|
+
{
|
|
877
|
+
id: "highlightFading",
|
|
878
|
+
type: "checkbox",
|
|
879
|
+
initialValue: NODE_OPTIONS.highlightFading,
|
|
880
|
+
label: "Анимация затухания",
|
|
881
|
+
},
|
|
882
|
+
{
|
|
883
|
+
id: "highlightColor",
|
|
884
|
+
type: "checkbox",
|
|
885
|
+
initialValue: NODE_OPTIONS.highlightColor,
|
|
886
|
+
label: "Анимация затухания цвета",
|
|
887
|
+
},
|
|
888
|
+
{
|
|
889
|
+
id: "highlightSizing",
|
|
890
|
+
type: "checkbox",
|
|
891
|
+
initialValue: NODE_OPTIONS.highlightSizing,
|
|
892
|
+
label: "Анимация размера",
|
|
893
|
+
},
|
|
894
|
+
{
|
|
895
|
+
id: "highlightTextFading",
|
|
896
|
+
type: "checkbox",
|
|
897
|
+
initialValue: NODE_OPTIONS.highlightTextFading,
|
|
898
|
+
label: "Анимация затухания текста",
|
|
899
|
+
},
|
|
900
|
+
{
|
|
901
|
+
id: "highlightTextSizing",
|
|
902
|
+
type: "checkbox",
|
|
903
|
+
initialValue: NODE_OPTIONS.highlightTextSizing,
|
|
904
|
+
label: "Анимация размера текста",
|
|
905
|
+
},
|
|
906
|
+
];
|
|
907
|
+
return keys ? NODE_CONTROLS.filter((control) => keys.includes(control.id)) : NODE_CONTROLS;
|
|
908
|
+
}
|
|
909
|
+
function getLinkControls(keys) {
|
|
910
|
+
const LINK_CONTROLS = [
|
|
911
|
+
{
|
|
912
|
+
id: "alpha",
|
|
913
|
+
type: "range",
|
|
914
|
+
max: 1,
|
|
915
|
+
min: 0,
|
|
916
|
+
step: 0.1,
|
|
917
|
+
label: "Прозрачность",
|
|
918
|
+
initialValue: LINK_OPTIONS.alpha,
|
|
919
|
+
},
|
|
920
|
+
{
|
|
921
|
+
id: "width",
|
|
922
|
+
type: "range",
|
|
923
|
+
max: 10,
|
|
924
|
+
min: 0.1,
|
|
925
|
+
step: 0.1,
|
|
926
|
+
label: "Толщина",
|
|
927
|
+
initialValue: 0.1,
|
|
928
|
+
},
|
|
929
|
+
{
|
|
930
|
+
id: "arrowAlpha",
|
|
931
|
+
type: "range",
|
|
932
|
+
max: 1,
|
|
933
|
+
min: 0,
|
|
934
|
+
step: 0.1,
|
|
935
|
+
label: "Прозрачность стрелки",
|
|
936
|
+
initialValue: LINK_OPTIONS.arrowAlpha,
|
|
937
|
+
},
|
|
938
|
+
{
|
|
939
|
+
id: "arrowSize",
|
|
940
|
+
type: "range",
|
|
941
|
+
max: 10,
|
|
942
|
+
min: 0.1,
|
|
943
|
+
step: 0.1,
|
|
944
|
+
label: "Размер стрелки",
|
|
945
|
+
initialValue: LINK_OPTIONS.arrowSize,
|
|
946
|
+
},
|
|
947
|
+
{
|
|
948
|
+
id: "particleAlpha",
|
|
949
|
+
type: "range",
|
|
950
|
+
max: 1,
|
|
951
|
+
min: 0,
|
|
952
|
+
step: 0.1,
|
|
953
|
+
label: "Прозрачность частиц",
|
|
954
|
+
initialValue: LINK_OPTIONS.particleAlpha,
|
|
955
|
+
},
|
|
956
|
+
{
|
|
957
|
+
id: "particleRadius",
|
|
958
|
+
type: "range",
|
|
959
|
+
max: 10,
|
|
960
|
+
min: 0.1,
|
|
961
|
+
step: 0.1,
|
|
962
|
+
label: "Радиус частиц",
|
|
963
|
+
initialValue: LINK_OPTIONS.particleRadius,
|
|
964
|
+
},
|
|
965
|
+
{
|
|
966
|
+
id: "particleCount",
|
|
967
|
+
type: "range",
|
|
968
|
+
max: 20,
|
|
969
|
+
min: 1,
|
|
970
|
+
step: 1,
|
|
971
|
+
label: "Количество частиц",
|
|
972
|
+
initialValue: LINK_OPTIONS.particleCount,
|
|
973
|
+
},
|
|
974
|
+
{
|
|
975
|
+
id: "particleSteps",
|
|
976
|
+
type: "range",
|
|
977
|
+
max: 200,
|
|
978
|
+
min: 1,
|
|
979
|
+
step: 1,
|
|
980
|
+
label: "Количество кадров у частиц",
|
|
981
|
+
initialValue: LINK_OPTIONS.particleSteps,
|
|
982
|
+
},
|
|
983
|
+
{
|
|
984
|
+
id: "color",
|
|
985
|
+
type: "color",
|
|
986
|
+
initialValue: "#000000FF",
|
|
987
|
+
label: "Цвет",
|
|
988
|
+
},
|
|
989
|
+
{
|
|
990
|
+
id: "arrowColor",
|
|
991
|
+
type: "color",
|
|
992
|
+
initialValue: "#000000FF",
|
|
993
|
+
label: "Цвет стрелки",
|
|
994
|
+
},
|
|
995
|
+
{
|
|
996
|
+
id: "particleColor",
|
|
997
|
+
type: "color",
|
|
998
|
+
initialValue: "#000000FF",
|
|
999
|
+
label: "Цвет частиц",
|
|
1000
|
+
},
|
|
1001
|
+
{
|
|
1002
|
+
id: "highlightFading",
|
|
1003
|
+
type: "checkbox",
|
|
1004
|
+
label: "Анимация Затухания",
|
|
1005
|
+
initialValue: LINK_OPTIONS.highlightFading,
|
|
1006
|
+
},
|
|
1007
|
+
{
|
|
1008
|
+
id: "pretty",
|
|
1009
|
+
type: "checkbox",
|
|
1010
|
+
label: "Обсчет соединения",
|
|
1011
|
+
initialValue: LINK_OPTIONS.pretty,
|
|
1012
|
+
},
|
|
1013
|
+
{
|
|
1014
|
+
id: "arrow",
|
|
1015
|
+
type: "checkbox",
|
|
1016
|
+
label: "Стрелка",
|
|
1017
|
+
initialValue: LINK_OPTIONS.arrow,
|
|
1018
|
+
},
|
|
1019
|
+
{
|
|
1020
|
+
id: "arrowHighlightFading",
|
|
1021
|
+
type: "checkbox",
|
|
1022
|
+
label: "Анимация затухания стрелки",
|
|
1023
|
+
initialValue: LINK_OPTIONS.arrowHighlightFading,
|
|
1024
|
+
},
|
|
1025
|
+
{
|
|
1026
|
+
id: "arrowReverseAppear",
|
|
1027
|
+
type: "checkbox",
|
|
1028
|
+
label: "Появление стрелки при анимации",
|
|
1029
|
+
initialValue: LINK_OPTIONS.arrowReverseAppear,
|
|
1030
|
+
},
|
|
1031
|
+
];
|
|
1032
|
+
return keys ? LINK_CONTROLS.filter((control) => keys.includes(control.id)) : LINK_CONTROLS;
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
let countTime = 0;
|
|
1036
|
+
let countOperation = 0;
|
|
1037
|
+
function setDrawTime(cb, showEveryTick) {
|
|
1038
|
+
return () => {
|
|
1039
|
+
const start = performance.now();
|
|
1040
|
+
cb();
|
|
1041
|
+
const end = performance.now();
|
|
1042
|
+
const result = end - start;
|
|
1043
|
+
countTime += result;
|
|
1044
|
+
countOperation++;
|
|
1045
|
+
if (showEveryTick) {
|
|
1046
|
+
const average = countTime / countOperation;
|
|
1047
|
+
// eslint-disable-next-line no-console
|
|
1048
|
+
console.log("average draw: ", average, "current draw: ", result);
|
|
1049
|
+
}
|
|
1050
|
+
};
|
|
1051
|
+
}
|
|
1052
|
+
function getDrawTime() {
|
|
1053
|
+
const average = countTime / countOperation;
|
|
1054
|
+
// eslint-disable-next-line no-console
|
|
1055
|
+
console.log("average draw: ", average);
|
|
1056
|
+
}
|
|
1057
|
+
|
|
431
1058
|
class GraphCanvas {
|
|
432
1059
|
/** initial data */
|
|
433
1060
|
nodes;
|
|
434
1061
|
links;
|
|
1062
|
+
particles = {};
|
|
435
1063
|
width;
|
|
436
1064
|
height;
|
|
437
1065
|
root;
|
|
@@ -451,6 +1079,8 @@ class GraphCanvas {
|
|
|
451
1079
|
draw;
|
|
452
1080
|
eventAbortController;
|
|
453
1081
|
cachedNodeText = {};
|
|
1082
|
+
linkOptionsCache = {};
|
|
1083
|
+
nodeOptionsCache = {};
|
|
454
1084
|
isDragging = false;
|
|
455
1085
|
highlightedNode = null;
|
|
456
1086
|
highlightedNeighbors = null;
|
|
@@ -523,20 +1153,35 @@ class GraphCanvas {
|
|
|
523
1153
|
this.updateData(alpha);
|
|
524
1154
|
}
|
|
525
1155
|
changeSettings(options) {
|
|
526
|
-
if (options.graphSettings)
|
|
1156
|
+
if (options.graphSettings) {
|
|
527
1157
|
this.graphSettings = graphSettingsGetter(options.graphSettings, this.graphSettings);
|
|
528
|
-
|
|
1158
|
+
this.draw = this.initDraw();
|
|
1159
|
+
this.initZoom(this.areaTransform);
|
|
1160
|
+
}
|
|
1161
|
+
if (options.forceSettings) {
|
|
529
1162
|
this.forceSettings = forceSettingsGetter(options.forceSettings, this.forceSettings);
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
this.
|
|
534
|
-
|
|
1163
|
+
}
|
|
1164
|
+
if (options.linkSettings) {
|
|
1165
|
+
this.linkSettings = linkSettingsGetter(options.linkSettings, this.linkSettings);
|
|
1166
|
+
this.linkOptionsCache = {};
|
|
1167
|
+
}
|
|
1168
|
+
if (options.nodeSettings) {
|
|
1169
|
+
this.nodeSettings = nodeSettingsGetter(options.nodeSettings, this.nodeSettings);
|
|
1170
|
+
this.cachedNodeText = {};
|
|
1171
|
+
this.nodeOptionsCache = {};
|
|
1172
|
+
}
|
|
1173
|
+
if (options.forceSettings) {
|
|
535
1174
|
return void this.updateSimulation();
|
|
1175
|
+
}
|
|
536
1176
|
this.tick();
|
|
537
1177
|
}
|
|
1178
|
+
clearCache() {
|
|
1179
|
+
this.nodeOptionsCache = {};
|
|
1180
|
+
this.linkOptionsCache = {};
|
|
1181
|
+
this.cachedNodeText = {};
|
|
1182
|
+
}
|
|
538
1183
|
tick() {
|
|
539
|
-
if (!this.simulationWorking)
|
|
1184
|
+
if (!this.simulationWorking && !this.highlightWorking)
|
|
540
1185
|
this.draw();
|
|
541
1186
|
}
|
|
542
1187
|
restart(alpha) {
|
|
@@ -592,6 +1237,8 @@ class GraphCanvas {
|
|
|
592
1237
|
}
|
|
593
1238
|
clearDataDependencies() {
|
|
594
1239
|
this.cachedNodeText = {};
|
|
1240
|
+
this.nodeOptionsCache = {};
|
|
1241
|
+
this.linkOptionsCache = {};
|
|
595
1242
|
}
|
|
596
1243
|
updateData(alpha) {
|
|
597
1244
|
this.clearDataDependencies();
|
|
@@ -615,7 +1262,7 @@ class GraphCanvas {
|
|
|
615
1262
|
this.initZoom();
|
|
616
1263
|
this.initResize();
|
|
617
1264
|
this.initPointer();
|
|
618
|
-
if (!this.simulationWorking)
|
|
1265
|
+
if (!this.simulationWorking && !this.highlightWorking)
|
|
619
1266
|
this.draw();
|
|
620
1267
|
}
|
|
621
1268
|
init() {
|
|
@@ -636,6 +1283,8 @@ class GraphCanvas {
|
|
|
636
1283
|
})
|
|
637
1284
|
.on("end", () => {
|
|
638
1285
|
this.listeners.onSimulationEnd?.(this.state);
|
|
1286
|
+
if (this.graphSettings.showDrawTime)
|
|
1287
|
+
getDrawTime();
|
|
639
1288
|
});
|
|
640
1289
|
this.initSimulationForces();
|
|
641
1290
|
}
|
|
@@ -658,9 +1307,9 @@ class GraphCanvas {
|
|
|
658
1307
|
.distanceMax(this.forceSettings.chargeDistanceMax)
|
|
659
1308
|
.distanceMin(this.forceSettings.chargeDistanceMin))
|
|
660
1309
|
.force("center", d3Force.forceCenter(this.forceSettings.centerPosition.x ?? 0, this.forceSettings.centerPosition.y ?? 0).strength(this.forceSettings.centerStrength));
|
|
661
|
-
this.initCollideForce();
|
|
1310
|
+
this.initCollideForce(true);
|
|
662
1311
|
}
|
|
663
|
-
initCollideForce() {
|
|
1312
|
+
initCollideForce(forceUpdate) {
|
|
664
1313
|
if (!this.simulation)
|
|
665
1314
|
return;
|
|
666
1315
|
if (!this.forceSettings.collideOn) {
|
|
@@ -671,9 +1320,10 @@ class GraphCanvas {
|
|
|
671
1320
|
const isHasMax = this.forceSettings.collideOffMax.links != 0 && this.forceSettings.collideOffMax.nodes != 0;
|
|
672
1321
|
const isMaxCollideNodes = isHasMax && this.forceSettings.collideOffMax.nodes < this.nodes.length;
|
|
673
1322
|
const isMaxCollideLinks = isHasMax && this.forceSettings.collideOffMax.links < this.links.length;
|
|
674
|
-
if (isMaxCollideNodes && isMaxCollideLinks)
|
|
1323
|
+
if (isMaxCollideNodes && isMaxCollideLinks) {
|
|
675
1324
|
this.simulation.force("collide", null);
|
|
676
|
-
|
|
1325
|
+
}
|
|
1326
|
+
else if (!this.simulation.force("collide") || forceUpdate) {
|
|
677
1327
|
this.simulation.force("collide", d3Force.forceCollide()
|
|
678
1328
|
.radius((node, index) => {
|
|
679
1329
|
if (this.forceSettings.collideRadius) {
|
|
@@ -691,6 +1341,7 @@ class GraphCanvas {
|
|
|
691
1341
|
})
|
|
692
1342
|
.strength(this.forceSettings.collideStrength)
|
|
693
1343
|
.iterations(this.forceSettings.collideIterations));
|
|
1344
|
+
}
|
|
694
1345
|
}
|
|
695
1346
|
initArea() {
|
|
696
1347
|
if (!this.area || !this.context || !this.container) {
|
|
@@ -725,19 +1376,27 @@ class GraphCanvas {
|
|
|
725
1376
|
this.highlightProgress -= this.graphSettings.highlightDownStep;
|
|
726
1377
|
if (!this.simulationWorking)
|
|
727
1378
|
return void requestAnimationFrame(() => this.draw());
|
|
728
|
-
|
|
1379
|
+
if (!this.linkSettings.particles)
|
|
1380
|
+
return;
|
|
729
1381
|
}
|
|
730
1382
|
if (this.highlightWorking && this.highlightProgress < 1) {
|
|
731
1383
|
this.highlightProgress += this.graphSettings.highlightUpStep;
|
|
732
1384
|
if (!this.simulationWorking)
|
|
733
1385
|
return void requestAnimationFrame(() => this.draw());
|
|
734
|
-
|
|
1386
|
+
if (!this.linkSettings.particles)
|
|
1387
|
+
return;
|
|
1388
|
+
}
|
|
1389
|
+
if (this.linkSettings.particles && this.highlightWorking && !this.simulationWorking) {
|
|
1390
|
+
return void requestAnimationFrame(() => this.draw());
|
|
735
1391
|
}
|
|
736
1392
|
if (!this.highlightWorking && this.highlightProgress <= 0) {
|
|
737
|
-
if (this.highlightedNeighbors)
|
|
1393
|
+
if (this.highlightedNeighbors || this.highlightedNode) {
|
|
738
1394
|
this.highlightedNeighbors = null;
|
|
739
|
-
if (this.highlightedNode)
|
|
740
1395
|
this.highlightedNode = null;
|
|
1396
|
+
this.particles = {};
|
|
1397
|
+
if (!this.simulationWorking)
|
|
1398
|
+
return void requestAnimationFrame(() => this.draw());
|
|
1399
|
+
}
|
|
741
1400
|
}
|
|
742
1401
|
this.highlightDrawing = false;
|
|
743
1402
|
}
|
|
@@ -760,13 +1419,13 @@ class GraphCanvas {
|
|
|
760
1419
|
this.context.clearRect(0, 0, this.width, this.height);
|
|
761
1420
|
this.context.translate(this.areaTransform.x, this.areaTransform.y);
|
|
762
1421
|
this.context.scale(this.areaTransform.k, this.areaTransform.k);
|
|
1422
|
+
const textRenders = [];
|
|
1423
|
+
const nodeRenders = [];
|
|
1424
|
+
this.nodes.forEach(getDrawNode(nodeRenders, textRenders, state).bind(this));
|
|
763
1425
|
/** links */
|
|
764
|
-
this.context.beginPath();
|
|
765
1426
|
this.links.forEach(getDrawLink(state).bind(this));
|
|
766
|
-
this.context.stroke();
|
|
767
1427
|
/** nodes */
|
|
768
|
-
|
|
769
|
-
this.nodes.forEach(getDrawNode(textRenders, state).bind(this));
|
|
1428
|
+
nodeRenders.forEach((render) => render());
|
|
770
1429
|
textRenders.forEach((render) => render());
|
|
771
1430
|
this.context.restore();
|
|
772
1431
|
this.listeners.onDrawFinished?.(state);
|
|
@@ -782,52 +1441,151 @@ class GraphCanvas {
|
|
|
782
1441
|
!link.target.x ||
|
|
783
1442
|
!link.target.y)
|
|
784
1443
|
return;
|
|
785
|
-
|
|
1444
|
+
if (!link.source._visible && !link.target._visible)
|
|
1445
|
+
return;
|
|
1446
|
+
const id = `${link.target.id}${link.source.id}`;
|
|
1447
|
+
let linkOptions;
|
|
1448
|
+
if (this.linkSettings.cache && this.linkOptionsCache[id]) {
|
|
1449
|
+
linkOptions = this.linkOptionsCache[id];
|
|
1450
|
+
}
|
|
1451
|
+
else {
|
|
1452
|
+
linkOptions = linkIterationExtractor(link, index, this.links, state, this.linkSettings.options ?? {}, linkOptionsGetter);
|
|
1453
|
+
if (this.linkSettings.cache) {
|
|
1454
|
+
this.linkOptionsCache[id] = linkOptions;
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
786
1457
|
if (linkOptions.drawLink) {
|
|
787
1458
|
linkOptions.drawLink(link, linkOptions, state);
|
|
788
1459
|
return;
|
|
789
1460
|
}
|
|
790
1461
|
let alpha = linkOptions.alpha;
|
|
1462
|
+
let arrowAlpha = linkOptions.arrowReverseAppear ? 0 : linkOptions.arrowAlpha;
|
|
791
1463
|
if (this.highlightedNeighbors && this.highlightedNode) {
|
|
792
1464
|
/** Not highlighted */
|
|
793
1465
|
if (this.highlightedNode.id != link.source.id &&
|
|
794
1466
|
this.highlightedNode.id != link.target.id) {
|
|
795
|
-
if (linkOptions.highlightFading)
|
|
796
|
-
|
|
797
|
-
this.graphSettings.highlightLinkFadingMin
|
|
798
|
-
|
|
1467
|
+
if (linkOptions.highlightFading) {
|
|
1468
|
+
const min = this.graphSettings.highlightLinkFadingMin < alpha
|
|
1469
|
+
? this.graphSettings.highlightLinkFadingMin
|
|
1470
|
+
: alpha;
|
|
1471
|
+
alpha = animationByProgress(min, alpha - min, 1 - this.highlightProgress);
|
|
1472
|
+
}
|
|
1473
|
+
if (linkOptions.arrow &&
|
|
1474
|
+
linkOptions.arrowHighlightFading &&
|
|
1475
|
+
!linkOptions.arrowReverseAppear) {
|
|
1476
|
+
const min = this.graphSettings.highlightArrowFadingMin < arrowAlpha
|
|
1477
|
+
? this.graphSettings.highlightArrowFadingMin
|
|
1478
|
+
: arrowAlpha;
|
|
1479
|
+
arrowAlpha = animationByProgress(min, arrowAlpha - min, 1 - this.highlightProgress);
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
else {
|
|
1483
|
+
// eslint-disable-next-line no-lonely-if
|
|
1484
|
+
if (linkOptions.arrow && linkOptions.arrowReverseAppear) {
|
|
1485
|
+
/** Highlighted */
|
|
1486
|
+
arrowAlpha = animationByProgress(0, linkOptions.arrowAlpha, this.highlightProgress);
|
|
1487
|
+
}
|
|
799
1488
|
}
|
|
800
|
-
this.context.beginPath();
|
|
801
1489
|
}
|
|
1490
|
+
/** Link */
|
|
1491
|
+
this.context.beginPath();
|
|
802
1492
|
this.context.globalAlpha = alpha;
|
|
803
1493
|
this.context.strokeStyle = linkOptions.color;
|
|
804
1494
|
this.context.lineWidth = linkOptions.width;
|
|
1495
|
+
let xStart = link.source.x;
|
|
1496
|
+
let yStart = link.source.y;
|
|
1497
|
+
let xEnd = link.target.x;
|
|
1498
|
+
let yEnd = link.target.y;
|
|
805
1499
|
if (linkOptions.pretty) {
|
|
806
|
-
const
|
|
1500
|
+
const isHasArrow = linkOptions.arrow && arrowAlpha > 0;
|
|
1501
|
+
const { x1, x2, y1, y2 } = calculateLinkPositionByRadius(link, isHasArrow ? linkOptions.arrowSize : 0) ?? {
|
|
807
1502
|
x1: 0,
|
|
808
1503
|
x2: 0,
|
|
809
1504
|
y1: 0,
|
|
810
1505
|
y2: 0,
|
|
811
1506
|
};
|
|
812
|
-
|
|
813
|
-
|
|
1507
|
+
xStart = x1;
|
|
1508
|
+
xEnd = x2;
|
|
1509
|
+
yStart = y1;
|
|
1510
|
+
yEnd = y2;
|
|
814
1511
|
}
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
1512
|
+
this.context.moveTo(xStart, yStart);
|
|
1513
|
+
this.context.lineTo(xEnd, yEnd);
|
|
1514
|
+
this.context.stroke();
|
|
1515
|
+
/** Particle */
|
|
1516
|
+
if (this.linkSettings.particles &&
|
|
1517
|
+
this.highlightedNode &&
|
|
1518
|
+
(this.highlightedNode.id === link.source.id || this.highlightedNode.id === link.target.id)) {
|
|
1519
|
+
if (!this.particles[id]) {
|
|
1520
|
+
const sourceId = link.source.id;
|
|
1521
|
+
const targetId = link.target.id;
|
|
1522
|
+
this.particles[id] = Array.from({ length: linkOptions.particleCount }, (_, index) => {
|
|
1523
|
+
return {
|
|
1524
|
+
step: 0,
|
|
1525
|
+
wait: index * (linkOptions.particleSteps / linkOptions.particleCount),
|
|
1526
|
+
sourceId,
|
|
1527
|
+
targetId,
|
|
1528
|
+
};
|
|
1529
|
+
});
|
|
1530
|
+
}
|
|
1531
|
+
this.particles[id].forEach((particle) => {
|
|
1532
|
+
if (!this.context)
|
|
1533
|
+
return;
|
|
1534
|
+
getParticlePosition({
|
|
1535
|
+
particle,
|
|
1536
|
+
totalSteps: linkOptions.particleSteps,
|
|
1537
|
+
xEnd,
|
|
1538
|
+
xStart,
|
|
1539
|
+
yEnd,
|
|
1540
|
+
yStart,
|
|
1541
|
+
});
|
|
1542
|
+
if (particle.x != undefined && particle.y != undefined) {
|
|
1543
|
+
this.context.beginPath();
|
|
1544
|
+
this.context.arc(particle.x, particle.y, linkOptions.particleRadius, 0, Math.PI * 2);
|
|
1545
|
+
this.context.fillStyle = linkOptions.particleColor;
|
|
1546
|
+
this.context.fill();
|
|
1547
|
+
this.context.stroke();
|
|
1548
|
+
}
|
|
1549
|
+
});
|
|
818
1550
|
}
|
|
819
|
-
|
|
1551
|
+
/** Arrow */
|
|
1552
|
+
if (linkOptions.arrow && arrowAlpha > 0) {
|
|
1553
|
+
const { x1: xStart, x2: xEnd, y1: yStart, y2: yEnd, } = calculateLinkPositionByRadius(link) ?? {
|
|
1554
|
+
x1: 0,
|
|
1555
|
+
x2: 0,
|
|
1556
|
+
y1: 0,
|
|
1557
|
+
y2: 0,
|
|
1558
|
+
};
|
|
1559
|
+
const angle = Math.atan2(yEnd - yStart, xEnd - xStart);
|
|
1560
|
+
this.context.beginPath();
|
|
1561
|
+
this.context.globalAlpha = arrowAlpha;
|
|
1562
|
+
this.context.moveTo(xEnd, yEnd);
|
|
1563
|
+
this.context.lineTo(xEnd - linkOptions.arrowSize * Math.cos(angle - Math.PI / 6), yEnd - linkOptions.arrowSize * Math.sin(angle - Math.PI / 6));
|
|
1564
|
+
this.context.lineTo(xEnd - linkOptions.arrowSize * Math.cos(angle + Math.PI / 6), yEnd - linkOptions.arrowSize * Math.sin(angle + Math.PI / 6));
|
|
1565
|
+
this.context.closePath();
|
|
1566
|
+
this.context.fillStyle = linkOptions.arrowColor;
|
|
1567
|
+
this.context.fill();
|
|
820
1568
|
this.context.stroke();
|
|
1569
|
+
}
|
|
821
1570
|
if (linkOptions.drawExtraLink) {
|
|
822
1571
|
linkOptions.drawExtraLink(link, { ...linkOptions, alpha }, state);
|
|
823
1572
|
}
|
|
824
1573
|
};
|
|
825
1574
|
}
|
|
826
|
-
function getDrawNode(textRenders, state) {
|
|
1575
|
+
function getDrawNode(nodeRenders, textRenders, state) {
|
|
827
1576
|
return function drawNode(node, index) {
|
|
828
1577
|
if (!this.context || !node.x || !node.y)
|
|
829
1578
|
return;
|
|
830
|
-
|
|
1579
|
+
let nodeOptions;
|
|
1580
|
+
if (this.nodeSettings.cache && this.nodeOptionsCache[node.id]) {
|
|
1581
|
+
nodeOptions = this.nodeOptionsCache[node.id];
|
|
1582
|
+
}
|
|
1583
|
+
else {
|
|
1584
|
+
nodeOptions = nodeIterationExtractor(node, index, this.nodes, state, this.nodeSettings.options ?? {}, nodeOptionsGetter);
|
|
1585
|
+
if (this.nodeSettings.cache) {
|
|
1586
|
+
this.nodeOptionsCache[node.id] = nodeOptions;
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
831
1589
|
if (nodeOptions.nodeDraw) {
|
|
832
1590
|
nodeOptions.nodeDraw(node, nodeOptions, state);
|
|
833
1591
|
return;
|
|
@@ -845,15 +1603,16 @@ class GraphCanvas {
|
|
|
845
1603
|
/** Not highlighted */
|
|
846
1604
|
if (!this.highlightedNeighbors.has(node.id) && this.highlightedNode.id != node.id) {
|
|
847
1605
|
if (nodeOptions.highlightFading) {
|
|
848
|
-
|
|
849
|
-
this.graphSettings.highlightFadingMin
|
|
850
|
-
|
|
1606
|
+
const min = this.graphSettings.highlightFadingMin < alpha
|
|
1607
|
+
? this.graphSettings.highlightFadingMin
|
|
1608
|
+
: alpha;
|
|
1609
|
+
alpha = animationByProgress(min, alpha - min, 1 - this.highlightProgress);
|
|
851
1610
|
}
|
|
852
1611
|
if (nodeOptions.highlightTextFading) {
|
|
853
|
-
|
|
854
|
-
this.graphSettings.highlightTextFadingMin
|
|
855
|
-
|
|
856
|
-
|
|
1612
|
+
const min = this.graphSettings.highlightTextFadingMin < textAlpha
|
|
1613
|
+
? this.graphSettings.highlightTextFadingMin
|
|
1614
|
+
: textAlpha;
|
|
1615
|
+
textAlpha = animationByProgress(min, textAlpha - min, 1 - this.highlightProgress);
|
|
857
1616
|
}
|
|
858
1617
|
if (nodeOptions.highlightColor) {
|
|
859
1618
|
const colorRgb = extractRgb(colorToRgb(color));
|
|
@@ -868,20 +1627,14 @@ class GraphCanvas {
|
|
|
868
1627
|
(this.graphSettings.highlightOnlyRoot && this.highlightedNode.id === node.id)) {
|
|
869
1628
|
/** Highlighted */
|
|
870
1629
|
if (nodeOptions.highlightSizing) {
|
|
871
|
-
|
|
872
|
-
radiusInitial += ((radiusMax - radiusInitial) / 100) * (this.highlightProgress * 100);
|
|
1630
|
+
radiusInitial = animationByProgress(radiusInitial, this.graphSettings.highlightSizingAdditional, this.highlightProgress);
|
|
873
1631
|
}
|
|
874
1632
|
if (nodeOptions.highlightTextSizing) {
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
textSize += ((textSizeMax - textSize) / 100) * (this.highlightProgress * 100);
|
|
881
|
-
textShiftX += ((textShiftXMax - textShiftX) / 100) * (this.highlightProgress * 100);
|
|
882
|
-
textShiftY += ((textShiftYMax - textShiftY) / 100) * (this.highlightProgress * 100);
|
|
883
|
-
textWeight += ((textWeightMax - textWeight) / 100) * (this.highlightProgress * 100);
|
|
884
|
-
textWidth += ((textWidthMax - textWidth) / 100) * (this.highlightProgress * 100);
|
|
1633
|
+
textSize = animationByProgress(textSize, this.graphSettings.highlightTextSizingAdditional, this.highlightProgress);
|
|
1634
|
+
textShiftX = animationByProgress(textShiftX, this.graphSettings.highlightTextShiftXAdditional, this.highlightProgress);
|
|
1635
|
+
textShiftY = animationByProgress(textShiftY, this.graphSettings.highlightTextShiftYAdditional, this.highlightProgress);
|
|
1636
|
+
textWeight = animationByProgress(textWeight, this.graphSettings.highlightTextWeightAdditional, this.highlightProgress);
|
|
1637
|
+
textWidth = animationByProgress(textWidth, this.graphSettings.highlightTextWidthAdditional, this.highlightProgress);
|
|
885
1638
|
}
|
|
886
1639
|
}
|
|
887
1640
|
}
|
|
@@ -893,8 +1646,31 @@ class GraphCanvas {
|
|
|
893
1646
|
linkCount: node.linkCount,
|
|
894
1647
|
});
|
|
895
1648
|
node._radius = radius;
|
|
896
|
-
|
|
897
|
-
|
|
1649
|
+
if (!isNodeVisible({
|
|
1650
|
+
height: this.height,
|
|
1651
|
+
width: this.width,
|
|
1652
|
+
x: node.x,
|
|
1653
|
+
y: node.y,
|
|
1654
|
+
radius,
|
|
1655
|
+
transform: this.areaTransform,
|
|
1656
|
+
})) {
|
|
1657
|
+
node._visible = false;
|
|
1658
|
+
return;
|
|
1659
|
+
}
|
|
1660
|
+
node._visible = true;
|
|
1661
|
+
nodeRenders.push(() => {
|
|
1662
|
+
if (!this.context || !node.x || !node.y)
|
|
1663
|
+
return;
|
|
1664
|
+
this.context.beginPath();
|
|
1665
|
+
this.context.globalAlpha = alpha;
|
|
1666
|
+
/** circle */
|
|
1667
|
+
this.context.lineWidth = nodeOptions.borderWidth;
|
|
1668
|
+
this.context.strokeStyle = nodeOptions.borderColor;
|
|
1669
|
+
this.context.fillStyle = color;
|
|
1670
|
+
this.context.arc(node.x, node.y, radius, 0, 2 * Math.PI);
|
|
1671
|
+
this.context.fill();
|
|
1672
|
+
this.context.stroke();
|
|
1673
|
+
});
|
|
898
1674
|
/** text */
|
|
899
1675
|
if (nodeOptions.textVisible && nodeOptions.text) {
|
|
900
1676
|
textRenders.push(() => {
|
|
@@ -949,13 +1725,6 @@ class GraphCanvas {
|
|
|
949
1725
|
}
|
|
950
1726
|
});
|
|
951
1727
|
}
|
|
952
|
-
/** circle */
|
|
953
|
-
this.context.lineWidth = nodeOptions.borderWidth;
|
|
954
|
-
this.context.strokeStyle = nodeOptions.borderColor;
|
|
955
|
-
this.context.fillStyle = color;
|
|
956
|
-
this.context.arc(node.x, node.y, radius, 0, 2 * Math.PI);
|
|
957
|
-
this.context.fill();
|
|
958
|
-
this.context.stroke();
|
|
959
1728
|
if (nodeOptions.nodeExtraDraw) {
|
|
960
1729
|
nodeOptions.nodeExtraDraw(node, {
|
|
961
1730
|
...nodeOptions,
|
|
@@ -972,6 +1741,9 @@ class GraphCanvas {
|
|
|
972
1741
|
}
|
|
973
1742
|
};
|
|
974
1743
|
}
|
|
1744
|
+
if (this.graphSettings.showDrawTime) {
|
|
1745
|
+
return setDrawTime(draw.bind(this), this.graphSettings.showDrawTimeEveryTick);
|
|
1746
|
+
}
|
|
975
1747
|
return draw;
|
|
976
1748
|
}
|
|
977
1749
|
initResize() {
|
|
@@ -1165,7 +1937,7 @@ class GraphCanvas {
|
|
|
1165
1937
|
this.listeners.onEndDragFinished?.(event, this.state);
|
|
1166
1938
|
}));
|
|
1167
1939
|
}
|
|
1168
|
-
initZoom() {
|
|
1940
|
+
initZoom(currentZoom) {
|
|
1169
1941
|
if (!this.area)
|
|
1170
1942
|
throw new Error("bad init data");
|
|
1171
1943
|
const zoomInstance = d3Zoom.zoom()
|
|
@@ -1173,7 +1945,9 @@ class GraphCanvas {
|
|
|
1173
1945
|
.on("zoom", (event) => {
|
|
1174
1946
|
this.listeners.onZoom?.(event);
|
|
1175
1947
|
this.areaTransform = event.transform;
|
|
1176
|
-
|
|
1948
|
+
this.linkOptionsCache = {};
|
|
1949
|
+
this.nodeOptionsCache = {};
|
|
1950
|
+
if (!this.simulationWorking && !this.highlightWorking)
|
|
1177
1951
|
requestAnimationFrame(() => this.draw());
|
|
1178
1952
|
});
|
|
1179
1953
|
if (this.graphSettings.translateExtentEnable) {
|
|
@@ -1188,18 +1962,24 @@ class GraphCanvas {
|
|
|
1188
1962
|
]);
|
|
1189
1963
|
}
|
|
1190
1964
|
d3Selection.select(this.area).call(zoomInstance).on("dblclick.zoom", null);
|
|
1191
|
-
const zoomInitial = this.graphSettings.zoomInitial;
|
|
1965
|
+
const zoomInitial = currentZoom ?? this.graphSettings.zoomInitial;
|
|
1192
1966
|
this.areaTransform = new d3Zoom.ZoomTransform(zoomInitial?.k ?? 1, zoomInitial?.x ?? this.width / 2, zoomInitial?.y ?? this.height / 2);
|
|
1193
1967
|
d3Zoom.zoom().transform(d3Selection.select(this.area), this.areaTransform);
|
|
1194
1968
|
}
|
|
1195
1969
|
}
|
|
1196
1970
|
|
|
1197
1971
|
exports.GraphCanvas = GraphCanvas;
|
|
1972
|
+
exports.animationByProgress = animationByProgress;
|
|
1198
1973
|
exports.calculateLinkPositionByRadius = calculateLinkPositionByRadius;
|
|
1199
1974
|
exports.colorToRgb = colorToRgb;
|
|
1200
1975
|
exports.drawText = drawText;
|
|
1201
1976
|
exports.extractRgb = extractRgb;
|
|
1202
1977
|
exports.fadeRgb = fadeRgb;
|
|
1978
|
+
exports.getForceControls = getForceControls;
|
|
1979
|
+
exports.getGraphControls = getGraphControls;
|
|
1980
|
+
exports.getLinkControls = getLinkControls;
|
|
1981
|
+
exports.getNodeControls = getNodeControls;
|
|
1982
|
+
exports.getParticlePosition = getParticlePosition;
|
|
1203
1983
|
exports.linkIterationExtractor = linkIterationExtractor;
|
|
1204
1984
|
exports.linkOptionsGetter = linkOptionsGetter;
|
|
1205
1985
|
exports.nodeIterationExtractor = nodeIterationExtractor;
|