@krainovsd/graph 0.10.0-rc1 → 0.10.0-rc3

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 CHANGED
@@ -54,7 +54,7 @@ const NODE_SETTINGS = {
54
54
  highlightByHoverNode: true,
55
55
  nodeRadiusFlexible: true,
56
56
  nodeSizeFlexible: true,
57
- textNodeDebug: false,
57
+ textNodeDebug: true,
58
58
  highlightByNodeNodeFading: true,
59
59
  highlightByNodeNodeColor: false,
60
60
  highlightByNodeNodeSizing: true,
@@ -70,7 +70,7 @@ const NODE_SETTINGS = {
70
70
  nodeSizeCoefficient: 5,
71
71
  nodeSizeFactor: 0.1,
72
72
  highlightByNodeNodeSizingAdditional: 0.5,
73
- highlightByLinkNodeSizingAdditionalCoefficient: 0.35,
73
+ highlightByNodeNodeSizingAdditionalCoefficient: 0.35,
74
74
  highlightByNodeNodeColorFadingMin: 0.15,
75
75
  highlightByNodeTextShiftXAdditional: 0,
76
76
  highlightByNodeTextShiftYAdditional: 2,
@@ -80,7 +80,7 @@ const NODE_SETTINGS = {
80
80
  highlightByNodeNodeFadingMin: 0.21,
81
81
  highlightByNodeTextFadingMin: 0.21,
82
82
  highlightByLinkNodeSizingAdditional: 0.5,
83
- highlightByNodeNodeSizingAdditionalCoefficient: 0.35,
83
+ highlightByLinkNodeSizingAdditionalCoefficient: 0.35,
84
84
  highlightByLinkNodeColorFadingMin: 0.15,
85
85
  highlightByLinkTextShiftXAdditional: 0,
86
86
  highlightByLinkTextShiftYAdditional: 2,
@@ -97,8 +97,8 @@ const NODE_OPTIONS = {
97
97
  borderRadius: 0,
98
98
  radius: 4,
99
99
  alpha: 1,
100
- textNodeXPadding: 5,
101
- textNodeYPadding: 3,
100
+ textNodeXPadding: 1,
101
+ textNodeYPadding: 1,
102
102
  borderWidth: 0.1,
103
103
  borderColor: "#000000FF",
104
104
  textAlpha: 1,
@@ -1265,13 +1265,15 @@ function nodeRadiusGetter({ radiusFlexible, radiusInitial, linkCount, radiusCoef
1265
1265
  return ((radiusFlexible && linkCount ? linkCount / radiusCoefficient : 0) * radiusFactor + radiusInitial);
1266
1266
  }
1267
1267
  function nodeSizeGetter({ heightInitial, linkCount, sizeCoefficient, sizeFactor, sizeFlexible, widthInitial, }) {
1268
- let widthCoefficient = 1;
1269
- let heightCoefficient = 1;
1268
+ let additionalSizeCoefficient = 1;
1270
1269
  if (sizeFlexible && linkCount != undefined) {
1271
- widthCoefficient += (linkCount / sizeCoefficient) * sizeFactor;
1272
- heightCoefficient += (linkCount / sizeCoefficient) * sizeFactor;
1270
+ additionalSizeCoefficient += (linkCount / sizeCoefficient) * sizeFactor;
1273
1271
  }
1274
- return { width: widthInitial * widthCoefficient, height: heightInitial * heightCoefficient };
1272
+ return {
1273
+ width: widthInitial * additionalSizeCoefficient,
1274
+ height: heightInitial * additionalSizeCoefficient,
1275
+ additionalSizeCoefficient,
1276
+ };
1275
1277
  }
1276
1278
  function nodeIdGetter(node) {
1277
1279
  return node.id;
@@ -2118,7 +2120,7 @@ function drawText({ context, id, textAlign, textColor, textFont, textStyle, text
2118
2120
  context.fillText(text, x, y);
2119
2121
  return;
2120
2122
  }
2121
- const lines = getTextLines({
2123
+ const { lines } = getTextLines({
2122
2124
  context,
2123
2125
  maxWidth,
2124
2126
  text,
@@ -2142,6 +2144,7 @@ function getTextLines({ context, textAlign, textColor, textFont, textStyle, text
2142
2144
  const lines = [];
2143
2145
  let lineWidth = 0;
2144
2146
  let line = "";
2147
+ let currentMaxSize = 0;
2145
2148
  for (const word of text.split(" ")) {
2146
2149
  const size = context.measureText(word).width;
2147
2150
  lineWidth += size + spaceWidth;
@@ -2150,7 +2153,10 @@ function getTextLines({ context, textAlign, textColor, textFont, textStyle, text
2150
2153
  continue;
2151
2154
  }
2152
2155
  if (lineWidth > maxWidth) {
2153
- lineWidth = 0;
2156
+ const initialSize = lineWidth - size - spaceWidth;
2157
+ if (initialSize > currentMaxSize)
2158
+ currentMaxSize = initialSize;
2159
+ lineWidth = size;
2154
2160
  lines.push(line);
2155
2161
  line = word;
2156
2162
  }
@@ -2161,7 +2167,9 @@ function getTextLines({ context, textAlign, textColor, textFont, textStyle, text
2161
2167
  }
2162
2168
  if (line !== "")
2163
2169
  lines.push(line);
2164
- return lines;
2170
+ if (lineWidth > currentMaxSize)
2171
+ currentMaxSize = lineWidth;
2172
+ return { lines, currentMaxSize };
2165
2173
  }
2166
2174
 
2167
2175
  function getDrawNode(nodeRenders, textRenders, state) {
@@ -2180,10 +2188,14 @@ function getDrawNode(nodeRenders, textRenders, state) {
2180
2188
  }
2181
2189
  if (nodeOptions.nodeDraw && nodeOptions.textDraw) {
2182
2190
  nodeRenders.push(() => {
2183
- nodeOptions?.nodeDraw?.(node, nodeOptions, state);
2191
+ if (nodeOptions.nodeDraw) {
2192
+ nodeOptions.nodeDraw.bind(this)(node, nodeOptions);
2193
+ }
2184
2194
  });
2185
2195
  textRenders.push(() => {
2186
- nodeOptions?.textDraw?.(node, nodeOptions, state);
2196
+ if (nodeOptions.textDraw) {
2197
+ nodeOptions.textDraw.bind(this)(node, nodeOptions);
2198
+ }
2187
2199
  });
2188
2200
  return;
2189
2201
  }
@@ -2198,6 +2210,7 @@ function getDrawNode(nodeRenders, textRenders, state) {
2198
2210
  let textShiftY = nodeOptions.textShiftY;
2199
2211
  let textWeight = nodeOptions.textWeight;
2200
2212
  let textWidth = nodeOptions.textWidth;
2213
+ let sizeCoefficient = 1;
2201
2214
  /** Node Highlight */
2202
2215
  if (this.highlightedNeighbors && this.highlightedNode) {
2203
2216
  /** Not highlighted */
@@ -2229,12 +2242,11 @@ function getDrawNode(nodeRenders, textRenders, state) {
2229
2242
  if (this.nodeSettings.highlightByNodeNodeSizing && nodeOptions.shape === "circle") {
2230
2243
  radiusInitial = animationByProgress(radiusInitial, this.nodeSettings.highlightByNodeNodeSizingAdditional, this.highlightProgress);
2231
2244
  }
2232
- if (this.nodeSettings.highlightByLinkNodeSizing &&
2245
+ if (this.nodeSettings.highlightByNodeNodeSizing &&
2233
2246
  (nodeOptions.shape === "square" || nodeOptions.shape === "text")) {
2234
- const widthCoefficient = animationByProgress(1, this.nodeSettings.highlightByNodeNodeSizingAdditionalCoefficient, this.highlightProgress);
2235
- const heightCoefficient = animationByProgress(1, this.nodeSettings.highlightByNodeNodeSizingAdditionalCoefficient, this.highlightProgress);
2236
- widthInitial *= widthCoefficient;
2237
- heightInitial *= heightCoefficient;
2247
+ sizeCoefficient = animationByProgress(sizeCoefficient, this.nodeSettings.highlightByNodeNodeSizingAdditionalCoefficient, this.highlightProgress);
2248
+ widthInitial *= sizeCoefficient;
2249
+ heightInitial *= sizeCoefficient;
2238
2250
  }
2239
2251
  if (this.nodeSettings.highlightByNodeTextSizing) {
2240
2252
  textSize = animationByProgress(textSize, this.nodeSettings.highlightByNodeTextSizingAdditional, this.highlightProgress);
@@ -2281,10 +2293,9 @@ function getDrawNode(nodeRenders, textRenders, state) {
2281
2293
  (nodeOptions.shape === "square" ||
2282
2294
  nodeOptions.shape === "text" ||
2283
2295
  nodeOptions.shape === "icon")) {
2284
- const widthCoefficient = animationByProgress(1, this.nodeSettings.highlightByLinkNodeSizingAdditionalCoefficient, this.highlightProgress);
2285
- const heightCoefficient = animationByProgress(1, this.nodeSettings.highlightByLinkNodeSizingAdditionalCoefficient, this.highlightProgress);
2286
- widthInitial *= widthCoefficient;
2287
- heightInitial *= heightCoefficient;
2296
+ sizeCoefficient = animationByProgress(sizeCoefficient, this.nodeSettings.highlightByNodeNodeSizingAdditionalCoefficient, this.highlightProgress);
2297
+ widthInitial *= sizeCoefficient;
2298
+ heightInitial *= sizeCoefficient;
2288
2299
  }
2289
2300
  if (this.nodeSettings.highlightByLinkTextSizing) {
2290
2301
  textSize = animationByProgress(textSize, this.nodeSettings.highlightByLinkTextSizingAdditional, this.highlightProgress);
@@ -2308,7 +2319,7 @@ function getDrawNode(nodeRenders, textRenders, state) {
2308
2319
  /** Flex size */
2309
2320
  let height = heightInitial;
2310
2321
  let width = widthInitial;
2311
- if (nodeOptions.shape === "square" || nodeOptions.shape === "text") {
2322
+ if (nodeOptions.shape === "square") {
2312
2323
  const size = nodeSizeGetter({
2313
2324
  heightInitial,
2314
2325
  widthInitial,
@@ -2320,27 +2331,53 @@ function getDrawNode(nodeRenders, textRenders, state) {
2320
2331
  width = size.width;
2321
2332
  height = size.height;
2322
2333
  }
2334
+ if (nodeOptions.shape === "text") {
2335
+ width = nodeOptions.width;
2336
+ const size = nodeSizeGetter({
2337
+ heightInitial,
2338
+ widthInitial: width,
2339
+ linkCount: node.linkCount,
2340
+ sizeCoefficient: this.nodeSettings.nodeSizeCoefficient,
2341
+ sizeFactor: this.nodeSettings.nodeSizeFactor,
2342
+ sizeFlexible: this.nodeSettings.nodeSizeFlexible,
2343
+ });
2344
+ textSize *= size.additionalSizeCoefficient;
2345
+ }
2346
+ /** Size by text in textNode */
2323
2347
  if (nodeOptions.shape === "text" && nodeOptions.text) {
2324
- const lines = this.cachedNodeText[node.id] ??
2325
- getTextLines({
2348
+ textWidth = width;
2349
+ let lines;
2350
+ let textNodeParameters;
2351
+ const cachedLines = this.cachedNodeText[node.id];
2352
+ const cachedTextNodeParameters = this.cachedTextNodeParameters[node.id];
2353
+ if (cachedLines != undefined && cachedTextNodeParameters != undefined) {
2354
+ lines = cachedLines;
2355
+ textNodeParameters = cachedTextNodeParameters;
2356
+ }
2357
+ else {
2358
+ const textInfo = getTextLines({
2326
2359
  context: this.context,
2327
2360
  text: nodeOptions.text,
2328
2361
  textAlign: nodeOptions.textAlign,
2329
2362
  textColor: nodeOptions.textColor,
2330
2363
  textFont: nodeOptions.textFont,
2331
2364
  textSize,
2332
- maxWidth: width,
2365
+ maxWidth: textWidth,
2333
2366
  textStyle: nodeOptions.textStyle,
2334
2367
  textWeight,
2335
2368
  });
2336
- if (!this.cachedNodeText[node.id]) {
2369
+ textNodeParameters = [textInfo.currentMaxSize, textSize];
2370
+ lines = textInfo.lines;
2337
2371
  this.cachedNodeText[node.id] = lines;
2372
+ this.cachedTextNodeParameters[node.id] = textNodeParameters;
2338
2373
  }
2374
+ const textSizeCoefficient = textSize / textNodeParameters[1];
2375
+ const maxSize = textNodeParameters[0] * textSizeCoefficient;
2339
2376
  height =
2340
2377
  lines.length * textSize +
2341
2378
  (lines.length - 1) * nodeOptions.textGap +
2342
2379
  nodeOptions.textNodeYPadding;
2343
- width += nodeOptions.textNodeXPadding;
2380
+ width = maxSize + nodeOptions.textNodeXPadding;
2344
2381
  }
2345
2382
  /** Node parameters */
2346
2383
  node._radius = radius;
@@ -2397,7 +2434,7 @@ function getDrawNode(nodeRenders, textRenders, state) {
2397
2434
  textSize,
2398
2435
  x: node.x,
2399
2436
  y: node.y + textSize / 4 - (lines.length - 1) * (textSize / 2),
2400
- maxWidth: widthInitial,
2437
+ maxWidth: textWidth,
2401
2438
  textStyle: nodeOptions.textStyle,
2402
2439
  textWeight,
2403
2440
  textGap: nodeOptions.textGap,
@@ -2414,7 +2451,7 @@ function getDrawNode(nodeRenders, textRenders, state) {
2414
2451
  });
2415
2452
  if (nodeOptions.nodeExtraDraw) {
2416
2453
  nodeRenders.push(() => {
2417
- nodeOptions?.nodeExtraDraw?.(node, {
2454
+ nodeOptions?.nodeExtraDraw?.bind?.(this)?.(node, {
2418
2455
  ...nodeOptions,
2419
2456
  radius,
2420
2457
  alpha,
@@ -2425,14 +2462,14 @@ function getDrawNode(nodeRenders, textRenders, state) {
2425
2462
  textShiftY,
2426
2463
  textWeight,
2427
2464
  textWidth,
2428
- }, state);
2465
+ });
2429
2466
  });
2430
2467
  }
2431
2468
  /** Text draw */
2432
2469
  if (nodeOptions.textVisible && nodeOptions.text && nodeOptions.shape !== "text") {
2433
2470
  textRenders.push(() => {
2434
2471
  if (nodeOptions.textDraw) {
2435
- nodeOptions.textDraw(node, {
2472
+ nodeOptions.textDraw.bind(this)(node, {
2436
2473
  ...nodeOptions,
2437
2474
  radius,
2438
2475
  alpha,
@@ -2443,7 +2480,7 @@ function getDrawNode(nodeRenders, textRenders, state) {
2443
2480
  textShiftY,
2444
2481
  textWeight,
2445
2482
  textWidth,
2446
- }, state);
2483
+ });
2447
2484
  return;
2448
2485
  }
2449
2486
  if (!this.context || !node.x || !node.y || !nodeOptions.text)
@@ -2474,7 +2511,7 @@ function getDrawNode(nodeRenders, textRenders, state) {
2474
2511
  textGap: nodeOptions.textGap,
2475
2512
  });
2476
2513
  if (nodeOptions.textExtraDraw) {
2477
- nodeOptions.textExtraDraw(node, {
2514
+ nodeOptions.textExtraDraw.bind(this)(node, {
2478
2515
  ...nodeOptions,
2479
2516
  radius,
2480
2517
  alpha,
@@ -2485,7 +2522,7 @@ function getDrawNode(nodeRenders, textRenders, state) {
2485
2522
  textShiftY,
2486
2523
  textWeight,
2487
2524
  textWidth,
2488
- }, state);
2525
+ });
2489
2526
  }
2490
2527
  });
2491
2528
  }
@@ -2928,7 +2965,7 @@ function initCollideForce(forceUpdate) {
2928
2965
  maxWidth: width,
2929
2966
  textStyle: nodeOptions.textStyle,
2930
2967
  textWeight: nodeOptions.textWeight,
2931
- });
2968
+ }).lines;
2932
2969
  height =
2933
2970
  lines.length * nodeOptions.textSize +
2934
2971
  (lines.length - 1) * nodeOptions.textGap +
@@ -3013,6 +3050,7 @@ class GraphCanvas {
3013
3050
  draw;
3014
3051
  eventAbortController;
3015
3052
  cachedNodeText = {};
3053
+ cachedTextNodeParameters = {};
3016
3054
  linkOptionsCache = {};
3017
3055
  nodeOptionsCache = {};
3018
3056
  isDragging = false;
@@ -3104,6 +3142,7 @@ class GraphCanvas {
3104
3142
  if (options.nodeSettings) {
3105
3143
  this.nodeSettings = nodeSettingsGetter(options.nodeSettings, this.nodeSettings);
3106
3144
  this.cachedNodeText = {};
3145
+ this.cachedTextNodeParameters = {};
3107
3146
  this.nodeOptionsCache = {};
3108
3147
  initCollideForce.call(this, true);
3109
3148
  }
@@ -3120,6 +3159,7 @@ class GraphCanvas {
3120
3159
  this.nodeOptionsCache = {};
3121
3160
  this.linkOptionsCache = {};
3122
3161
  this.cachedNodeText = {};
3162
+ this.cachedTextNodeParameters = {};
3123
3163
  }
3124
3164
  tick() {
3125
3165
  if (!this.simulationWorking && !this.highlightWorking)
@@ -3151,7 +3191,7 @@ class GraphCanvas {
3151
3191
  }
3152
3192
  this.clearHTMLElements();
3153
3193
  this.clearState();
3154
- this.clearDataDependencies();
3194
+ this.clearCache();
3155
3195
  }
3156
3196
  clearHTMLElements() {
3157
3197
  this.root.replaceChildren();
@@ -3177,13 +3217,8 @@ class GraphCanvas {
3177
3217
  this.highlightWorking = false;
3178
3218
  this.highlightDrawing = false;
3179
3219
  }
3180
- clearDataDependencies() {
3181
- this.cachedNodeText = {};
3182
- this.nodeOptionsCache = {};
3183
- this.linkOptionsCache = {};
3184
- }
3185
3220
  updateData(alpha) {
3186
- this.clearDataDependencies();
3221
+ this.clearCache();
3187
3222
  if (this.simulation) {
3188
3223
  initCollideForce.call(this, false);
3189
3224
  this.simulation