@almadar/ui 5.146.3 → 5.148.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/dist/avl/index.cjs +363 -35
- package/dist/avl/index.js +363 -35
- package/dist/{cn-BdGFhYe3.d.cts → cn-BAn68sNO.d.cts} +92 -2
- package/dist/{cn-DNkqAWZK.d.ts → cn-CWxxLkri.d.ts} +92 -2
- package/dist/components/index.cjs +364 -36
- package/dist/components/index.d.cts +99 -175
- package/dist/components/index.d.ts +99 -175
- package/dist/components/index.js +364 -36
- package/dist/lib/index.cjs +104 -0
- package/dist/lib/index.d.cts +2 -1
- package/dist/lib/index.d.ts +2 -1
- package/dist/lib/index.js +104 -1
- package/dist/providers/index.cjs +363 -35
- package/dist/providers/index.js +363 -35
- package/dist/runtime/index.cjs +363 -35
- package/dist/runtime/index.js +363 -35
- package/package.json +6 -6
- package/themes/bloomberg-dense.css +266 -229
- package/themes/retro.css +30 -30
package/dist/providers/index.js
CHANGED
|
@@ -11779,7 +11779,10 @@ var init_LearningCanvas = __esm({
|
|
|
11779
11779
|
ctx.fillRect(0, 0, width, height);
|
|
11780
11780
|
}
|
|
11781
11781
|
for (const shape of shapes) {
|
|
11782
|
-
drawShape(ctx, shape, width, height);
|
|
11782
|
+
if (shape.type !== "text") drawShape(ctx, shape, width, height);
|
|
11783
|
+
}
|
|
11784
|
+
for (const shape of shapes) {
|
|
11785
|
+
if (shape.type === "text") drawShape(ctx, shape, width, height);
|
|
11783
11786
|
}
|
|
11784
11787
|
}, [width, height, backgroundColor, shapes]);
|
|
11785
11788
|
useEffect(() => {
|
|
@@ -13725,7 +13728,7 @@ var init_AlgorithmCanvas = __esm({
|
|
|
13725
13728
|
DEFAULT_CELL_COLOR = "#e5e7eb";
|
|
13726
13729
|
DEFAULT_POINTER_COLOR = "#dc2626";
|
|
13727
13730
|
POINTER_BAND = 34;
|
|
13728
|
-
TOP_PAD =
|
|
13731
|
+
TOP_PAD = 26;
|
|
13729
13732
|
AlgorithmCanvas = ({
|
|
13730
13733
|
className,
|
|
13731
13734
|
width = 600,
|
|
@@ -25331,6 +25334,7 @@ var init_FilterGroup = __esm({
|
|
|
25331
25334
|
init_Badge();
|
|
25332
25335
|
init_Stack();
|
|
25333
25336
|
init_Icon();
|
|
25337
|
+
init_RangeSlider();
|
|
25334
25338
|
init_useEventBus();
|
|
25335
25339
|
init_useQuerySingleton();
|
|
25336
25340
|
resolveFilterType = (filter) => filter.filterType ?? filter.type;
|
|
@@ -25525,6 +25529,35 @@ var init_FilterGroup = __esm({
|
|
|
25525
25529
|
onClear: () => handleFilterSelect(`${filter.field}_to`, null)
|
|
25526
25530
|
}
|
|
25527
25531
|
)
|
|
25532
|
+
] }) : resolveFilterType(filter) === "numberrange" || resolveFilterType(filter) === "number-range" ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
25533
|
+
/* @__PURE__ */ jsx(
|
|
25534
|
+
RangeSlider,
|
|
25535
|
+
{
|
|
25536
|
+
min: filter.min ?? 0,
|
|
25537
|
+
max: filter.max ?? 100,
|
|
25538
|
+
step: filter.step ?? 1,
|
|
25539
|
+
value: Number(
|
|
25540
|
+
selectedValues[`${filter.field}_min`] ?? filter.min ?? 0
|
|
25541
|
+
),
|
|
25542
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_min`, String(v)),
|
|
25543
|
+
showTooltip: true,
|
|
25544
|
+
"aria-label": t("filterGroup.from")
|
|
25545
|
+
}
|
|
25546
|
+
),
|
|
25547
|
+
/* @__PURE__ */ jsx(
|
|
25548
|
+
RangeSlider,
|
|
25549
|
+
{
|
|
25550
|
+
min: filter.min ?? 0,
|
|
25551
|
+
max: filter.max ?? 100,
|
|
25552
|
+
step: filter.step ?? 1,
|
|
25553
|
+
value: Number(
|
|
25554
|
+
selectedValues[`${filter.field}_max`] ?? filter.max ?? 100
|
|
25555
|
+
),
|
|
25556
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_max`, String(v)),
|
|
25557
|
+
showTooltip: true,
|
|
25558
|
+
"aria-label": t("filterGroup.to")
|
|
25559
|
+
}
|
|
25560
|
+
)
|
|
25528
25561
|
] }) : resolveFilterType(filter) === "text" ? /* @__PURE__ */ jsx(
|
|
25529
25562
|
Input,
|
|
25530
25563
|
{
|
|
@@ -25607,6 +25640,36 @@ var init_FilterGroup = __esm({
|
|
|
25607
25640
|
className: "text-sm min-w-[100px]"
|
|
25608
25641
|
}
|
|
25609
25642
|
)
|
|
25643
|
+
] }) : resolveFilterType(filter) === "numberrange" || resolveFilterType(filter) === "number-range" ? /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
25644
|
+
/* @__PURE__ */ jsx(
|
|
25645
|
+
RangeSlider,
|
|
25646
|
+
{
|
|
25647
|
+
min: filter.min ?? 0,
|
|
25648
|
+
max: filter.max ?? 100,
|
|
25649
|
+
step: filter.step ?? 1,
|
|
25650
|
+
value: Number(
|
|
25651
|
+
selectedValues[`${filter.field}_min`] ?? filter.min ?? 0
|
|
25652
|
+
),
|
|
25653
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_min`, String(v)),
|
|
25654
|
+
className: "min-w-[100px]",
|
|
25655
|
+
"aria-label": t("filterGroup.from")
|
|
25656
|
+
}
|
|
25657
|
+
),
|
|
25658
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "-" }),
|
|
25659
|
+
/* @__PURE__ */ jsx(
|
|
25660
|
+
RangeSlider,
|
|
25661
|
+
{
|
|
25662
|
+
min: filter.min ?? 0,
|
|
25663
|
+
max: filter.max ?? 100,
|
|
25664
|
+
step: filter.step ?? 1,
|
|
25665
|
+
value: Number(
|
|
25666
|
+
selectedValues[`${filter.field}_max`] ?? filter.max ?? 100
|
|
25667
|
+
),
|
|
25668
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_max`, String(v)),
|
|
25669
|
+
className: "min-w-[100px]",
|
|
25670
|
+
"aria-label": t("filterGroup.to")
|
|
25671
|
+
}
|
|
25672
|
+
)
|
|
25610
25673
|
] }) : resolveFilterType(filter) === "text" ? /* @__PURE__ */ jsx(
|
|
25611
25674
|
Input,
|
|
25612
25675
|
{
|
|
@@ -25725,6 +25788,38 @@ var init_FilterGroup = __esm({
|
|
|
25725
25788
|
className: "min-w-[130px]"
|
|
25726
25789
|
}
|
|
25727
25790
|
)
|
|
25791
|
+
] }) : resolveFilterType(filter) === "numberrange" || resolveFilterType(filter) === "number-range" ? /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
25792
|
+
/* @__PURE__ */ jsx(
|
|
25793
|
+
RangeSlider,
|
|
25794
|
+
{
|
|
25795
|
+
min: filter.min ?? 0,
|
|
25796
|
+
max: filter.max ?? 100,
|
|
25797
|
+
step: filter.step ?? 1,
|
|
25798
|
+
value: Number(
|
|
25799
|
+
selectedValues[`${filter.field}_min`] ?? filter.min ?? 0
|
|
25800
|
+
),
|
|
25801
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_min`, String(v)),
|
|
25802
|
+
showTooltip: true,
|
|
25803
|
+
className: "min-w-[130px]",
|
|
25804
|
+
"aria-label": t("filterGroup.from")
|
|
25805
|
+
}
|
|
25806
|
+
),
|
|
25807
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "-" }),
|
|
25808
|
+
/* @__PURE__ */ jsx(
|
|
25809
|
+
RangeSlider,
|
|
25810
|
+
{
|
|
25811
|
+
min: filter.min ?? 0,
|
|
25812
|
+
max: filter.max ?? 100,
|
|
25813
|
+
step: filter.step ?? 1,
|
|
25814
|
+
value: Number(
|
|
25815
|
+
selectedValues[`${filter.field}_max`] ?? filter.max ?? 100
|
|
25816
|
+
),
|
|
25817
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_max`, String(v)),
|
|
25818
|
+
showTooltip: true,
|
|
25819
|
+
className: "min-w-[130px]",
|
|
25820
|
+
"aria-label": t("filterGroup.to")
|
|
25821
|
+
}
|
|
25822
|
+
)
|
|
25728
25823
|
] }) : resolveFilterType(filter) === "text" ? /* @__PURE__ */ jsx(
|
|
25729
25824
|
Input,
|
|
25730
25825
|
{
|
|
@@ -27624,7 +27719,12 @@ function daysAgo(n) {
|
|
|
27624
27719
|
d.setDate(d.getDate() - n);
|
|
27625
27720
|
return d;
|
|
27626
27721
|
}
|
|
27627
|
-
|
|
27722
|
+
function resolvePresetRange(preset) {
|
|
27723
|
+
if (typeof preset.range === "function") return preset.range();
|
|
27724
|
+
if (preset.range) return preset.range;
|
|
27725
|
+
return TOKEN_RANGES[preset.value]?.() ?? null;
|
|
27726
|
+
}
|
|
27727
|
+
var TOKEN_RANGES, DEFAULT_PRESETS, DateRangePicker;
|
|
27628
27728
|
var init_DateRangePicker = __esm({
|
|
27629
27729
|
"components/core/molecules/DateRangePicker.tsx"() {
|
|
27630
27730
|
"use client";
|
|
@@ -27634,32 +27734,19 @@ var init_DateRangePicker = __esm({
|
|
|
27634
27734
|
init_Stack();
|
|
27635
27735
|
init_Typography();
|
|
27636
27736
|
init_useEventBus();
|
|
27737
|
+
TOKEN_RANGES = {
|
|
27738
|
+
"7d": () => ({ from: toISODate(daysAgo(7)), to: toISODate(/* @__PURE__ */ new Date()) }),
|
|
27739
|
+
"30d": () => ({ from: toISODate(daysAgo(30)), to: toISODate(/* @__PURE__ */ new Date()) }),
|
|
27740
|
+
month: () => ({ from: toISODate(startOfMonth(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) }),
|
|
27741
|
+
quarter: () => ({ from: toISODate(startOfQuarter(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) }),
|
|
27742
|
+
ytd: () => ({ from: toISODate(startOfYear(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
|
|
27743
|
+
};
|
|
27637
27744
|
DEFAULT_PRESETS = [
|
|
27638
|
-
{
|
|
27639
|
-
|
|
27640
|
-
|
|
27641
|
-
|
|
27642
|
-
}
|
|
27643
|
-
{
|
|
27644
|
-
label: "Last 30 days",
|
|
27645
|
-
value: "30d",
|
|
27646
|
-
range: () => ({ from: toISODate(daysAgo(30)), to: toISODate(/* @__PURE__ */ new Date()) })
|
|
27647
|
-
},
|
|
27648
|
-
{
|
|
27649
|
-
label: "This Month",
|
|
27650
|
-
value: "month",
|
|
27651
|
-
range: () => ({ from: toISODate(startOfMonth(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
|
|
27652
|
-
},
|
|
27653
|
-
{
|
|
27654
|
-
label: "This Quarter",
|
|
27655
|
-
value: "quarter",
|
|
27656
|
-
range: () => ({ from: toISODate(startOfQuarter(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
|
|
27657
|
-
},
|
|
27658
|
-
{
|
|
27659
|
-
label: "YTD",
|
|
27660
|
-
value: "ytd",
|
|
27661
|
-
range: () => ({ from: toISODate(startOfYear(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
|
|
27662
|
-
}
|
|
27745
|
+
{ label: "Last 7 days", value: "7d" },
|
|
27746
|
+
{ label: "Last 30 days", value: "30d" },
|
|
27747
|
+
{ label: "This Month", value: "month" },
|
|
27748
|
+
{ label: "This Quarter", value: "quarter" },
|
|
27749
|
+
{ label: "YTD", value: "ytd" }
|
|
27663
27750
|
];
|
|
27664
27751
|
DateRangePicker = ({
|
|
27665
27752
|
from: fromProp,
|
|
@@ -27700,7 +27787,8 @@ var init_DateRangePicker = __esm({
|
|
|
27700
27787
|
);
|
|
27701
27788
|
const handlePreset = useCallback(
|
|
27702
27789
|
(preset) => {
|
|
27703
|
-
const range = preset
|
|
27790
|
+
const range = resolvePresetRange(preset);
|
|
27791
|
+
if (range === null) return;
|
|
27704
27792
|
setFrom(range.from);
|
|
27705
27793
|
setTo(range.to);
|
|
27706
27794
|
setActivePreset(preset.value);
|
|
@@ -27708,8 +27796,12 @@ var init_DateRangePicker = __esm({
|
|
|
27708
27796
|
},
|
|
27709
27797
|
[emit]
|
|
27710
27798
|
);
|
|
27799
|
+
const renderablePresets = useMemo(
|
|
27800
|
+
() => presets.filter((p) => p.range !== void 0 || TOKEN_RANGES[p.value] !== void 0),
|
|
27801
|
+
[presets]
|
|
27802
|
+
);
|
|
27711
27803
|
const presetButtons = useMemo(
|
|
27712
|
-
() =>
|
|
27804
|
+
() => renderablePresets.map((preset) => /* @__PURE__ */ jsx(
|
|
27713
27805
|
Button,
|
|
27714
27806
|
{
|
|
27715
27807
|
variant: activePreset === preset.value ? "primary" : "ghost",
|
|
@@ -27719,7 +27811,7 @@ var init_DateRangePicker = __esm({
|
|
|
27719
27811
|
},
|
|
27720
27812
|
preset.value
|
|
27721
27813
|
)),
|
|
27722
|
-
[
|
|
27814
|
+
[renderablePresets, activePreset, handlePreset]
|
|
27723
27815
|
);
|
|
27724
27816
|
return /* @__PURE__ */ jsxs(VStack, { gap: "sm", className: cn(className), children: [
|
|
27725
27817
|
/* @__PURE__ */ jsxs(HStack, { gap: "md", align: "end", children: [
|
|
@@ -27746,7 +27838,7 @@ var init_DateRangePicker = __esm({
|
|
|
27746
27838
|
)
|
|
27747
27839
|
] })
|
|
27748
27840
|
] }),
|
|
27749
|
-
|
|
27841
|
+
renderablePresets.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", wrap: true, children: presetButtons })
|
|
27750
27842
|
] });
|
|
27751
27843
|
};
|
|
27752
27844
|
DateRangePicker.displayName = "DateRangePicker";
|
|
@@ -28188,6 +28280,208 @@ var init_PhysicsCanvas = __esm({
|
|
|
28188
28280
|
};
|
|
28189
28281
|
}
|
|
28190
28282
|
});
|
|
28283
|
+
|
|
28284
|
+
// lib/graphViewLayouts.ts
|
|
28285
|
+
function buildAdjacency(nodeIds, edges) {
|
|
28286
|
+
const known = new Set(nodeIds);
|
|
28287
|
+
const out = /* @__PURE__ */ new Map();
|
|
28288
|
+
const inMap = /* @__PURE__ */ new Map();
|
|
28289
|
+
for (const id of nodeIds) {
|
|
28290
|
+
out.set(id, []);
|
|
28291
|
+
inMap.set(id, []);
|
|
28292
|
+
}
|
|
28293
|
+
for (const edge of edges) {
|
|
28294
|
+
if (!known.has(edge.source) || !known.has(edge.target)) continue;
|
|
28295
|
+
out.get(edge.source)?.push(edge.target);
|
|
28296
|
+
inMap.get(edge.target)?.push(edge.source);
|
|
28297
|
+
}
|
|
28298
|
+
return { out, in: inMap };
|
|
28299
|
+
}
|
|
28300
|
+
function findRoots(nodeIds, adjacency) {
|
|
28301
|
+
return nodeIds.filter((id) => (adjacency.in.get(id)?.length ?? 0) === 0);
|
|
28302
|
+
}
|
|
28303
|
+
function assignLayers(nodeIds, adjacency, roots) {
|
|
28304
|
+
const layer = new Map(nodeIds.map((id) => [id, 0]));
|
|
28305
|
+
const onStack = /* @__PURE__ */ new Set();
|
|
28306
|
+
const visit = (id) => {
|
|
28307
|
+
onStack.add(id);
|
|
28308
|
+
const currentLayer = layer.get(id) ?? 0;
|
|
28309
|
+
for (const next of adjacency.out.get(id) ?? []) {
|
|
28310
|
+
if (onStack.has(next)) continue;
|
|
28311
|
+
const candidate = currentLayer + 1;
|
|
28312
|
+
if (candidate > (layer.get(next) ?? 0)) {
|
|
28313
|
+
layer.set(next, candidate);
|
|
28314
|
+
}
|
|
28315
|
+
visit(next);
|
|
28316
|
+
}
|
|
28317
|
+
onStack.delete(id);
|
|
28318
|
+
};
|
|
28319
|
+
for (const root of roots) visit(root);
|
|
28320
|
+
return layer;
|
|
28321
|
+
}
|
|
28322
|
+
function computeVisitOrder(nodeIds, adjacency, roots) {
|
|
28323
|
+
const order = /* @__PURE__ */ new Map();
|
|
28324
|
+
const visited = /* @__PURE__ */ new Set();
|
|
28325
|
+
let counter = 0;
|
|
28326
|
+
const visit = (id) => {
|
|
28327
|
+
if (visited.has(id)) return;
|
|
28328
|
+
visited.add(id);
|
|
28329
|
+
order.set(id, counter++);
|
|
28330
|
+
for (const next of adjacency.out.get(id) ?? []) visit(next);
|
|
28331
|
+
};
|
|
28332
|
+
for (const root of roots) visit(root);
|
|
28333
|
+
for (const id of nodeIds) {
|
|
28334
|
+
if (!visited.has(id)) order.set(id, counter++);
|
|
28335
|
+
}
|
|
28336
|
+
return order;
|
|
28337
|
+
}
|
|
28338
|
+
function bfsDepthAndOrder(nodeIds, adjacency, roots) {
|
|
28339
|
+
const depth = new Map(nodeIds.map((id) => [id, 0]));
|
|
28340
|
+
const visitOrder = /* @__PURE__ */ new Map();
|
|
28341
|
+
const visited = /* @__PURE__ */ new Set();
|
|
28342
|
+
const queue = [];
|
|
28343
|
+
let counter = 0;
|
|
28344
|
+
for (const root of roots) {
|
|
28345
|
+
if (visited.has(root)) continue;
|
|
28346
|
+
visited.add(root);
|
|
28347
|
+
depth.set(root, 0);
|
|
28348
|
+
visitOrder.set(root, counter++);
|
|
28349
|
+
queue.push(root);
|
|
28350
|
+
}
|
|
28351
|
+
let head = 0;
|
|
28352
|
+
while (head < queue.length) {
|
|
28353
|
+
const id = queue[head++];
|
|
28354
|
+
const d = depth.get(id) ?? 0;
|
|
28355
|
+
for (const next of adjacency.out.get(id) ?? []) {
|
|
28356
|
+
if (visited.has(next)) continue;
|
|
28357
|
+
visited.add(next);
|
|
28358
|
+
depth.set(next, d + 1);
|
|
28359
|
+
visitOrder.set(next, counter++);
|
|
28360
|
+
queue.push(next);
|
|
28361
|
+
}
|
|
28362
|
+
}
|
|
28363
|
+
for (const id of nodeIds) {
|
|
28364
|
+
if (!visited.has(id)) visitOrder.set(id, counter++);
|
|
28365
|
+
}
|
|
28366
|
+
return { depth, visitOrder };
|
|
28367
|
+
}
|
|
28368
|
+
function edgeWalkOrder(nodeIds, adjacency) {
|
|
28369
|
+
const visited = /* @__PURE__ */ new Set();
|
|
28370
|
+
const result = [];
|
|
28371
|
+
for (const start of nodeIds) {
|
|
28372
|
+
if (visited.has(start)) continue;
|
|
28373
|
+
let current = start;
|
|
28374
|
+
while (current !== void 0 && !visited.has(current)) {
|
|
28375
|
+
visited.add(current);
|
|
28376
|
+
result.push(current);
|
|
28377
|
+
const outs = adjacency.out.get(current) ?? [];
|
|
28378
|
+
current = outs.find((next) => !visited.has(next));
|
|
28379
|
+
}
|
|
28380
|
+
}
|
|
28381
|
+
return result;
|
|
28382
|
+
}
|
|
28383
|
+
function groupByTier(nodeIds, tierOf, maxTier) {
|
|
28384
|
+
const groups = Array.from({ length: maxTier + 1 }, () => []);
|
|
28385
|
+
for (const id of nodeIds) {
|
|
28386
|
+
groups[tierOf.get(id) ?? 0].push(id);
|
|
28387
|
+
}
|
|
28388
|
+
return groups;
|
|
28389
|
+
}
|
|
28390
|
+
function distributeAxis(count, start, end) {
|
|
28391
|
+
if (count <= 0) return [];
|
|
28392
|
+
const slot = (end - start) / count;
|
|
28393
|
+
return Array.from({ length: count }, (_, i) => start + slot * (i + 0.5));
|
|
28394
|
+
}
|
|
28395
|
+
function orderByParentPositionThenInput(group, adjacency, positioned, inputIndex) {
|
|
28396
|
+
const withKey = group.map((id) => {
|
|
28397
|
+
const parentValues = (adjacency.in.get(id) ?? []).map((p) => positioned.get(p)).filter((v) => v !== void 0);
|
|
28398
|
+
const avg = parentValues.length > 0 ? parentValues.reduce((a, b) => a + b, 0) / parentValues.length : Number.POSITIVE_INFINITY;
|
|
28399
|
+
return { id, avg, idx: inputIndex.get(id) ?? 0 };
|
|
28400
|
+
});
|
|
28401
|
+
withKey.sort((a, b) => a.avg !== b.avg ? a.avg - b.avg : a.idx - b.idx);
|
|
28402
|
+
return withKey.map((k) => k.id);
|
|
28403
|
+
}
|
|
28404
|
+
function layoutFlow(nodeIds, adjacency, roots, width, height, margin) {
|
|
28405
|
+
const inputIndex = new Map(nodeIds.map((id, i) => [id, i]));
|
|
28406
|
+
const layers = assignLayers(nodeIds, adjacency, roots);
|
|
28407
|
+
const maxLayer = Math.max(...Array.from(layers.values()));
|
|
28408
|
+
const layerGroups = groupByTier(nodeIds, layers, maxLayer);
|
|
28409
|
+
const positions = /* @__PURE__ */ new Map();
|
|
28410
|
+
const yById = /* @__PURE__ */ new Map();
|
|
28411
|
+
for (let l = 0; l <= maxLayer; l++) {
|
|
28412
|
+
const x = margin + l * (width - 2 * margin) / Math.max(1, maxLayer);
|
|
28413
|
+
const ordered2 = orderByParentPositionThenInput(layerGroups[l], adjacency, yById, inputIndex);
|
|
28414
|
+
const ys = distributeAxis(ordered2.length, margin, height - margin);
|
|
28415
|
+
ordered2.forEach((id, i) => {
|
|
28416
|
+
positions.set(id, { id, x, y: ys[i] });
|
|
28417
|
+
yById.set(id, ys[i]);
|
|
28418
|
+
});
|
|
28419
|
+
}
|
|
28420
|
+
return nodeIds.map((id) => positions.get(id));
|
|
28421
|
+
}
|
|
28422
|
+
function layoutTree(nodeIds, adjacency, roots, width, height, margin) {
|
|
28423
|
+
const effectiveRoots = roots.length > 0 ? roots : [nodeIds[0]];
|
|
28424
|
+
const layers = assignLayers(nodeIds, adjacency, effectiveRoots);
|
|
28425
|
+
const maxLayer = Math.max(...Array.from(layers.values()));
|
|
28426
|
+
const visitOrder = computeVisitOrder(nodeIds, adjacency, effectiveRoots);
|
|
28427
|
+
const layerGroups = groupByTier(nodeIds, layers, maxLayer);
|
|
28428
|
+
const positions = /* @__PURE__ */ new Map();
|
|
28429
|
+
for (let l = 0; l <= maxLayer; l++) {
|
|
28430
|
+
const ordered2 = [...layerGroups[l]].sort(
|
|
28431
|
+
(a, b) => (visitOrder.get(a) ?? 0) - (visitOrder.get(b) ?? 0)
|
|
28432
|
+
);
|
|
28433
|
+
const y = margin + l * (height - 2 * margin) / Math.max(1, maxLayer);
|
|
28434
|
+
const xs = distributeAxis(ordered2.length, margin, width - margin);
|
|
28435
|
+
ordered2.forEach((id, i) => positions.set(id, { id, x: xs[i], y }));
|
|
28436
|
+
}
|
|
28437
|
+
return nodeIds.map((id) => positions.get(id));
|
|
28438
|
+
}
|
|
28439
|
+
function layoutRadial(nodeIds, adjacency, roots, width, height, margin) {
|
|
28440
|
+
const cx = width / 2;
|
|
28441
|
+
const cy = height / 2;
|
|
28442
|
+
const maxRadius = Math.min(width, height) / 2 - margin;
|
|
28443
|
+
if (roots.length === 0) {
|
|
28444
|
+
const order = edgeWalkOrder(nodeIds, adjacency);
|
|
28445
|
+
const k = order.length;
|
|
28446
|
+
const positions2 = /* @__PURE__ */ new Map();
|
|
28447
|
+
order.forEach((id, i) => {
|
|
28448
|
+
const angle = i / k * 2 * Math.PI;
|
|
28449
|
+
positions2.set(id, { id, x: cx + maxRadius * Math.cos(angle), y: cy + maxRadius * Math.sin(angle) });
|
|
28450
|
+
});
|
|
28451
|
+
return nodeIds.map((id) => positions2.get(id));
|
|
28452
|
+
}
|
|
28453
|
+
const { depth, visitOrder } = bfsDepthAndOrder(nodeIds, adjacency, roots);
|
|
28454
|
+
const maxDepth = Math.max(...Array.from(depth.values()));
|
|
28455
|
+
const ringGroups = groupByTier(nodeIds, depth, maxDepth);
|
|
28456
|
+
const positions = /* @__PURE__ */ new Map();
|
|
28457
|
+
for (let d = 0; d <= maxDepth; d++) {
|
|
28458
|
+
const ordered2 = [...ringGroups[d]].sort(
|
|
28459
|
+
(a, b) => (visitOrder.get(a) ?? 0) - (visitOrder.get(b) ?? 0)
|
|
28460
|
+
);
|
|
28461
|
+
const radius = d * maxRadius / Math.max(1, maxDepth);
|
|
28462
|
+
const k = ordered2.length;
|
|
28463
|
+
ordered2.forEach((id, i) => {
|
|
28464
|
+
const angle = i / k * 2 * Math.PI;
|
|
28465
|
+
positions.set(id, { id, x: cx + radius * Math.cos(angle), y: cy + radius * Math.sin(angle) });
|
|
28466
|
+
});
|
|
28467
|
+
}
|
|
28468
|
+
return nodeIds.map((id) => positions.get(id));
|
|
28469
|
+
}
|
|
28470
|
+
function computeStaticLayout(mode, input) {
|
|
28471
|
+
const { nodeIds, edges, width, height } = input;
|
|
28472
|
+
const margin = input.margin ?? 40;
|
|
28473
|
+
if (nodeIds.length === 0) return [];
|
|
28474
|
+
if (nodeIds.length === 1) return [{ id: nodeIds[0], x: width / 2, y: height / 2 }];
|
|
28475
|
+
const adjacency = buildAdjacency(nodeIds, edges);
|
|
28476
|
+
const roots = findRoots(nodeIds, adjacency);
|
|
28477
|
+
if (mode === "flow") return layoutFlow(nodeIds, adjacency, roots, width, height, margin);
|
|
28478
|
+
if (mode === "tree") return layoutTree(nodeIds, adjacency, roots, width, height, margin);
|
|
28479
|
+
return layoutRadial(nodeIds, adjacency, roots, width, height, margin);
|
|
28480
|
+
}
|
|
28481
|
+
var init_graphViewLayouts = __esm({
|
|
28482
|
+
"lib/graphViewLayouts.ts"() {
|
|
28483
|
+
}
|
|
28484
|
+
});
|
|
28191
28485
|
function resolveNodeColor(node, groups) {
|
|
28192
28486
|
if (node.color) return node.color;
|
|
28193
28487
|
if (node.group) {
|
|
@@ -28202,6 +28496,7 @@ var init_GraphView = __esm({
|
|
|
28202
28496
|
"use client";
|
|
28203
28497
|
init_cn();
|
|
28204
28498
|
init_atoms();
|
|
28499
|
+
init_graphViewLayouts();
|
|
28205
28500
|
GROUP_COLORS = [
|
|
28206
28501
|
"#3b82f6",
|
|
28207
28502
|
// blue-500
|
|
@@ -28232,11 +28527,13 @@ var init_GraphView = __esm({
|
|
|
28232
28527
|
height: propHeight,
|
|
28233
28528
|
className,
|
|
28234
28529
|
showLabels = true,
|
|
28235
|
-
zoomToFit = true
|
|
28530
|
+
zoomToFit = true,
|
|
28531
|
+
layout = "force"
|
|
28236
28532
|
}) => {
|
|
28237
28533
|
const { t } = useTranslate();
|
|
28238
28534
|
const containerRef = useRef(null);
|
|
28239
28535
|
const animRef = useRef(0);
|
|
28536
|
+
const arrowMarkerId = useId();
|
|
28240
28537
|
const [simNodes, setSimNodes] = useState([]);
|
|
28241
28538
|
const [settled, setSettled] = useState(false);
|
|
28242
28539
|
const [hoveredId, setHoveredId] = useState(null);
|
|
@@ -28293,6 +28590,22 @@ var init_GraphView = __esm({
|
|
|
28293
28590
|
fy: 0
|
|
28294
28591
|
};
|
|
28295
28592
|
});
|
|
28593
|
+
if (layout !== "force") {
|
|
28594
|
+
const points = computeStaticLayout(layout, {
|
|
28595
|
+
nodeIds: nodes.map((n) => n.id),
|
|
28596
|
+
edges,
|
|
28597
|
+
width: w,
|
|
28598
|
+
height: h
|
|
28599
|
+
});
|
|
28600
|
+
const pointById = new Map(points.map((p) => [p.id, p]));
|
|
28601
|
+
const laidOut = initialNodes.map((node) => {
|
|
28602
|
+
const point = pointById.get(node.id);
|
|
28603
|
+
return point ? { ...node, x: point.x, y: point.y } : node;
|
|
28604
|
+
});
|
|
28605
|
+
setSimNodes(laidOut);
|
|
28606
|
+
setSettled(true);
|
|
28607
|
+
return;
|
|
28608
|
+
}
|
|
28296
28609
|
let iterations = 0;
|
|
28297
28610
|
const maxIterations = 120;
|
|
28298
28611
|
let currentNodes = initialNodes;
|
|
@@ -28361,7 +28674,7 @@ var init_GraphView = __esm({
|
|
|
28361
28674
|
return () => {
|
|
28362
28675
|
cancelAnimationFrame(animRef.current);
|
|
28363
28676
|
};
|
|
28364
|
-
}, [nodes, edges, w, h, groups]);
|
|
28677
|
+
}, [nodes, edges, w, h, groups, layout]);
|
|
28365
28678
|
const viewBox = useMemo(() => {
|
|
28366
28679
|
if (!zoomToFit || !settled || simNodes.length === 0) {
|
|
28367
28680
|
return `0 0 ${w} ${h}`;
|
|
@@ -28436,6 +28749,19 @@ var init_GraphView = __esm({
|
|
|
28436
28749
|
viewBox,
|
|
28437
28750
|
preserveAspectRatio: "xMidYMid meet",
|
|
28438
28751
|
children: [
|
|
28752
|
+
layout !== "force" && /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
|
|
28753
|
+
"marker",
|
|
28754
|
+
{
|
|
28755
|
+
id: arrowMarkerId,
|
|
28756
|
+
viewBox: "0 0 10 10",
|
|
28757
|
+
refX: "9",
|
|
28758
|
+
refY: "5",
|
|
28759
|
+
markerWidth: "6",
|
|
28760
|
+
markerHeight: "6",
|
|
28761
|
+
orient: "auto-start-reverse",
|
|
28762
|
+
children: /* @__PURE__ */ jsx("path", { d: "M0,0 L10,5 L0,10 z", fill: "currentColor" })
|
|
28763
|
+
}
|
|
28764
|
+
) }),
|
|
28439
28765
|
edges.map((edge, idx) => {
|
|
28440
28766
|
const source = nodeMap.get(edge.source);
|
|
28441
28767
|
const target = nodeMap.get(edge.target);
|
|
@@ -28450,8 +28776,10 @@ var init_GraphView = __esm({
|
|
|
28450
28776
|
x2: target.x,
|
|
28451
28777
|
y2: target.y,
|
|
28452
28778
|
stroke: edge.color ?? DEFAULT_EDGE_COLOR,
|
|
28779
|
+
color: edge.color ?? DEFAULT_EDGE_COLOR,
|
|
28453
28780
|
strokeWidth: 1.5,
|
|
28454
|
-
opacity: isHighlighted ? 0.8 : 0.15
|
|
28781
|
+
opacity: isHighlighted ? 0.8 : 0.15,
|
|
28782
|
+
markerEnd: layout !== "force" ? `url(#${arrowMarkerId})` : void 0
|
|
28455
28783
|
}
|
|
28456
28784
|
),
|
|
28457
28785
|
showLabels && edge.label && /* @__PURE__ */ jsx(
|