@alphacifer/slidev-addon-theme 0.0.8 → 0.0.10

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 (41) hide show
  1. package/README.md +80 -0
  2. package/components/defense-in-depth/arc-did/ArcDiD.vue +732 -0
  3. package/components/defense-in-depth/arc-did/ArcDiDLayer.vue +321 -0
  4. package/components/defense-in-depth/arc-did/ArcDiDLayerPart.vue +449 -0
  5. package/components/defense-in-depth/arc-did/ArcDiDLayerParts.vue +11 -0
  6. package/components/defense-in-depth/arc-did/ArcDiDLayerSector.vue +148 -0
  7. package/components/defense-in-depth/arc-did/ArcDiDLayerTitle.vue +98 -0
  8. package/components/pyramid/circular-pyramid/CircularPyramid.vue +858 -0
  9. package/components/pyramid/circular-pyramid/CircularPyramidStack.vue +342 -0
  10. package/components/pyramid/circular-pyramid/CircularPyramidStackContent.vue +305 -0
  11. package/components/pyramid/circular-pyramid/CircularPyramidStackTitle.vue +208 -0
  12. package/components/pyramid/square-pyramid/SquarePyramid.vue +863 -0
  13. package/components/pyramid/square-pyramid/SquarePyramidStack.vue +333 -0
  14. package/components/pyramid/square-pyramid/SquarePyramidStackContent.vue +301 -0
  15. package/components/pyramid/square-pyramid/SquarePyramidStackTitle.vue +204 -0
  16. package/package.json +2 -1
  17. package/utils/defenseInDepth/arcDid/context.ts +110 -0
  18. package/utils/defenseInDepth/arcDid/createArcDiDGeometry.ts +570 -0
  19. package/utils/defenseInDepth/arcDid/index.ts +3 -0
  20. package/utils/defenseInDepth/arcDid/types.ts +140 -0
  21. package/utils/defenseInDepth/index.ts +2 -0
  22. package/utils/defenseInDepth/shared/colors.ts +121 -0
  23. package/utils/defenseInDepth/shared/constants.ts +14 -0
  24. package/utils/defenseInDepth/shared/index.ts +3 -0
  25. package/utils/defenseInDepth/shared/types.ts +12 -0
  26. package/utils/pyramid/circular-pyramid/context.ts +46 -0
  27. package/utils/pyramid/circular-pyramid/createCircularPyramidGeometry.ts +143 -0
  28. package/utils/pyramid/circular-pyramid/index.ts +3 -0
  29. package/utils/pyramid/circular-pyramid/types.ts +34 -0
  30. package/utils/pyramid/index.ts +3 -0
  31. package/utils/pyramid/shared/colors.ts +92 -0
  32. package/utils/pyramid/shared/connector.ts +111 -0
  33. package/utils/pyramid/shared/constants.ts +9 -0
  34. package/utils/pyramid/shared/index.ts +5 -0
  35. package/utils/pyramid/shared/stacking.ts +76 -0
  36. package/utils/pyramid/shared/types.ts +36 -0
  37. package/utils/pyramid/square-pyramid/context.ts +46 -0
  38. package/utils/pyramid/square-pyramid/createSquarePyramidGeometry.ts +265 -0
  39. package/utils/pyramid/square-pyramid/index.ts +3 -0
  40. package/utils/pyramid/square-pyramid/types.ts +39 -0
  41. package/utils/useDiagramAutoScale.ts +64 -20
