@antv/layout 0.2.2 → 0.2.5

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 (90) 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 +6 -21
  4. package/es/layout/comboCombined.js.map +1 -1
  5. package/es/layout/grid.js +2 -0
  6. package/es/layout/grid.js.map +1 -1
  7. package/es/layout/types.d.ts +7 -3
  8. package/lib/layout/comboCombined.js +6 -21
  9. package/lib/layout/comboCombined.js.map +1 -1
  10. package/lib/layout/grid.js +2 -0
  11. package/lib/layout/grid.js.map +1 -1
  12. package/lib/layout/types.d.ts +7 -3
  13. package/package.json +2 -1
  14. package/src/index.ts +7 -0
  15. package/src/layout/base.ts +54 -0
  16. package/src/layout/circular.ts +369 -0
  17. package/src/layout/comboCombined.ts +391 -0
  18. package/src/layout/comboForce.ts +873 -0
  19. package/src/layout/concentric.ts +289 -0
  20. package/src/layout/constants.ts +21 -0
  21. package/src/layout/dagre/graph.ts +104 -0
  22. package/src/layout/dagre/index.ts +31 -0
  23. package/src/layout/dagre/src/acyclic.ts +58 -0
  24. package/src/layout/dagre/src/add-border-segments.ts +47 -0
  25. package/src/layout/dagre/src/coordinate-system.ts +77 -0
  26. package/src/layout/dagre/src/data/list.ts +60 -0
  27. package/src/layout/dagre/src/debug.ts +30 -0
  28. package/src/layout/dagre/src/greedy-fas.ts +144 -0
  29. package/src/layout/dagre/src/layout.ts +580 -0
  30. package/src/layout/dagre/src/nesting-graph.ts +143 -0
  31. package/src/layout/dagre/src/normalize.ts +96 -0
  32. package/src/layout/dagre/src/order/add-subgraph-constraints.ts +29 -0
  33. package/src/layout/dagre/src/order/barycenter.ts +26 -0
  34. package/src/layout/dagre/src/order/build-layer-graph.ts +82 -0
  35. package/src/layout/dagre/src/order/cross-count.ts +77 -0
  36. package/src/layout/dagre/src/order/index.ts +105 -0
  37. package/src/layout/dagre/src/order/init-data-order.ts +27 -0
  38. package/src/layout/dagre/src/order/init-order.ts +56 -0
  39. package/src/layout/dagre/src/order/resolve-conflicts.ts +152 -0
  40. package/src/layout/dagre/src/order/sort-subgraph.ts +105 -0
  41. package/src/layout/dagre/src/order/sort.ts +76 -0
  42. package/src/layout/dagre/src/parent-dummy-chains.ts +102 -0
  43. package/src/layout/dagre/src/position/bk.ts +494 -0
  44. package/src/layout/dagre/src/position/index.ts +82 -0
  45. package/src/layout/dagre/src/rank/feasible-tree.ts +165 -0
  46. package/src/layout/dagre/src/rank/index.ts +54 -0
  47. package/src/layout/dagre/src/rank/network-simplex.ts +225 -0
  48. package/src/layout/dagre/src/rank/util.ts +157 -0
  49. package/src/layout/dagre/src/util.ts +308 -0
  50. package/src/layout/dagre.ts +423 -0
  51. package/src/layout/dagreCompound.ts +518 -0
  52. package/src/layout/er/core.ts +117 -0
  53. package/src/layout/er/forceGrid.ts +95 -0
  54. package/src/layout/er/grid.ts +185 -0
  55. package/src/layout/er/index.ts +68 -0
  56. package/src/layout/er/mysqlWorkbench.ts +345 -0
  57. package/src/layout/er/type.ts +39 -0
  58. package/src/layout/force/force-in-a-box.ts +400 -0
  59. package/src/layout/force/force.ts +391 -0
  60. package/src/layout/force/index.ts +1 -0
  61. package/src/layout/forceAtlas2/body.ts +115 -0
  62. package/src/layout/forceAtlas2/index.ts +556 -0
  63. package/src/layout/forceAtlas2/quad.ts +115 -0
  64. package/src/layout/forceAtlas2/quadTree.ts +107 -0
  65. package/src/layout/fruchterman.ts +361 -0
  66. package/src/layout/gForce.ts +487 -0
  67. package/src/layout/gpu/fruchterman.ts +314 -0
  68. package/src/layout/gpu/fruchtermanShader.ts +204 -0
  69. package/src/layout/gpu/gForce.ts +406 -0
  70. package/src/layout/gpu/gForceShader.ts +221 -0
  71. package/src/layout/grid.ts +393 -0
  72. package/src/layout/index.ts +45 -0
  73. package/src/layout/layout.ts +75 -0
  74. package/src/layout/mds.ts +140 -0
  75. package/src/layout/radial/index.ts +1 -0
  76. package/src/layout/radial/mds.ts +51 -0
  77. package/src/layout/radial/radial.ts +500 -0
  78. package/src/layout/radial/radialNonoverlapForce.ts +189 -0
  79. package/src/layout/random.ts +75 -0
  80. package/src/layout/types.ts +425 -0
  81. package/src/registy/index.ts +43 -0
  82. package/src/util/array.ts +1 -0
  83. package/src/util/function.ts +64 -0
  84. package/src/util/gpu.ts +254 -0
  85. package/src/util/index.ts +6 -0
  86. package/src/util/math.ts +158 -0
  87. package/src/util/number.ts +8 -0
  88. package/src/util/object.ts +28 -0
  89. package/src/util/string.ts +18 -0
  90. 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,425 @@
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
+ controlPoints?: boolean;
176
+ sortByCombo?: boolean;
177
+ workerEnabled?: boolean;
178
+ edgeLabelSpace?: boolean;
179
+ nodeOrder?: string[];
180
+ preset?: {
181
+ nodes: OutNode[],
182
+ edges: any[],
183
+ };
184
+ onLayoutEnd?: () => void;
185
+ nodesepFunc?: ((d?: any) => number) | undefined;
186
+ ranksepFunc?: ((d?: any) => number) | undefined;
187
+ }
188
+
189
+ export interface DagreCompoundLayoutOptions {
190
+ type?: "dagreCompound";
191
+ rankdir?: "TB" | "BT" | "LR" | "RL";
192
+ align?: "UL" | "UR" | "DL" | "DR";
193
+ begin?: PointTuple;
194
+ nodeSize?: number | number[] | undefined;
195
+ nodesep?: number;
196
+ ranksep?: number;
197
+ controlPoints?: boolean;
198
+ anchorPoint?: boolean;
199
+ settings?: any;
200
+ onLayoutEnd?: () => void;
201
+ }
202
+
203
+ export interface FruchtermanLayoutOptions {
204
+ type: "fruchterman";
205
+ center?: PointTuple;
206
+ maxIteration?: number;
207
+ width?: number;
208
+ height?: number;
209
+ gravity?: number;
210
+ speed?: number;
211
+ clustering?: boolean;
212
+ clusterGravity?: number;
213
+ workerEnabled?: boolean;
214
+ gpuEnabled?: boolean;
215
+ onLayoutEnd?: () => void;
216
+ }
217
+
218
+ export interface GForceLayoutOptions {
219
+ type?: "gForce";
220
+ center?: PointTuple;
221
+ width?: number;
222
+ height?: number;
223
+ linkDistance?: number | ((edge?: any, source?: any, target?: any) => number) | undefined;
224
+ nodeStrength?: number | ((d?: any) => number) | undefined;
225
+ edgeStrength?: number | ((d?: any) => number) | undefined;
226
+ preventOverlap?: boolean;
227
+ nodeSize?: number | number[] | ((d?: any) => number) | undefined;
228
+ nodeSpacing?: number | number[] | ((d?: any) => number) | undefined;
229
+ minMovement?: number;
230
+ maxIteration?: number;
231
+ damping?: number;
232
+ maxSpeed?: number;
233
+ coulombDisScale?: number;
234
+ getMass?: ((d?: any) => number) | undefined;
235
+ getCenter?: ((d?: any, degree?: number) => number[]) | undefined;
236
+ gravity?: number;
237
+ factor?: number;
238
+ tick?: () => void;
239
+ onLayoutEnd?: () => void;
240
+ workerEnabled?: boolean;
241
+ gpuEnabled?: boolean;
242
+ }
243
+
244
+ type INode = OutNode & {
245
+ degree: number;
246
+ size: number | PointTuple;
247
+ };
248
+
249
+ export interface GridLayoutOptions {
250
+ type: "grid";
251
+ width?: number;
252
+ height?: number;
253
+ begin?: PointTuple;
254
+ preventOverlap?: boolean;
255
+ nodeSize?: number | number[];
256
+ preventOverlapPadding?: number;
257
+ condense?: boolean;
258
+ rows?: number;
259
+ cols?: number;
260
+ sortBy?: string;
261
+ workerEnabled?: boolean;
262
+ position?: ((node: INode) => { row?: number; col?: number }) | undefined;
263
+ onLayoutEnd?: () => void;
264
+ }
265
+
266
+ export interface MDSLayoutOptions {
267
+ type: "mds";
268
+ center?: PointTuple;
269
+ linkDistance?: number;
270
+ workerEnabled?: boolean;
271
+ onLayoutEnd?: () => void;
272
+ }
273
+
274
+ export interface RandomLayoutOptions {
275
+ type: "random";
276
+ center?: PointTuple;
277
+ width?: number;
278
+ height?: number;
279
+ workerEnabled?: boolean;
280
+ onLayoutEnd?: () => void;
281
+ }
282
+
283
+ export interface ForceLayoutOptions {
284
+ type: "force";
285
+ center?: PointTuple;
286
+ linkDistance?: number | ((d?: any) => number) | undefined;
287
+ edgeStrength?: number | ((d?: any) => number) | undefined;
288
+ nodeStrength?: number | ((d?: any) => number) | undefined;
289
+ preventOverlap?: boolean;
290
+ collideStrength?: number;
291
+ nodeSize?: number | number[] | ((d?: any) => number) | undefined;
292
+ nodeSpacing?: number | number[] | ((d?: any) => number) | undefined;
293
+ alpha?: number;
294
+ alphaDecay?: number;
295
+ alphaMin?: number;
296
+ clustering?: boolean;
297
+ clusterNodeStrength?: number;
298
+ clusterEdgeStrength?: number;
299
+ clusterEdgeDistance?: number;
300
+ clusterNodeSize?: number;
301
+ clusterFociStrength?: number;
302
+ forceSimulation?: any;
303
+ tick?: () => void;
304
+ onLayoutEnd?: () => void;
305
+ workerEnabled?: boolean;
306
+ }
307
+
308
+ export interface RadialLayoutOptions {
309
+ type: "radial";
310
+ center?: PointTuple;
311
+ width?: number;
312
+ height?: number;
313
+ linkDistance?: number;
314
+ maxIteration?: number;
315
+ focusNode?: string | Node | null;
316
+ unitRadius?: number | null;
317
+ preventOverlap?: boolean;
318
+ nodeSize?: number | number[] | undefined;
319
+ nodeSpacing?: number | Function | undefined;
320
+ maxPreventOverlapIteration?: number;
321
+ strictRadial?: boolean;
322
+ sortBy?: string | undefined;
323
+ sortStrength?: number;
324
+ workerEnabled?: boolean;
325
+ onLayoutEnd?: () => void;
326
+ }
327
+
328
+ export interface FruchtermanGPULayoutOptions {
329
+ type: "fruchterman-gpu";
330
+ center?: PointTuple;
331
+ width?: number;
332
+ height?: number;
333
+ maxIteration?: number;
334
+ gravity?: number;
335
+ speed?: number;
336
+ clustering?: boolean;
337
+ clusterGravity?: number;
338
+ workerEnabled?: boolean;
339
+ gpuEnabled?: boolean;
340
+ onLayoutEnd?: () => void;
341
+ }
342
+
343
+ export interface GForceGPULayoutOptions {
344
+ type: "gForce-gpu";
345
+ center?: PointTuple;
346
+ linkDistance?: number | ((d?: any) => number) | undefined;
347
+ nodeStrength?: number | ((d?: any) => number) | undefined;
348
+ edgeStrength?: number | ((d?: any) => number) | undefined;
349
+ minMovement?: number;
350
+ maxIteration?: number;
351
+ damping?: number;
352
+ maxSpeed?: number;
353
+ coulombDisScale?: number;
354
+ getMass?: ((d?: any) => number) | undefined;
355
+ getCenter?: ((d?: any, degree?: number) => number[]) | undefined;
356
+ gravity?: number;
357
+ onLayoutEnd?: () => void;
358
+ workerEnabled?: boolean;
359
+ gpuEnabled?: boolean;
360
+ }
361
+
362
+
363
+ export interface ForceAtlas2LayoutOptions {
364
+ type: "forceAtlas2";
365
+ center?: PointTuple;
366
+ width?: number;
367
+ height?: number;
368
+ workerEnabled?: boolean;
369
+ onLayoutEnd?: () => void;
370
+ tick?: () => void;
371
+ kr?: number;
372
+ kg?: number;
373
+ ks?: number;
374
+ ksmax?: number;
375
+ tao?: number;
376
+ maxIteration?: number;
377
+ mode?: 'normal' | 'linlog';
378
+ preventOverlap?: boolean;
379
+ dissuadeHubs?: boolean;
380
+ barnesHut?: boolean;
381
+ prune?: boolean;
382
+ }
383
+
384
+ export interface ERLayoutOptions {
385
+ type: "er";
386
+ width?: number;
387
+ height?: number;
388
+ nodeMinGap?: number;
389
+ }
390
+ export namespace ILayout {
391
+ export type LayoutTypes =
392
+ | "grid"
393
+ | "random"
394
+ | "force"
395
+ | "circular"
396
+ | "dagre"
397
+ | "radial"
398
+ | "concentric"
399
+ | "mds"
400
+ | "fruchterman"
401
+ | "fruchterman-gpu"
402
+ | "gForce"
403
+ | "gForce-gpu"
404
+ | "comboForce"
405
+ | "forceAtlas2"
406
+ | "er";
407
+
408
+ export type LayoutOptions =
409
+ | GridLayoutOptions
410
+ | RandomLayoutOptions
411
+ | ForceLayoutOptions
412
+ | CircularLayoutOptions
413
+ | DagreLayoutOptions
414
+ | RadialLayoutOptions
415
+ | ConcentricLayoutOptions
416
+ | MDSLayoutOptions
417
+ | FruchtermanLayoutOptions
418
+ | FruchtermanGPULayoutOptions
419
+ | GForceLayoutOptions
420
+ | GForceGPULayoutOptions
421
+ | ComboForceLayoutOptions
422
+ | ComboCombinedLayoutOptions
423
+ | ForceAtlas2LayoutOptions
424
+ | ERLayoutOptions;
425
+ }
@@ -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
+ };