@antv/layout 0.2.2 → 0.2.3

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.
Files changed (84) hide show
  1. package/dist/layout.min.js +1 -1
  2. package/dist/layout.min.js.map +1 -1
  3. package/es/layout/comboCombined.js +2 -18
  4. package/es/layout/comboCombined.js.map +1 -1
  5. package/lib/layout/comboCombined.js +2 -18
  6. package/lib/layout/comboCombined.js.map +1 -1
  7. package/package.json +2 -1
  8. package/src/index.ts +7 -0
  9. package/src/layout/base.ts +54 -0
  10. package/src/layout/circular.ts +369 -0
  11. package/src/layout/comboCombined.ts +390 -0
  12. package/src/layout/comboForce.ts +873 -0
  13. package/src/layout/concentric.ts +289 -0
  14. package/src/layout/constants.ts +21 -0
  15. package/src/layout/dagre/graph.ts +104 -0
  16. package/src/layout/dagre/index.ts +31 -0
  17. package/src/layout/dagre/src/acyclic.ts +58 -0
  18. package/src/layout/dagre/src/add-border-segments.ts +47 -0
  19. package/src/layout/dagre/src/coordinate-system.ts +77 -0
  20. package/src/layout/dagre/src/data/list.ts +60 -0
  21. package/src/layout/dagre/src/debug.ts +30 -0
  22. package/src/layout/dagre/src/greedy-fas.ts +144 -0
  23. package/src/layout/dagre/src/layout.ts +580 -0
  24. package/src/layout/dagre/src/nesting-graph.ts +143 -0
  25. package/src/layout/dagre/src/normalize.ts +96 -0
  26. package/src/layout/dagre/src/order/add-subgraph-constraints.ts +29 -0
  27. package/src/layout/dagre/src/order/barycenter.ts +26 -0
  28. package/src/layout/dagre/src/order/build-layer-graph.ts +82 -0
  29. package/src/layout/dagre/src/order/cross-count.ts +77 -0
  30. package/src/layout/dagre/src/order/index.ts +105 -0
  31. package/src/layout/dagre/src/order/init-data-order.ts +27 -0
  32. package/src/layout/dagre/src/order/init-order.ts +56 -0
  33. package/src/layout/dagre/src/order/resolve-conflicts.ts +152 -0
  34. package/src/layout/dagre/src/order/sort-subgraph.ts +105 -0
  35. package/src/layout/dagre/src/order/sort.ts +76 -0
  36. package/src/layout/dagre/src/parent-dummy-chains.ts +102 -0
  37. package/src/layout/dagre/src/position/bk.ts +494 -0
  38. package/src/layout/dagre/src/position/index.ts +82 -0
  39. package/src/layout/dagre/src/rank/feasible-tree.ts +165 -0
  40. package/src/layout/dagre/src/rank/index.ts +54 -0
  41. package/src/layout/dagre/src/rank/network-simplex.ts +225 -0
  42. package/src/layout/dagre/src/rank/util.ts +157 -0
  43. package/src/layout/dagre/src/util.ts +308 -0
  44. package/src/layout/dagre.ts +423 -0
  45. package/src/layout/dagreCompound.ts +518 -0
  46. package/src/layout/er/core.ts +117 -0
  47. package/src/layout/er/forceGrid.ts +95 -0
  48. package/src/layout/er/grid.ts +185 -0
  49. package/src/layout/er/index.ts +68 -0
  50. package/src/layout/er/mysqlWorkbench.ts +345 -0
  51. package/src/layout/er/type.ts +39 -0
  52. package/src/layout/force/force-in-a-box.ts +400 -0
  53. package/src/layout/force/force.ts +391 -0
  54. package/src/layout/force/index.ts +1 -0
  55. package/src/layout/forceAtlas2/body.ts +115 -0
  56. package/src/layout/forceAtlas2/index.ts +556 -0
  57. package/src/layout/forceAtlas2/quad.ts +115 -0
  58. package/src/layout/forceAtlas2/quadTree.ts +107 -0
  59. package/src/layout/fruchterman.ts +361 -0
  60. package/src/layout/gForce.ts +487 -0
  61. package/src/layout/gpu/fruchterman.ts +314 -0
  62. package/src/layout/gpu/fruchtermanShader.ts +204 -0
  63. package/src/layout/gpu/gForce.ts +406 -0
  64. package/src/layout/gpu/gForceShader.ts +221 -0
  65. package/src/layout/grid.ts +391 -0
  66. package/src/layout/index.ts +45 -0
  67. package/src/layout/layout.ts +75 -0
  68. package/src/layout/mds.ts +140 -0
  69. package/src/layout/radial/index.ts +1 -0
  70. package/src/layout/radial/mds.ts +51 -0
  71. package/src/layout/radial/radial.ts +500 -0
  72. package/src/layout/radial/radialNonoverlapForce.ts +189 -0
  73. package/src/layout/random.ts +75 -0
  74. package/src/layout/types.ts +421 -0
  75. package/src/registy/index.ts +43 -0
  76. package/src/util/array.ts +1 -0
  77. package/src/util/function.ts +64 -0
  78. package/src/util/gpu.ts +254 -0
  79. package/src/util/index.ts +6 -0
  80. package/src/util/math.ts +158 -0
  81. package/src/util/number.ts +8 -0
  82. package/src/util/object.ts +28 -0
  83. package/src/util/string.ts +18 -0
  84. package/CHANGELOG.md +0 -88