@@ -0,0 +1,570 @@
1
+ import type {
2
+ IArcDiDDecorativeArc,
3
+ IArcDiDGeometry,
4
+ IArcDiDLayerGeometry,
5
+ IArcDiDLayerItem,
6
+ IArcDiDPartGeometry,
7
+ IArcDiDPartItem,
8
+ IArcDiDPoint,
9
+ IArcDiDSectorGeometry,
10
+ IArcDiDSectorItem,
11
+ ICreateArcDiDOptions,
12
+ TArcDiDOrder,
13
+ } from './types';
14
+
15
+ export function round(val: number, decimals = 2): number {
16
+ const factor = 10 ** decimals;
17
+ return Math.round(val * factor) / factor;
18
+ }
19
+
20
+ export function polarToCartesian(
21
+ cx: number,
22
+ cy: number,
23
+ radius: number,
24
+ angleInDegrees: number,
25
+ ): IArcDiDPoint {
26
+ const angleInRadians = (angleInDegrees * Math.PI) / 180;
27
+ return {
28
+ x: round(cx + radius * Math.cos(angleInRadians)),
29
+ y: round(cy - radius * Math.sin(angleInRadians)),
30
+ };
31
+ }
32
+
33
+ export function describeArc(
34
+ cx: number,
35
+ cy: number,
36
+ radius: number,
37
+ startAngleDeg: number,
38
+ endAngleDeg: number,
39
+ ): string {
40
+ const start = polarToCartesian(cx, cy, radius, startAngleDeg);
41
+ const end = polarToCartesian(cx, cy, radius, endAngleDeg);
42
+ const angleDiff = Math.abs(endAngleDeg - startAngleDeg);
43
+ const largeArcFlag = angleDiff > 180 ? 1 : 0;
44
+ const sweepFlag = startAngleDeg > endAngleDeg ? 1 : 0;
45
+
46
+ return `M ${start.x} ${start.y} A ${round(radius)} ${round(radius)} 0 ${largeArcFlag} ${sweepFlag} ${end.x} ${end.y}`;
47
+ }
48
+
49
+ export function describeArcBand(
50
+ cx: number,
51
+ cy: number,
52
+ rIn: number,
53
+ rOut: number,
54
+ startAngleDeg = 180,
55
+ endAngleDeg = 0,
56
+ ): string {
57
+ const outerStart = polarToCartesian(cx, cy, rOut, startAngleDeg);
58
+ const outerEnd = polarToCartesian(cx, cy, rOut, endAngleDeg);
59
+ const innerStart = polarToCartesian(cx, cy, rIn, endAngleDeg);
60
+ const innerEnd = polarToCartesian(cx, cy, rIn, startAngleDeg);
61
+
62
+ return [
63
+ `M ${outerStart.x} ${outerStart.y}`,
64
+ `A ${round(rOut)} ${round(rOut)} 0 0 1 ${outerEnd.x} ${outerEnd.y}`,
65
+ `L ${innerStart.x} ${innerStart.y}`,
66
+ `A ${round(rIn)} ${round(rIn)} 0 0 0 ${innerEnd.x} ${innerEnd.y}`,
67
+ 'Z',
68
+ ].join(' ');
69
+ }
70
+
71
+ export interface IArcDiDSectorInfo {
72
+ readonly startAngle: number;
73
+ readonly endAngle: number;
74
+ readonly midAngle: number;
75
+ }
76
+
77
+ export interface IArcDiDTitleAngles {
78
+ readonly halfSpan: number;
79
+ readonly titleLeft: number;
80
+ readonly titleRight: number;
81
+ }
82
+
83
+ export function calculateTitleAngles(titleAngleSpan = 40): IArcDiDTitleAngles {
84
+ const halfSpan = round(titleAngleSpan / 2, 2);
85
+ const titleLeft = round(90 + halfSpan, 1);
86
+ const titleRight = round(90 - halfSpan, 1);
87
+ return { halfSpan, titleLeft, titleRight };
88
+ }
89
+
90
+ function resolveSpansDistribution(
91
+ count: number,
92
+ totalSpan: number,
93
+ inputSpans?: readonly (number | undefined)[],
94
+ ): number[] {
95
+ if (count <= 0) return [];
96
+ if (
97
+ !inputSpans ||
98
+ inputSpans.length === 0 ||
99
+ inputSpans.every((s) => s === undefined)
100
+ ) {
101
+ return Array.from({ length: count }, () => totalSpan / count);
102
+ }
103
+
104
+ let specifiedSum = 0;
105
+ let unspecifiedCount = 0;
106
+
107
+ for (let i = 0; i < count; i++) {
108
+ const s = inputSpans[i];
109
+ if (s !== undefined && s > 0) {
110
+ specifiedSum += s;
111
+ } else {
112
+ unspecifiedCount++;
113
+ }
114
+ }
115
+
116
+ if (unspecifiedCount > 0) {
117
+ const remaining = Math.max(0, totalSpan - specifiedSum);
118
+ const perUnspecified = remaining / unspecifiedCount;
119
+ return Array.from({ length: count }, (_, i) => {
120
+ const s = inputSpans[i];
121
+ return s !== undefined && s > 0 ? s : perUnspecified;
122
+ });
123
+ }
124
+
125
+ // All sectors have explicit spans: keep head sectors exact and absorb remainder into last sector
126
+ if (count > 1) {
127
+ const headSpans = inputSpans.slice(0, count - 1).map((s) => s ?? 0);
128
+ const headSum = headSpans.reduce((a, b) => a + b, 0);
129
+ const lastSpan = Math.max(0, totalSpan - headSum);
130
+ return [...headSpans, round(lastSpan, 2)];
131
+ }
132
+
133
+ return [totalSpan];
134
+ }
135
+
136
+ export function calculatePartSectors(
137
+ partCount: number,
138
+ titleAngleSpan = 40,
139
+ sectorSpans?: readonly (number | undefined)[],
140
+ ): IArcDiDSectorInfo[] {
141
+ if (partCount <= 0) {
142
+ return [];
143
+ }
144
+
145
+ const { titleLeft, titleRight } = calculateTitleAngles(titleAngleSpan);
146
+
147
+ if (partCount === 1) {
148
+ return [
149
+ {
150
+ startAngle: 180,
151
+ endAngle: titleLeft,
152
+ midAngle: round((180 + titleLeft) / 2, 1),
153
+ },
154
+ ];
155
+ }
156
+
157
+ const leftCount = Math.ceil(partCount / 2);
158
+ const rightCount = partCount - leftCount;
159
+
160
+ const leftSpansInput = sectorSpans?.slice(0, leftCount);
161
+ const rightSpansInput = sectorSpans?.slice(leftCount);
162
+
163
+ const totalLeftSpan = 180 - titleLeft;
164
+ const leftAllocatedSpans = resolveSpansDistribution(
165
+ leftCount,
166
+ totalLeftSpan,
167
+ leftSpansInput,
168
+ );
169
+
170
+ const totalRightSpan = titleRight;
171
+ const rightAllocatedSpans = resolveSpansDistribution(
172
+ rightCount,
173
+ totalRightSpan,
174
+ rightSpansInput,
175
+ );
176
+
177
+ const sectors: IArcDiDSectorInfo[] = [];
178
+
179
+ // Left sectors: 180 down to titleLeft
180
+ let currentLeft = 180;
181
+ for (let i = 0; i < leftCount; i++) {
182
+ const span = leftAllocatedSpans[i] ?? totalLeftSpan / leftCount;
183
+ const start = currentLeft;
184
+ const end = i === leftCount - 1 ? titleLeft : round(currentLeft - span, 1);
185
+ currentLeft = end;
186
+ sectors.push({
187
+ startAngle: round(start, 1),
188
+ endAngle: round(end, 1),
189
+ midAngle: round((start + end) / 2, 1),
190
+ });
191
+ }
192
+
193
+ // Right sectors: titleRight down to 0
194
+ let currentRight = titleRight;
195
+ for (let j = 0; j < rightCount; j++) {
196
+ const span = rightAllocatedSpans[j] ?? totalRightSpan / rightCount;
197
+ const start = currentRight;
198
+ const end = j === rightCount - 1 ? 0 : round(currentRight - span, 1);
199
+ currentRight = end;
200
+ sectors.push({
201
+ startAngle: round(start, 1),
202
+ endAngle: round(end, 1),
203
+ midAngle: round((start + end) / 2, 1),
204
+ });
205
+ }
206
+
207
+ return sectors;
208
+ }
209
+
210
+ export function calculatePartAngles(
211
+ partCount: number,
212
+ titleAngleSpan = 40,
213
+ ): number[] {
214
+ return calculatePartSectors(partCount, titleAngleSpan).map((s) => s.midAngle);
215
+ }
216
+
217
+ export function resolveLayerTitleSpan(
218
+ midRadius: number,
219
+ layerTitleAngleSpan?: number,
220
+ globalTitleAngleSpan?: number,
221
+ titleWidth = 115,
222
+ ): number {
223
+ if (layerTitleAngleSpan !== undefined) {
224
+ return Math.max(10, Math.min(80, layerTitleAngleSpan));
225
+ }
226
+ if (globalTitleAngleSpan !== undefined) {
227
+ return Math.max(10, Math.min(80, globalTitleAngleSpan));
228
+ }
229
+ const computedAngle = (titleWidth / Math.max(1, midRadius)) * (180 / Math.PI);
230
+ return Math.max(18, Math.min(50, round(computedAngle, 1)));
231
+ }
232
+
233
+ export function createDecorativeArcs(
234
+ _cx?: number,
235
+ _cy?: number,
236
+ _outerRadius?: number,
237
+ _innerRadius?: number,
238
+ ): readonly IArcDiDDecorativeArc[] {
239
+ return [];
240
+ }
241
+
242
+ export function createArcDiDGeometry(
243
+ options: ICreateArcDiDOptions = {},
244
+ ): IArcDiDGeometry {
245
+ const viewBoxWidth = options.viewBoxWidth ?? 900;
246
+ const viewBoxHeight = options.viewBoxHeight ?? 460;
247
+ const cx = options.cx ?? round(viewBoxWidth / 2);
248
+ const cy = options.cy ?? round(viewBoxHeight - 6);
249
+
250
+ const innerRadius = Math.max(30, options.innerRadius ?? 90);
251
+ const outerRadius = Math.max(innerRadius + 40, options.outerRadius ?? 445);
252
+
253
+ const rawCount =
254
+ options.count ??
255
+ (options.layers && options.layers.length > 0 ? options.layers.length : 0);
256
+ const count = Math.max(0, Math.min(rawCount, 6));
257
+
258
+ const gap = options.gap !== undefined ? Math.max(0, options.gap) : 0;
259
+ const order: TArcDiDOrder = options.order ?? 'outer-to-inner';
260
+
261
+ const totalSpan = outerRadius - innerRadius;
262
+ const totalGaps = count > 1 ? (count - 1) * gap : 0;
263
+ const layerThickness =
264
+ count > 0 ? Math.max(10, (totalSpan - totalGaps) / count) : 0;
265
+
266
+ const layersData: readonly IArcDiDLayerItem[] = options.layers ?? [];
267
+
268
+ const layers: IArcDiDLayerGeometry[] = [];
269
+
270
+ if (count > 0) {
271
+ for (let i = 0; i < count; i++) {
272
+ let rIn: number;
273
+ let rOut: number;
274
+
275
+ if (order === 'outer-to-inner') {
276
+ // index 0 is outermost
277
+ rOut = outerRadius - i * (layerThickness + gap);
278
+ rIn = rOut - layerThickness;
279
+ } else {
280
+ // index 0 is innermost
281
+ rIn = innerRadius + i * (layerThickness + gap);
282
+ rOut = rIn + layerThickness;
283
+ }
284
+
285
+ const midRadius = (rIn + rOut) / 2;
286
+ const path = describeArcBand(cx, cy, rIn, rOut, 180, 0);
287
+
288
+ const layerItem = layersData[i];
289
+ let rawSectors: readonly IArcDiDSectorItem[] = [];
290
+
291
+ if (layerItem?.sectors && layerItem.sectors.length > 0) {
292
+ rawSectors = layerItem.sectors.map((s) => {
293
+ if (Array.isArray(s)) {
294
+ return { parts: s, split: false };
295
+ }
296
+ return s as IArcDiDSectorItem;
297
+ });
298
+ } else if (layerItem?.parts && layerItem.parts.length > 0) {
299
+ rawSectors = layerItem.parts.map((p) => {
300
+ if (
301
+ typeof p === 'object' &&
302
+ p !== null &&
303
+ 'parts' in p &&
304
+ Array.isArray((p as { parts: unknown }).parts)
305
+ ) {
306
+ return p as IArcDiDSectorItem;
307
+ }
308
+ return { parts: [p], split: false };
309
+ });
310
+ }
311
+
312
+ const layerTitleSpan = resolveLayerTitleSpan(
313
+ midRadius,
314
+ layerItem?.titleAngleSpan,
315
+ options.titleAngleSpan,
316
+ layerItem?.titleWidth ?? options.titleWidth,
317
+ );
318
+ const { titleLeft, titleRight } = calculateTitleAngles(layerTitleSpan);
319
+
320
+ const titlePosition = polarToCartesian(cx, cy, midRadius, 90);
321
+ const titlePath = describeArcBand(
322
+ cx,
323
+ cy,
324
+ rIn,
325
+ rOut,
326
+ titleLeft,
327
+ titleRight,
328
+ );
329
+
330
+ const sectorCount = rawSectors.length;
331
+ const rawSectorSpans = rawSectors.map((s) => s?.span);
332
+ const partSectors = calculatePartSectors(
333
+ sectorCount,
334
+ layerTitleSpan,
335
+ rawSectorSpans,
336
+ );
337
+
338
+ const sectors: IArcDiDSectorGeometry[] = [];
339
+ const parts: IArcDiDPartGeometry[] = [];
340
+
341
+ for (let s = 0; s < sectorCount; s++) {
342
+ const sectorItem = rawSectors[s];
343
+ const sector = partSectors[s];
344
+ let startAngle = sector?.startAngle ?? 180;
345
+ let endAngle = sector?.endAngle ?? 0;
346
+ let midAngle = sector?.midAngle ?? 90;
347
+
348
+ if (sectorItem?.angle !== undefined) {
349
+ midAngle = sectorItem.angle;
350
+ const defaultSpan = Math.abs(startAngle - endAngle);
351
+ const span = sectorItem.span ?? defaultSpan;
352
+ startAngle = round(Math.min(180, midAngle + span / 2), 1);
353
+ endAngle = round(Math.max(0, midAngle - span / 2), 1);
354
+ }
355
+
356
+ const sectorSpan = Math.abs(startAngle - endAngle);
357
+ const sectorPath = describeArcBand(
358
+ cx,
359
+ cy,
360
+ rIn,
361
+ rOut,
362
+ startAngle,
363
+ endAngle,
364
+ );
365
+
366
+ const rawSectorParts = sectorItem?.parts ?? [];
367
+ const numParts = rawSectorParts.length;
368
+ const isSplit = sectorItem?.split !== false && numParts > 1;
369
+ const trackThickness =
370
+ numParts > 0 ? layerThickness / numParts : layerThickness;
371
+
372
+ const dividerPaths: string[] = [];
373
+ if (isSplit && numParts > 1) {
374
+ for (let d = 1; d < numParts; d++) {
375
+ const dividerRadius = round(rOut - d * trackThickness, 2);
376
+ dividerPaths.push(
377
+ describeArc(cx, cy, dividerRadius, startAngle, endAngle),
378
+ );
379
+ }
380
+ }
381
+
382
+ const sectorParts: IArcDiDPartGeometry[] = [];
383
+
384
+ for (let p = 0; p < numParts; p++) {
385
+ const rawPart = rawSectorParts[p];
386
+ const partItem: IArcDiDPartItem =
387
+ typeof rawPart === 'string'
388
+ ? { label: rawPart }
389
+ : (rawPart ?? { label: '' });
390
+
391
+ let trackIndex = p;
392
+ if (partItem.position === 'top') {
393
+ trackIndex = 0;
394
+ } else if (partItem.position === 'bottom') {
395
+ trackIndex = Math.max(0, numParts - 1);
396
+ } else if (partItem.position === 'middle') {
397
+ trackIndex = numParts > 2 ? 1 : 0.5;
398
+ } else if (partItem.position === 'center' || numParts === 1) {
399
+ trackIndex = (numParts - 1) / 2;
400
+ }
401
+
402
+ const trackOuter = rOut - trackIndex * trackThickness;
403
+ const trackInner = trackOuter - trackThickness;
404
+ const trackMid = (trackOuter + trackInner) / 2;
405
+
406
+ let partRadius =
407
+ partItem.position === 'center' || numParts === 1
408
+ ? midRadius
409
+ : trackMid;
410
+
411
+ // For bottom tracks in split sectors, adjust default radius slightly inward
412
+ // to compensate for corner expansion of horizontal text across curved boundaries
413
+ if (
414
+ numParts > 1 &&
415
+ trackIndex === numParts - 1 &&
416
+ partItem.position !== 'center'
417
+ ) {
418
+ partRadius = trackMid - 2.5;
419
+ }
420
+
421
+ if (partItem.radius !== undefined) {
422
+ partRadius = partItem.radius;
423
+ } else if (partItem.radialOffset !== undefined) {
424
+ partRadius = partRadius + partItem.radialOffset;
425
+ }
426
+
427
+ let partAngle = midAngle;
428
+ let pStart = startAngle;
429
+ let pEnd = endAngle;
430
+
431
+ if (partItem.angle !== undefined) {
432
+ partAngle = partItem.angle;
433
+ const pSpan = partItem.span ?? sectorSpan;
434
+ pStart = round(Math.min(180, partAngle + pSpan / 2), 1);
435
+ pEnd = round(Math.max(0, partAngle - pSpan / 2), 1);
436
+ } else if (partItem.span !== undefined) {
437
+ pStart = round(Math.min(180, partAngle + partItem.span / 2), 1);
438
+ pEnd = round(Math.max(0, partAngle - partItem.span / 2), 1);
439
+ }
440
+
441
+ const point = polarToCartesian(cx, cy, partRadius, partAngle);
442
+
443
+ const partPath = isSplit
444
+ ? describeArcBand(
445
+ cx,
446
+ cy,
447
+ Math.max(rIn, trackInner),
448
+ Math.min(rOut, trackOuter),
449
+ pStart,
450
+ pEnd,
451
+ )
452
+ : sectorPath;
453
+
454
+ const partArcLength =
455
+ partRadius * (Math.abs(pStart - pEnd) * (Math.PI / 180));
456
+ const effectiveRotate = partItem.rotate ?? sectorItem?.rotate;
457
+ const effectiveSkew = partItem.skew ?? sectorItem?.skew;
458
+
459
+ const tangentAngle = round(90 - partAngle, 1);
460
+ let rotationAngle: number | undefined;
461
+ if (typeof effectiveRotate === 'number') {
462
+ rotationAngle = effectiveRotate;
463
+ } else if (
464
+ effectiveRotate === true ||
465
+ effectiveRotate === 'tangent' ||
466
+ effectiveRotate === 'auto'
467
+ ) {
468
+ rotationAngle = tangentAngle;
469
+ } else if (
470
+ effectiveSkew === true ||
471
+ effectiveSkew === 'tangent' ||
472
+ effectiveSkew === 'auto'
473
+ ) {
474
+ rotationAngle = tangentAngle;
475
+ }
476
+
477
+ const isOrientedAlongArc = rotationAngle !== undefined;
478
+ const defaultMaxContentWidth =
479
+ numParts > 1 && !isOrientedAlongArc
480
+ ? Math.max(75, Math.min(105, Math.round(partArcLength * 0.75)))
481
+ : Math.max(105, Math.min(180, Math.round(partArcLength * 0.92)));
482
+ const maxContentWidth =
483
+ partItem.maxWidth !== undefined
484
+ ? typeof partItem.maxWidth === 'number'
485
+ ? partItem.maxWidth
486
+ : Number.parseInt(partItem.maxWidth, 10)
487
+ : defaultMaxContentWidth;
488
+
489
+ const partGeo: IArcDiDPartGeometry = {
490
+ index: parts.length,
491
+ sectorIndex: s,
492
+ trackIndex,
493
+ position: partItem.position,
494
+ label: partItem.label,
495
+ angle: round(partAngle, 1),
496
+ radius: round(partRadius, 2),
497
+ x: round(point.x, 2),
498
+ y: round(point.y, 2),
499
+ color: partItem.color,
500
+ icon: partItem.icon,
501
+ startAngle: pStart,
502
+ endAngle: pEnd,
503
+ midAngle: round(partAngle, 1),
504
+ path: partPath,
505
+ innerRadius: round(isSplit ? trackInner : rIn, 2),
506
+ outerRadius: round(isSplit ? trackOuter : rOut, 2),
507
+ maxContentWidth,
508
+ rotate: effectiveRotate,
509
+ skew: effectiveSkew,
510
+ rotationAngle,
511
+ active: partItem.active,
512
+ };
513
+
514
+ sectorParts.push(partGeo);
515
+ parts.push(partGeo);
516
+ }
517
+
518
+ sectors.push({
519
+ index: s,
520
+ startAngle,
521
+ endAngle,
522
+ midAngle,
523
+ span: sectorSpan,
524
+ path: sectorPath,
525
+ split: isSplit,
526
+ dividerPaths,
527
+ color: sectorItem?.color,
528
+ rotate: sectorItem?.rotate,
529
+ skew: sectorItem?.skew,
530
+ parts: sectorParts,
531
+ });
532
+ }
533
+
534
+ layers.push({
535
+ index: i,
536
+ innerRadius: round(rIn),
537
+ outerRadius: round(rOut),
538
+ midRadius: round(midRadius),
539
+ thickness: round(layerThickness),
540
+ path,
541
+ titlePosition,
542
+ titlePath,
543
+ titleLeft,
544
+ titleRight,
545
+ sectors,
546
+ parts,
547
+ });
548
+ }
549
+ }
550
+
551
+ const decorativeArcs =
552
+ count > 0 ? createDecorativeArcs(cx, cy, outerRadius, innerRadius) : [];
553
+ const innerCutoutPath =
554
+ count > 0
555
+ ? `M ${round(cx - innerRadius)} ${cy} A ${round(innerRadius)} ${round(innerRadius)} 0 0 1 ${round(cx + innerRadius)} ${cy} Z`
556
+ : '';
557
+
558
+ return {
559
+ viewBoxWidth,
560
+ viewBoxHeight,
561
+ cx,
562
+ cy,
563
+ innerRadius,
564
+ outerRadius,
565
+ count,
566
+ innerCutoutPath,
567
+ layers,
568
+ decorativeArcs,
569
+ };
570
+ }
@@ -0,0 +1,3 @@
1
+ export * from './context';
2
+ export * from './createArcDiDGeometry';
3
+ export * from './types';
@@ -0,0 +1,140 @@
1
+ export type TArcDiDOrder = 'outer-to-inner' | 'inner-to-outer';
2
+ export type TArcDiDPartPosition = 'top' | 'middle' | 'bottom' | 'center';
3
+ export type TArcDiDOrientation =
4
+ | boolean
5
+ | number
6
+ | 'tangent'
7
+ | 'auto'
8
+ | (string & {});
9
+
10
+ export interface IArcDiDPoint {
11
+ readonly x: number;
12
+ readonly y: number;
13
+ }
14
+
15
+ export interface IArcDiDPartItem {
16
+ readonly label: string;
17
+ readonly angle?: number;
18
+ readonly radius?: number;
19
+ readonly radialOffset?: number;
20
+ readonly color?: string;
21
+ readonly icon?: string;
22
+ readonly span?: number;
23
+ readonly position?: TArcDiDPartPosition;
24
+ readonly maxWidth?: number | string;
25
+ readonly rotate?: TArcDiDOrientation;
26
+ readonly skew?: TArcDiDOrientation;
27
+ readonly active?: boolean;
28
+ }
29
+
30
+ export interface IArcDiDSectorItem {
31
+ readonly parts: readonly (string | IArcDiDPartItem)[];
32
+ readonly split?: boolean;
33
+ readonly angle?: number;
34
+ readonly span?: number;
35
+ readonly color?: string;
36
+ readonly rotate?: TArcDiDOrientation;
37
+ readonly skew?: TArcDiDOrientation;
38
+ }
39
+
40
+ export interface IArcDiDLayerItem {
41
+ readonly title?: string;
42
+ readonly parts?: readonly (string | IArcDiDPartItem)[];
43
+ readonly sectors?: readonly (
44
+ | IArcDiDSectorItem
45
+ | readonly (string | IArcDiDPartItem)[]
46
+ )[];
47
+ readonly color?: string;
48
+ readonly textColor?: string;
49
+ readonly titleAngleSpan?: number;
50
+ readonly titleWidth?: number;
51
+ }
52
+
53
+ export interface IArcDiDPartGeometry {
54
+ readonly index: number;
55
+ readonly sectorIndex?: number;
56
+ readonly trackIndex?: number;
57
+ readonly position?: TArcDiDPartPosition;
58
+ readonly label: string;
59
+ readonly angle: number;
60
+ readonly radius: number;
61
+ readonly x: number;
62
+ readonly y: number;
63
+ readonly color?: string;
64
+ readonly icon?: string;
65
+ readonly startAngle?: number;
66
+ readonly endAngle?: number;
67
+ readonly midAngle?: number;
68
+ readonly path?: string;
69
+ readonly innerRadius?: number;
70
+ readonly outerRadius?: number;
71
+ readonly maxContentWidth?: number;
72
+ readonly rotate?: TArcDiDOrientation;
73
+ readonly skew?: TArcDiDOrientation;
74
+ readonly rotationAngle?: number;
75
+ readonly active?: boolean;
76
+ }
77
+
78
+ export interface IArcDiDSectorGeometry {
79
+ readonly index: number;
80
+ readonly startAngle: number;
81
+ readonly endAngle: number;
82
+ readonly midAngle: number;
83
+ readonly span: number;
84
+ readonly path: string;
85
+ readonly split: boolean;
86
+ readonly dividerPaths: readonly string[];
87
+ readonly color?: string;
88
+ readonly rotate?: TArcDiDOrientation;
89
+ readonly skew?: TArcDiDOrientation;
90
+ readonly parts: readonly IArcDiDPartGeometry[];
91
+ }
92
+
93
+ export interface IArcDiDLayerGeometry {
94
+ readonly index: number;
95
+ readonly innerRadius: number;
96
+ readonly outerRadius: number;
97
+ readonly midRadius: number;
98
+ readonly thickness: number;
99
+ readonly path: string;
100
+ readonly titlePosition: IArcDiDPoint;
101
+ readonly titlePath?: string;
102
+ readonly titleLeft?: number;
103
+ readonly titleRight?: number;
104
+ readonly sectors: readonly IArcDiDSectorGeometry[];
105
+ readonly parts: readonly IArcDiDPartGeometry[];
106
+ }
107
+
108
+ export interface IArcDiDDecorativeArc {
109
+ readonly path: string;
110
+ readonly strokeWidth: number;
111
+ readonly opacity: number;
112
+ }
113
+
114
+ export interface IArcDiDGeometry {
115
+ readonly viewBoxWidth: number;
116
+ readonly viewBoxHeight: number;
117
+ readonly cx: number;
118
+ readonly cy: number;
119
+ readonly innerRadius: number;
120
+ readonly outerRadius: number;
121
+ readonly count: number;
122
+ readonly layers: readonly IArcDiDLayerGeometry[];
123
+ readonly decorativeArcs: readonly IArcDiDDecorativeArc[];
124
+ readonly innerCutoutPath?: string;
125
+ }
126
+
127
+ export interface ICreateArcDiDOptions {
128
+ readonly viewBoxWidth?: number;
129
+ readonly viewBoxHeight?: number;
130
+ readonly cx?: number;
131
+ readonly cy?: number;
132
+ readonly innerRadius?: number;
133
+ readonly outerRadius?: number;
134
+ readonly count?: number;
135
+ readonly gap?: number;
136
+ readonly order?: TArcDiDOrder;
137
+ readonly titleAngleSpan?: number;
138
+ readonly titleWidth?: number;
139
+ readonly layers?: readonly IArcDiDLayerItem[];
140
+ }
@@ -0,0 +1,2 @@
1
+ export * from './arcDid';
2
+ export * from './shared';