@@ -0,0 +1,75 @@
1
+ /**
2
+ * @fileOverview random layout
3
+ * @author shiwu.wyy@antfin.com
4
+ */
5
+
6
+ import { PointTuple, OutNode, Edge, RandomLayoutOptions } from "./types";
7
+ import { Base } from "./base";
8
+
9
+ /**
10
+ * 随机布局
11
+ */
12
+ export class RandomLayout extends Base {
13
+ /** 布局中心 */
14
+ public center: PointTuple = [0, 0];
15
+
16
+ /** 宽度 */
17
+ public width: number = 300;
18
+
19
+ /** 高度 */
20
+ public height: number = 300;
21
+
22
+ public nodes: OutNode[] = [];
23
+
24
+ public edges: Edge[] = [];
25
+
26
+ /** 迭代结束的回调函数 */
27
+ public onLayoutEnd: () => void = () => {};
28
+
29
+ constructor(options?: RandomLayoutOptions) {
30
+ super();
31
+ this.updateCfg(options);
32
+ }
33
+
34
+ public getDefaultCfg() {
35
+ return {
36
+ center: [0, 0],
37
+ width: 300,
38
+ height: 300
39
+ };
40
+ }
41
+
42
+ /**
43
+ * 执行布局
44
+ */
45
+ public execute() {
46
+ const self = this;
47
+ const nodes = self.nodes;
48
+ const layoutScale = 0.9;
49
+ const center = self.center;
50
+ if (!self.width && typeof window !== "undefined") {
51
+ self.width = window.innerWidth;
52
+ }
53
+ if (!self.height && typeof window !== "undefined") {
54
+ self.height = window.innerHeight;
55
+ }
56
+
57
+ if (nodes) {
58
+ nodes.forEach((node) => {
59
+ node.x = (Math.random() - 0.5) * layoutScale * self.width + center[0];
60
+ node.y = (Math.random() - 0.5) * layoutScale * self.height + center[1];
61
+ });
62
+ }
63
+
64
+ if (self.onLayoutEnd) self.onLayoutEnd();
65
+
66
+ return {
67
+ nodes,
68
+ edges: this.edges
69
+ };
70
+ }
71
+
72
+ public getType() {
73
+ return "random";
74
+ }
75
+ }
@@ -0,0 +1,421 @@
1
+ import { Base } from "./base";
2
+
3
+ export interface Node {
4
+ id: string;
5
+ }
6
+
7
+ export interface OutNode extends Node {
8
+ x: number;
9
+ y: number;
10
+ comboId?: string;
11
+ layer?: number; // dagre布局中指定的层级
12
+ _order?: number; // dagre布局中层内排序结果,用于增量布局
13
+ layout?: boolean;
14
+ size?: number | number[] | undefined;
15
+ }
16
+
17
+ export interface Edge {
18
+ source: string;
19
+ target: string;
20
+ }
21
+
22
+ export interface Combo {
23
+ id: string;
24
+ parentId?: string;
25
+ x?: number;
26
+ y?: number;
27
+ name?: string | number;
28
+ cx?: number;
29
+ cy?: number;
30
+ count?: number;
31
+ depth?: number;
32
+ children?: any[];
33
+ empty?: boolean;
34
+ minX?: number;
35
+ maxX?: number;
36
+ minY?: number;
37
+ maxY?: number;
38
+ size?: number;
39
+ r?: number;
40
+ itemType?: string;
41
+ }
42
+
43
+ export interface Model {
44
+ nodes?: Node[];
45
+ edges?: Edge[];
46
+ combos?: Combo[];
47
+ comboEdges?: Edge[];
48
+ hiddenNodes?: Node[];
49
+ hiddenEdges?: Edge[];
50
+ hiddenCombos?: Combo[];
51
+ }
52
+
53
+ export interface OutModel extends Model {
54
+ nodes?: OutNode[];
55
+ }
56
+
57
+ export type PointTuple = [number, number];
58
+
59
+ export interface Size {
60
+ width: number;
61
+ height: number;
62
+ }
63
+
64
+ export type IndexMap = {
65
+ [key: string]: number;
66
+ };
67
+
68
+ export type Matrix = number[];
69
+
70
+ export type Point = {
71
+ x: number;
72
+ y: number;
73
+ };
74
+
75
+ export interface ComboTree {
76
+ id: string;
77
+ children?: ComboTree[];
78
+ depth?: number;
79
+ parentId?: string;
80
+ itemType?: "node" | "combo";
81
+ [key: string]: unknown;
82
+ }
83
+ export interface ComboConfig {
84
+ id: string;
85
+ parentId?: string;
86
+ children?: ComboTree[];
87
+ depth?: number;
88
+ }
89
+
90
+ export interface CircularLayoutOptions {
91
+ type: "circular";
92
+ center?: PointTuple;
93
+ width?: number;
94
+ height?: number;
95
+ radius?: number | null;
96
+ startRadius?: number | null;
97
+ endRadius?: number | null;
98
+ clockwise?: boolean;
99
+ divisions?: number;
100
+ ordering?: "topology" | "topology-directed" | "degree" | null;
101
+ angleRatio?: number;
102
+ workerEnabled?: boolean;
103
+ startAngle?: number;
104
+ endAngle?: number;
105
+ onLayoutEnd?: () => void;
106
+ }
107
+
108
+ export interface ComboForceLayoutOptions {
109
+ type: "comboForce";
110
+ center?: PointTuple;
111
+ maxIteration?: number;
112
+ linkDistance?: number | ((d?: unknown) => number);
113
+ nodeStrength?: number | ((d?: unknown) => number);
114
+ edgeStrength?: number | ((d?: unknown) => number);
115
+ preventOverlap?: boolean;
116
+ preventNodeOverlap?: boolean;
117
+ preventComboOverlap?: boolean;
118
+ collideStrength?: number | undefined;
119
+ nodeCollideStrength?: number | undefined;
120
+ comboCollideStrength?: number | undefined;
121
+ nodeSize?: number | number[] | ((d?: unknown) => number) | undefined;
122
+ nodeSpacing?: ((d?: unknown) => number) | number | undefined;
123
+ comboSpacing?: ((d?: unknown) => number) | number | undefined;
124
+ comboPadding?: ((d?: unknown) => number) | number | number[] | undefined;
125
+ alpha?: number;
126
+ alphaDecay?: number;
127
+ alphaMin?: number;
128
+ onTick?: () => void;
129
+ onLayoutEnd?: () => void;
130
+ gravity?: number;
131
+ comboGravity?: number;
132
+ optimizeRangeFactor?: number;
133
+ depthAttractiveForceScale?: number;
134
+ depthRepulsiveForceScale?: number;
135
+ velocityDecay?: number;
136
+ workerEnabled?: boolean;
137
+ }
138
+ export interface ComboCombinedLayoutOptions {
139
+ type: "comboConcentricForce";
140
+ center?: PointTuple;
141
+ nodeSize?: number | number[] | ((d?: any) => number) | undefined;
142
+ spacing?: number | number[] | ((d?: any) => number) | undefined;
143
+ comboPadding?: ((d?: unknown) => number) | number | number[] | undefined;
144
+ comboTrees?: ComboTree[];
145
+ outerLayout?: Base;
146
+ innerLayout?: Base;
147
+ }
148
+
149
+ export interface ConcentricLayoutOptions {
150
+ type: "concentric";
151
+ center?: PointTuple;
152
+ preventOverlap?: boolean;
153
+ nodeSize?: number | PointTuple;
154
+ minNodeSpacing?: number;
155
+ sweep?: number;
156
+ equidistant?: boolean;
157
+ startAngle?: number;
158
+ clockwise?: boolean;
159
+ maxLevelDiff?: number;
160
+ sortBy?: string;
161
+ workerEnabled?: boolean;
162
+ width?: number;
163
+ height?: number;
164
+ onLayoutEnd?: () => void;
165
+ }
166
+
167
+ export interface DagreLayoutOptions {
168
+ type: "dagre";
169
+ rankdir?: "TB" | "BT" | "LR" | "RL";
170
+ align?: "UL" | "UR" | "DL" | "DR";
171
+ begin?: PointTuple;
172
+ nodeSize?: number | number[] | undefined;
173
+ nodesep?: number;
174
+ ranksep?: number;
175
+ nodesepFunc?: ((d?: any) => number) | undefined;
176
+ ranksepFunc?: ((d?: any) => number) | undefined;
177
+ controlPoints?: boolean;
178
+ sortByCombo?: boolean;
179
+ workerEnabled?: boolean;
180
+ onLayoutEnd?: () => void;
181
+ edgeLabelSpace?: boolean;
182
+ nodeOrder?: string[];
183
+ }
184
+
185
+ export interface DagreCompoundLayoutOptions {
186
+ type?: "dagreCompound";
187
+ rankdir?: "TB" | "BT" | "LR" | "RL";
188
+ align?: "UL" | "UR" | "DL" | "DR";
189
+ begin?: PointTuple;
190
+ nodeSize?: number | number[] | undefined;
191
+ nodesep?: number;
192
+ ranksep?: number;
193
+ controlPoints?: boolean;
194
+ anchorPoint?: boolean;
195
+ settings?: any;
196
+ onLayoutEnd?: () => void;
197
+ }
198
+
199
+ export interface FruchtermanLayoutOptions {
200
+ type: "fruchterman";
201
+ center?: PointTuple;
202
+ maxIteration?: number;
203
+ width?: number;
204
+ height?: number;
205
+ gravity?: number;
206
+ speed?: number;
207
+ clustering?: boolean;
208
+ clusterGravity?: number;
209
+ workerEnabled?: boolean;
210
+ gpuEnabled?: boolean;
211
+ onLayoutEnd?: () => void;
212
+ }
213
+
214
+ export interface GForceLayoutOptions {
215
+ type?: "gForce";
216
+ center?: PointTuple;
217
+ width?: number;
218
+ height?: number;
219
+ linkDistance?: number | ((edge?: any, source?: any, target?: any) => number) | undefined;
220
+ nodeStrength?: number | ((d?: any) => number) | undefined;
221
+ edgeStrength?: number | ((d?: any) => number) | undefined;
222
+ preventOverlap?: boolean;
223
+ nodeSize?: number | number[] | ((d?: any) => number) | undefined;
224
+ nodeSpacing?: number | number[] | ((d?: any) => number) | undefined;
225
+ minMovement?: number;
226
+ maxIteration?: number;
227
+ damping?: number;
228
+ maxSpeed?: number;
229
+ coulombDisScale?: number;
230
+ getMass?: ((d?: any) => number) | undefined;
231
+ getCenter?: ((d?: any, degree?: number) => number[]) | undefined;
232
+ gravity?: number;
233
+ factor?: number;
234
+ tick?: () => void;
235
+ onLayoutEnd?: () => void;
236
+ workerEnabled?: boolean;
237
+ gpuEnabled?: boolean;
238
+ }
239
+
240
+ type INode = OutNode & {
241
+ degree: number;
242
+ size: number | PointTuple;
243
+ };
244
+
245
+ export interface GridLayoutOptions {
246
+ type: "grid";
247
+ width?: number;
248
+ height?: number;
249
+ begin?: PointTuple;
250
+ preventOverlap?: boolean;
251
+ nodeSize?: number | number[];
252
+ preventOverlapPadding?: number;
253
+ condense?: boolean;
254
+ rows?: number;
255
+ cols?: number;
256
+ sortBy?: string;
257
+ workerEnabled?: boolean;
258
+ position?: ((node: INode) => { row?: number; col?: number }) | undefined;
259
+ onLayoutEnd?: () => void;
260
+ }
261
+
262
+ export interface MDSLayoutOptions {
263
+ type: "mds";
264
+ center?: PointTuple;
265
+ linkDistance?: number;
266
+ workerEnabled?: boolean;
267
+ onLayoutEnd?: () => void;
268
+ }
269
+
270
+ export interface RandomLayoutOptions {
271
+ type: "random";
272
+ center?: PointTuple;
273
+ width?: number;
274
+ height?: number;
275
+ workerEnabled?: boolean;
276
+ onLayoutEnd?: () => void;
277
+ }
278
+
279
+ export interface ForceLayoutOptions {
280
+ type: "force";
281
+ center?: PointTuple;
282
+ linkDistance?: number | ((d?: any) => number) | undefined;
283
+ edgeStrength?: number | ((d?: any) => number) | undefined;
284
+ nodeStrength?: number | ((d?: any) => number) | undefined;
285
+ preventOverlap?: boolean;
286
+ collideStrength?: number;
287
+ nodeSize?: number | number[] | ((d?: any) => number) | undefined;
288
+ nodeSpacing?: number | number[] | ((d?: any) => number) | undefined;
289
+ alpha?: number;
290
+ alphaDecay?: number;
291
+ alphaMin?: number;
292
+ clustering?: boolean;
293
+ clusterNodeStrength?: number;
294
+ clusterEdgeStrength?: number;
295
+ clusterEdgeDistance?: number;
296
+ clusterNodeSize?: number;
297
+ clusterFociStrength?: number;
298
+ forceSimulation?: any;
299
+ tick?: () => void;
300
+ onLayoutEnd?: () => void;
301
+ workerEnabled?: boolean;
302
+ }
303
+
304
+ export interface RadialLayoutOptions {
305
+ type: "radial";
306
+ center?: PointTuple;
307
+ width?: number;
308
+ height?: number;
309
+ linkDistance?: number;
310
+ maxIteration?: number;
311
+ focusNode?: string | Node | null;
312
+ unitRadius?: number | null;
313
+ preventOverlap?: boolean;
314
+ nodeSize?: number | number[] | undefined;
315
+ nodeSpacing?: number | Function | undefined;
316
+ maxPreventOverlapIteration?: number;
317
+ strictRadial?: boolean;
318
+ sortBy?: string | undefined;
319
+ sortStrength?: number;
320
+ workerEnabled?: boolean;
321
+ onLayoutEnd?: () => void;
322
+ }
323
+
324
+ export interface FruchtermanGPULayoutOptions {
325
+ type: "fruchterman-gpu";
326
+ center?: PointTuple;
327
+ width?: number;
328
+ height?: number;
329
+ maxIteration?: number;
330
+ gravity?: number;
331
+ speed?: number;
332
+ clustering?: boolean;
333
+ clusterGravity?: number;
334
+ workerEnabled?: boolean;
335
+ gpuEnabled?: boolean;
336
+ onLayoutEnd?: () => void;
337
+ }
338
+
339
+ export interface GForceGPULayoutOptions {
340
+ type: "gForce-gpu";
341
+ center?: PointTuple;
342
+ linkDistance?: number | ((d?: any) => number) | undefined;
343
+ nodeStrength?: number | ((d?: any) => number) | undefined;
344
+ edgeStrength?: number | ((d?: any) => number) | undefined;
345
+ minMovement?: number;
346
+ maxIteration?: number;
347
+ damping?: number;
348
+ maxSpeed?: number;
349
+ coulombDisScale?: number;
350
+ getMass?: ((d?: any) => number) | undefined;
351
+ getCenter?: ((d?: any, degree?: number) => number[]) | undefined;
352
+ gravity?: number;
353
+ onLayoutEnd?: () => void;
354
+ workerEnabled?: boolean;
355
+ gpuEnabled?: boolean;
356
+ }
357
+
358
+
359
+ export interface ForceAtlas2LayoutOptions {
360
+ type: "forceAtlas2";
361
+ center?: PointTuple;
362
+ width?: number;
363
+ height?: number;
364
+ workerEnabled?: boolean;
365
+ onLayoutEnd?: () => void;
366
+ tick?: () => void;
367
+ kr?: number;
368
+ kg?: number;
369
+ ks?: number;
370
+ ksmax?: number;
371
+ tao?: number;
372
+ maxIteration?: number;
373
+ mode?: 'normal' | 'linlog';
374
+ preventOverlap?: boolean;
375
+ dissuadeHubs?: boolean;
376
+ barnesHut?: boolean;
377
+ prune?: boolean;
378
+ }
379
+
380
+ export interface ERLayoutOptions {
381
+ type: "er";
382
+ width?: number;
383
+ height?: number;
384
+ nodeMinGap?: number;
385
+ }
386
+ export namespace ILayout {
387
+ export type LayoutTypes =
388
+ | "grid"
389
+ | "random"
390
+ | "force"
391
+ | "circular"
392
+ | "dagre"
393
+ | "radial"
394
+ | "concentric"
395
+ | "mds"
396
+ | "fruchterman"
397
+ | "fruchterman-gpu"
398
+ | "gForce"
399
+ | "gForce-gpu"
400
+ | "comboForce"
401
+ | "forceAtlas2"
402
+ | "er";
403
+
404
+ export type LayoutOptions =
405
+ | GridLayoutOptions
406
+ | RandomLayoutOptions
407
+ | ForceLayoutOptions
408
+ | CircularLayoutOptions
409
+ | DagreLayoutOptions
410
+ | RadialLayoutOptions
411
+ | ConcentricLayoutOptions
412
+ | MDSLayoutOptions
413
+ | FruchtermanLayoutOptions
414
+ | FruchtermanGPULayoutOptions
415
+ | GForceLayoutOptions
416
+ | GForceGPULayoutOptions
417
+ | ComboForceLayoutOptions
418
+ | ComboCombinedLayoutOptions
419
+ | ForceAtlas2LayoutOptions
420
+ | ERLayoutOptions;
421
+ }
@@ -0,0 +1,43 @@
1
+ import { Base } from "../layout/base";
2
+ import { isObject } from "../util";
3
+
4
+ const map: Map<string, any> = new Map();
5
+
6
+ export const registerLayout = (name: string, layoutOverride: any) => {
7
+ if (map.get(name)) {
8
+ console.warn(`The layout with the name ${name} exists already, it will be overridden`);
9
+ }
10
+ if (isObject(layoutOverride)) {
11
+ // tslint:disable-next-line: max-classes-per-file
12
+ class GLayout extends Base {
13
+ constructor(cfg: any) {
14
+ super();
15
+ const self = this as any;
16
+ const props: any = {};
17
+ const defaultCfg = self.getDefaultCfg();
18
+ Object.assign(props, defaultCfg, layoutOverride, cfg as unknown);
19
+ Object.keys(props).forEach((key: string) => {
20
+ const value = props[key];
21
+ self[key] = value;
22
+ });
23
+ }
24
+ }
25
+ map.set(name, GLayout);
26
+ } else {
27
+ map.set(name, layoutOverride);
28
+ }
29
+ return map.get(name);
30
+ };
31
+
32
+ export const unRegisterLayout = (name: string) => {
33
+ if (map.has(name)) {
34
+ map.delete(name);
35
+ }
36
+ };
37
+
38
+ export const getLayoutByName = (name: string) => {
39
+ if (map.has(name)) {
40
+ return map.get(name);
41
+ }
42
+ return null;
43
+ };
@@ -0,0 +1 @@
1
+ export const isArray = Array.isArray;
@@ -0,0 +1,64 @@
1
+ import { isArray, isObject } from ".";
2
+ import { isNumber } from "./number";
3
+
4
+ export const isFunction = (val: unknown): val is Function =>
5
+ typeof val === 'function';
6
+
7
+
8
+ export const getFunc = (
9
+ value: number,
10
+ defaultValue: number,
11
+ func?: ((d?: any) => number) | undefined,
12
+ ): Function => {
13
+ let resultFunc;
14
+ if (func) {
15
+ resultFunc = func;
16
+ } else if (isNumber(value)) {
17
+ resultFunc = () => value;
18
+ } else {
19
+ resultFunc = () => defaultValue;
20
+ }
21
+ return resultFunc;
22
+ };
23
+
24
+ export const getFuncByUnknownType = (
25
+ defaultValue: number,
26
+ value?: number | number[] | { width: number, height: number } | ((d?: any) => number) | undefined,
27
+ resultIsNumber: boolean = true
28
+ ): (d?: any) => number | number[] => {
29
+ if (!value && value !== 0) {
30
+ return (d) => {
31
+ if (d.size) {
32
+ if (isArray(d.size)) return d.size[0] > d.size[1] ? d.size[0] : d.size[1];
33
+ if (isObject(d.size)) return d.size.width > d.size.height ? d.size.width : d.size.height;
34
+ return d.size;
35
+ }
36
+ return defaultValue;
37
+ };
38
+ }
39
+ if (isFunction(value)) {
40
+ return value;
41
+ }
42
+ if (isNumber(value)) {
43
+ return () => value;
44
+ }
45
+ if (isArray(value)) {
46
+ return () => {
47
+ if (resultIsNumber) {
48
+ const max = Math.max(...(value as number[]));
49
+ return isNaN(max) ? defaultValue : max;
50
+ }
51
+ return value;
52
+ };
53
+ }
54
+ if (isObject(value)) {
55
+ return () => {
56
+ if (resultIsNumber) {
57
+ const max = Math.max(value.width, value.height);
58
+ return isNaN(max) ? defaultValue : max;
59
+ }
60
+ return [value.width, value.height];
61
+ };
62
+ }
63
+ return () => defaultValue;
64
+ };