@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/runtime/index.cjs
CHANGED
|
@@ -11940,7 +11940,10 @@ var init_LearningCanvas = __esm({
|
|
|
11940
11940
|
ctx.fillRect(0, 0, width, height);
|
|
11941
11941
|
}
|
|
11942
11942
|
for (const shape of shapes) {
|
|
11943
|
-
drawShape(ctx, shape, width, height);
|
|
11943
|
+
if (shape.type !== "text") drawShape(ctx, shape, width, height);
|
|
11944
|
+
}
|
|
11945
|
+
for (const shape of shapes) {
|
|
11946
|
+
if (shape.type === "text") drawShape(ctx, shape, width, height);
|
|
11944
11947
|
}
|
|
11945
11948
|
}, [width, height, backgroundColor, shapes]);
|
|
11946
11949
|
React85.useEffect(() => {
|
|
@@ -13503,7 +13506,7 @@ var init_AlgorithmCanvas = __esm({
|
|
|
13503
13506
|
DEFAULT_CELL_COLOR = "#e5e7eb";
|
|
13504
13507
|
DEFAULT_POINTER_COLOR = "#dc2626";
|
|
13505
13508
|
POINTER_BAND = 34;
|
|
13506
|
-
TOP_PAD =
|
|
13509
|
+
TOP_PAD = 26;
|
|
13507
13510
|
AlgorithmCanvas = ({
|
|
13508
13511
|
className,
|
|
13509
13512
|
width = 600,
|
|
@@ -24914,6 +24917,7 @@ var init_FilterGroup = __esm({
|
|
|
24914
24917
|
init_Badge();
|
|
24915
24918
|
init_Stack();
|
|
24916
24919
|
init_Icon();
|
|
24920
|
+
init_RangeSlider();
|
|
24917
24921
|
init_useEventBus();
|
|
24918
24922
|
init_useQuerySingleton();
|
|
24919
24923
|
resolveFilterType = (filter) => filter.filterType ?? filter.type;
|
|
@@ -25108,6 +25112,35 @@ var init_FilterGroup = __esm({
|
|
|
25108
25112
|
onClear: () => handleFilterSelect(`${filter.field}_to`, null)
|
|
25109
25113
|
}
|
|
25110
25114
|
)
|
|
25115
|
+
] }) : resolveFilterType(filter) === "numberrange" || resolveFilterType(filter) === "number-range" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
25116
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
25117
|
+
RangeSlider,
|
|
25118
|
+
{
|
|
25119
|
+
min: filter.min ?? 0,
|
|
25120
|
+
max: filter.max ?? 100,
|
|
25121
|
+
step: filter.step ?? 1,
|
|
25122
|
+
value: Number(
|
|
25123
|
+
selectedValues[`${filter.field}_min`] ?? filter.min ?? 0
|
|
25124
|
+
),
|
|
25125
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_min`, String(v)),
|
|
25126
|
+
showTooltip: true,
|
|
25127
|
+
"aria-label": t("filterGroup.from")
|
|
25128
|
+
}
|
|
25129
|
+
),
|
|
25130
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
25131
|
+
RangeSlider,
|
|
25132
|
+
{
|
|
25133
|
+
min: filter.min ?? 0,
|
|
25134
|
+
max: filter.max ?? 100,
|
|
25135
|
+
step: filter.step ?? 1,
|
|
25136
|
+
value: Number(
|
|
25137
|
+
selectedValues[`${filter.field}_max`] ?? filter.max ?? 100
|
|
25138
|
+
),
|
|
25139
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_max`, String(v)),
|
|
25140
|
+
showTooltip: true,
|
|
25141
|
+
"aria-label": t("filterGroup.to")
|
|
25142
|
+
}
|
|
25143
|
+
)
|
|
25111
25144
|
] }) : resolveFilterType(filter) === "text" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
25112
25145
|
Input,
|
|
25113
25146
|
{
|
|
@@ -25190,6 +25223,36 @@ var init_FilterGroup = __esm({
|
|
|
25190
25223
|
className: "text-sm min-w-[100px]"
|
|
25191
25224
|
}
|
|
25192
25225
|
)
|
|
25226
|
+
] }) : resolveFilterType(filter) === "numberrange" || resolveFilterType(filter) === "number-range" ? /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
25227
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
25228
|
+
RangeSlider,
|
|
25229
|
+
{
|
|
25230
|
+
min: filter.min ?? 0,
|
|
25231
|
+
max: filter.max ?? 100,
|
|
25232
|
+
step: filter.step ?? 1,
|
|
25233
|
+
value: Number(
|
|
25234
|
+
selectedValues[`${filter.field}_min`] ?? filter.min ?? 0
|
|
25235
|
+
),
|
|
25236
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_min`, String(v)),
|
|
25237
|
+
className: "min-w-[100px]",
|
|
25238
|
+
"aria-label": t("filterGroup.from")
|
|
25239
|
+
}
|
|
25240
|
+
),
|
|
25241
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "-" }),
|
|
25242
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
25243
|
+
RangeSlider,
|
|
25244
|
+
{
|
|
25245
|
+
min: filter.min ?? 0,
|
|
25246
|
+
max: filter.max ?? 100,
|
|
25247
|
+
step: filter.step ?? 1,
|
|
25248
|
+
value: Number(
|
|
25249
|
+
selectedValues[`${filter.field}_max`] ?? filter.max ?? 100
|
|
25250
|
+
),
|
|
25251
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_max`, String(v)),
|
|
25252
|
+
className: "min-w-[100px]",
|
|
25253
|
+
"aria-label": t("filterGroup.to")
|
|
25254
|
+
}
|
|
25255
|
+
)
|
|
25193
25256
|
] }) : resolveFilterType(filter) === "text" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
25194
25257
|
Input,
|
|
25195
25258
|
{
|
|
@@ -25308,6 +25371,38 @@ var init_FilterGroup = __esm({
|
|
|
25308
25371
|
className: "min-w-[130px]"
|
|
25309
25372
|
}
|
|
25310
25373
|
)
|
|
25374
|
+
] }) : resolveFilterType(filter) === "numberrange" || resolveFilterType(filter) === "number-range" ? /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
25375
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
25376
|
+
RangeSlider,
|
|
25377
|
+
{
|
|
25378
|
+
min: filter.min ?? 0,
|
|
25379
|
+
max: filter.max ?? 100,
|
|
25380
|
+
step: filter.step ?? 1,
|
|
25381
|
+
value: Number(
|
|
25382
|
+
selectedValues[`${filter.field}_min`] ?? filter.min ?? 0
|
|
25383
|
+
),
|
|
25384
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_min`, String(v)),
|
|
25385
|
+
showTooltip: true,
|
|
25386
|
+
className: "min-w-[130px]",
|
|
25387
|
+
"aria-label": t("filterGroup.from")
|
|
25388
|
+
}
|
|
25389
|
+
),
|
|
25390
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "-" }),
|
|
25391
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
25392
|
+
RangeSlider,
|
|
25393
|
+
{
|
|
25394
|
+
min: filter.min ?? 0,
|
|
25395
|
+
max: filter.max ?? 100,
|
|
25396
|
+
step: filter.step ?? 1,
|
|
25397
|
+
value: Number(
|
|
25398
|
+
selectedValues[`${filter.field}_max`] ?? filter.max ?? 100
|
|
25399
|
+
),
|
|
25400
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_max`, String(v)),
|
|
25401
|
+
showTooltip: true,
|
|
25402
|
+
className: "min-w-[130px]",
|
|
25403
|
+
"aria-label": t("filterGroup.to")
|
|
25404
|
+
}
|
|
25405
|
+
)
|
|
25311
25406
|
] }) : resolveFilterType(filter) === "text" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
25312
25407
|
Input,
|
|
25313
25408
|
{
|
|
@@ -27207,7 +27302,12 @@ function daysAgo(n) {
|
|
|
27207
27302
|
d.setDate(d.getDate() - n);
|
|
27208
27303
|
return d;
|
|
27209
27304
|
}
|
|
27210
|
-
|
|
27305
|
+
function resolvePresetRange(preset) {
|
|
27306
|
+
if (typeof preset.range === "function") return preset.range();
|
|
27307
|
+
if (preset.range) return preset.range;
|
|
27308
|
+
return TOKEN_RANGES[preset.value]?.() ?? null;
|
|
27309
|
+
}
|
|
27310
|
+
var TOKEN_RANGES, DEFAULT_PRESETS, DateRangePicker;
|
|
27211
27311
|
var init_DateRangePicker = __esm({
|
|
27212
27312
|
"components/core/molecules/DateRangePicker.tsx"() {
|
|
27213
27313
|
"use client";
|
|
@@ -27217,32 +27317,19 @@ var init_DateRangePicker = __esm({
|
|
|
27217
27317
|
init_Stack();
|
|
27218
27318
|
init_Typography();
|
|
27219
27319
|
init_useEventBus();
|
|
27320
|
+
TOKEN_RANGES = {
|
|
27321
|
+
"7d": () => ({ from: toISODate(daysAgo(7)), to: toISODate(/* @__PURE__ */ new Date()) }),
|
|
27322
|
+
"30d": () => ({ from: toISODate(daysAgo(30)), to: toISODate(/* @__PURE__ */ new Date()) }),
|
|
27323
|
+
month: () => ({ from: toISODate(startOfMonth(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) }),
|
|
27324
|
+
quarter: () => ({ from: toISODate(startOfQuarter(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) }),
|
|
27325
|
+
ytd: () => ({ from: toISODate(startOfYear(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
|
|
27326
|
+
};
|
|
27220
27327
|
DEFAULT_PRESETS = [
|
|
27221
|
-
{
|
|
27222
|
-
|
|
27223
|
-
|
|
27224
|
-
|
|
27225
|
-
}
|
|
27226
|
-
{
|
|
27227
|
-
label: "Last 30 days",
|
|
27228
|
-
value: "30d",
|
|
27229
|
-
range: () => ({ from: toISODate(daysAgo(30)), to: toISODate(/* @__PURE__ */ new Date()) })
|
|
27230
|
-
},
|
|
27231
|
-
{
|
|
27232
|
-
label: "This Month",
|
|
27233
|
-
value: "month",
|
|
27234
|
-
range: () => ({ from: toISODate(startOfMonth(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
|
|
27235
|
-
},
|
|
27236
|
-
{
|
|
27237
|
-
label: "This Quarter",
|
|
27238
|
-
value: "quarter",
|
|
27239
|
-
range: () => ({ from: toISODate(startOfQuarter(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
|
|
27240
|
-
},
|
|
27241
|
-
{
|
|
27242
|
-
label: "YTD",
|
|
27243
|
-
value: "ytd",
|
|
27244
|
-
range: () => ({ from: toISODate(startOfYear(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
|
|
27245
|
-
}
|
|
27328
|
+
{ label: "Last 7 days", value: "7d" },
|
|
27329
|
+
{ label: "Last 30 days", value: "30d" },
|
|
27330
|
+
{ label: "This Month", value: "month" },
|
|
27331
|
+
{ label: "This Quarter", value: "quarter" },
|
|
27332
|
+
{ label: "YTD", value: "ytd" }
|
|
27246
27333
|
];
|
|
27247
27334
|
DateRangePicker = ({
|
|
27248
27335
|
from: fromProp,
|
|
@@ -27283,7 +27370,8 @@ var init_DateRangePicker = __esm({
|
|
|
27283
27370
|
);
|
|
27284
27371
|
const handlePreset = React85.useCallback(
|
|
27285
27372
|
(preset) => {
|
|
27286
|
-
const range = preset
|
|
27373
|
+
const range = resolvePresetRange(preset);
|
|
27374
|
+
if (range === null) return;
|
|
27287
27375
|
setFrom(range.from);
|
|
27288
27376
|
setTo(range.to);
|
|
27289
27377
|
setActivePreset(preset.value);
|
|
@@ -27291,8 +27379,12 @@ var init_DateRangePicker = __esm({
|
|
|
27291
27379
|
},
|
|
27292
27380
|
[emit]
|
|
27293
27381
|
);
|
|
27382
|
+
const renderablePresets = React85.useMemo(
|
|
27383
|
+
() => presets.filter((p) => p.range !== void 0 || TOKEN_RANGES[p.value] !== void 0),
|
|
27384
|
+
[presets]
|
|
27385
|
+
);
|
|
27294
27386
|
const presetButtons = React85.useMemo(
|
|
27295
|
-
() =>
|
|
27387
|
+
() => renderablePresets.map((preset) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
27296
27388
|
Button,
|
|
27297
27389
|
{
|
|
27298
27390
|
variant: activePreset === preset.value ? "primary" : "ghost",
|
|
@@ -27302,7 +27394,7 @@ var init_DateRangePicker = __esm({
|
|
|
27302
27394
|
},
|
|
27303
27395
|
preset.value
|
|
27304
27396
|
)),
|
|
27305
|
-
[
|
|
27397
|
+
[renderablePresets, activePreset, handlePreset]
|
|
27306
27398
|
);
|
|
27307
27399
|
return /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", className: cn(className), children: [
|
|
27308
27400
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "md", align: "end", children: [
|
|
@@ -27329,7 +27421,7 @@ var init_DateRangePicker = __esm({
|
|
|
27329
27421
|
)
|
|
27330
27422
|
] })
|
|
27331
27423
|
] }),
|
|
27332
|
-
|
|
27424
|
+
renderablePresets.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", wrap: true, children: presetButtons })
|
|
27333
27425
|
] });
|
|
27334
27426
|
};
|
|
27335
27427
|
DateRangePicker.displayName = "DateRangePicker";
|
|
@@ -27771,6 +27863,208 @@ var init_PhysicsCanvas = __esm({
|
|
|
27771
27863
|
};
|
|
27772
27864
|
}
|
|
27773
27865
|
});
|
|
27866
|
+
|
|
27867
|
+
// lib/graphViewLayouts.ts
|
|
27868
|
+
function buildAdjacency(nodeIds, edges) {
|
|
27869
|
+
const known = new Set(nodeIds);
|
|
27870
|
+
const out = /* @__PURE__ */ new Map();
|
|
27871
|
+
const inMap = /* @__PURE__ */ new Map();
|
|
27872
|
+
for (const id of nodeIds) {
|
|
27873
|
+
out.set(id, []);
|
|
27874
|
+
inMap.set(id, []);
|
|
27875
|
+
}
|
|
27876
|
+
for (const edge of edges) {
|
|
27877
|
+
if (!known.has(edge.source) || !known.has(edge.target)) continue;
|
|
27878
|
+
out.get(edge.source)?.push(edge.target);
|
|
27879
|
+
inMap.get(edge.target)?.push(edge.source);
|
|
27880
|
+
}
|
|
27881
|
+
return { out, in: inMap };
|
|
27882
|
+
}
|
|
27883
|
+
function findRoots(nodeIds, adjacency) {
|
|
27884
|
+
return nodeIds.filter((id) => (adjacency.in.get(id)?.length ?? 0) === 0);
|
|
27885
|
+
}
|
|
27886
|
+
function assignLayers(nodeIds, adjacency, roots) {
|
|
27887
|
+
const layer = new Map(nodeIds.map((id) => [id, 0]));
|
|
27888
|
+
const onStack = /* @__PURE__ */ new Set();
|
|
27889
|
+
const visit = (id) => {
|
|
27890
|
+
onStack.add(id);
|
|
27891
|
+
const currentLayer = layer.get(id) ?? 0;
|
|
27892
|
+
for (const next of adjacency.out.get(id) ?? []) {
|
|
27893
|
+
if (onStack.has(next)) continue;
|
|
27894
|
+
const candidate = currentLayer + 1;
|
|
27895
|
+
if (candidate > (layer.get(next) ?? 0)) {
|
|
27896
|
+
layer.set(next, candidate);
|
|
27897
|
+
}
|
|
27898
|
+
visit(next);
|
|
27899
|
+
}
|
|
27900
|
+
onStack.delete(id);
|
|
27901
|
+
};
|
|
27902
|
+
for (const root of roots) visit(root);
|
|
27903
|
+
return layer;
|
|
27904
|
+
}
|
|
27905
|
+
function computeVisitOrder(nodeIds, adjacency, roots) {
|
|
27906
|
+
const order = /* @__PURE__ */ new Map();
|
|
27907
|
+
const visited = /* @__PURE__ */ new Set();
|
|
27908
|
+
let counter = 0;
|
|
27909
|
+
const visit = (id) => {
|
|
27910
|
+
if (visited.has(id)) return;
|
|
27911
|
+
visited.add(id);
|
|
27912
|
+
order.set(id, counter++);
|
|
27913
|
+
for (const next of adjacency.out.get(id) ?? []) visit(next);
|
|
27914
|
+
};
|
|
27915
|
+
for (const root of roots) visit(root);
|
|
27916
|
+
for (const id of nodeIds) {
|
|
27917
|
+
if (!visited.has(id)) order.set(id, counter++);
|
|
27918
|
+
}
|
|
27919
|
+
return order;
|
|
27920
|
+
}
|
|
27921
|
+
function bfsDepthAndOrder(nodeIds, adjacency, roots) {
|
|
27922
|
+
const depth = new Map(nodeIds.map((id) => [id, 0]));
|
|
27923
|
+
const visitOrder = /* @__PURE__ */ new Map();
|
|
27924
|
+
const visited = /* @__PURE__ */ new Set();
|
|
27925
|
+
const queue = [];
|
|
27926
|
+
let counter = 0;
|
|
27927
|
+
for (const root of roots) {
|
|
27928
|
+
if (visited.has(root)) continue;
|
|
27929
|
+
visited.add(root);
|
|
27930
|
+
depth.set(root, 0);
|
|
27931
|
+
visitOrder.set(root, counter++);
|
|
27932
|
+
queue.push(root);
|
|
27933
|
+
}
|
|
27934
|
+
let head = 0;
|
|
27935
|
+
while (head < queue.length) {
|
|
27936
|
+
const id = queue[head++];
|
|
27937
|
+
const d = depth.get(id) ?? 0;
|
|
27938
|
+
for (const next of adjacency.out.get(id) ?? []) {
|
|
27939
|
+
if (visited.has(next)) continue;
|
|
27940
|
+
visited.add(next);
|
|
27941
|
+
depth.set(next, d + 1);
|
|
27942
|
+
visitOrder.set(next, counter++);
|
|
27943
|
+
queue.push(next);
|
|
27944
|
+
}
|
|
27945
|
+
}
|
|
27946
|
+
for (const id of nodeIds) {
|
|
27947
|
+
if (!visited.has(id)) visitOrder.set(id, counter++);
|
|
27948
|
+
}
|
|
27949
|
+
return { depth, visitOrder };
|
|
27950
|
+
}
|
|
27951
|
+
function edgeWalkOrder(nodeIds, adjacency) {
|
|
27952
|
+
const visited = /* @__PURE__ */ new Set();
|
|
27953
|
+
const result = [];
|
|
27954
|
+
for (const start of nodeIds) {
|
|
27955
|
+
if (visited.has(start)) continue;
|
|
27956
|
+
let current = start;
|
|
27957
|
+
while (current !== void 0 && !visited.has(current)) {
|
|
27958
|
+
visited.add(current);
|
|
27959
|
+
result.push(current);
|
|
27960
|
+
const outs = adjacency.out.get(current) ?? [];
|
|
27961
|
+
current = outs.find((next) => !visited.has(next));
|
|
27962
|
+
}
|
|
27963
|
+
}
|
|
27964
|
+
return result;
|
|
27965
|
+
}
|
|
27966
|
+
function groupByTier(nodeIds, tierOf, maxTier) {
|
|
27967
|
+
const groups = Array.from({ length: maxTier + 1 }, () => []);
|
|
27968
|
+
for (const id of nodeIds) {
|
|
27969
|
+
groups[tierOf.get(id) ?? 0].push(id);
|
|
27970
|
+
}
|
|
27971
|
+
return groups;
|
|
27972
|
+
}
|
|
27973
|
+
function distributeAxis(count, start, end) {
|
|
27974
|
+
if (count <= 0) return [];
|
|
27975
|
+
const slot = (end - start) / count;
|
|
27976
|
+
return Array.from({ length: count }, (_, i) => start + slot * (i + 0.5));
|
|
27977
|
+
}
|
|
27978
|
+
function orderByParentPositionThenInput(group, adjacency, positioned, inputIndex) {
|
|
27979
|
+
const withKey = group.map((id) => {
|
|
27980
|
+
const parentValues = (adjacency.in.get(id) ?? []).map((p) => positioned.get(p)).filter((v) => v !== void 0);
|
|
27981
|
+
const avg = parentValues.length > 0 ? parentValues.reduce((a, b) => a + b, 0) / parentValues.length : Number.POSITIVE_INFINITY;
|
|
27982
|
+
return { id, avg, idx: inputIndex.get(id) ?? 0 };
|
|
27983
|
+
});
|
|
27984
|
+
withKey.sort((a, b) => a.avg !== b.avg ? a.avg - b.avg : a.idx - b.idx);
|
|
27985
|
+
return withKey.map((k) => k.id);
|
|
27986
|
+
}
|
|
27987
|
+
function layoutFlow(nodeIds, adjacency, roots, width, height, margin) {
|
|
27988
|
+
const inputIndex = new Map(nodeIds.map((id, i) => [id, i]));
|
|
27989
|
+
const layers = assignLayers(nodeIds, adjacency, roots);
|
|
27990
|
+
const maxLayer = Math.max(...Array.from(layers.values()));
|
|
27991
|
+
const layerGroups = groupByTier(nodeIds, layers, maxLayer);
|
|
27992
|
+
const positions = /* @__PURE__ */ new Map();
|
|
27993
|
+
const yById = /* @__PURE__ */ new Map();
|
|
27994
|
+
for (let l = 0; l <= maxLayer; l++) {
|
|
27995
|
+
const x = margin + l * (width - 2 * margin) / Math.max(1, maxLayer);
|
|
27996
|
+
const ordered2 = orderByParentPositionThenInput(layerGroups[l], adjacency, yById, inputIndex);
|
|
27997
|
+
const ys = distributeAxis(ordered2.length, margin, height - margin);
|
|
27998
|
+
ordered2.forEach((id, i) => {
|
|
27999
|
+
positions.set(id, { id, x, y: ys[i] });
|
|
28000
|
+
yById.set(id, ys[i]);
|
|
28001
|
+
});
|
|
28002
|
+
}
|
|
28003
|
+
return nodeIds.map((id) => positions.get(id));
|
|
28004
|
+
}
|
|
28005
|
+
function layoutTree(nodeIds, adjacency, roots, width, height, margin) {
|
|
28006
|
+
const effectiveRoots = roots.length > 0 ? roots : [nodeIds[0]];
|
|
28007
|
+
const layers = assignLayers(nodeIds, adjacency, effectiveRoots);
|
|
28008
|
+
const maxLayer = Math.max(...Array.from(layers.values()));
|
|
28009
|
+
const visitOrder = computeVisitOrder(nodeIds, adjacency, effectiveRoots);
|
|
28010
|
+
const layerGroups = groupByTier(nodeIds, layers, maxLayer);
|
|
28011
|
+
const positions = /* @__PURE__ */ new Map();
|
|
28012
|
+
for (let l = 0; l <= maxLayer; l++) {
|
|
28013
|
+
const ordered2 = [...layerGroups[l]].sort(
|
|
28014
|
+
(a, b) => (visitOrder.get(a) ?? 0) - (visitOrder.get(b) ?? 0)
|
|
28015
|
+
);
|
|
28016
|
+
const y = margin + l * (height - 2 * margin) / Math.max(1, maxLayer);
|
|
28017
|
+
const xs = distributeAxis(ordered2.length, margin, width - margin);
|
|
28018
|
+
ordered2.forEach((id, i) => positions.set(id, { id, x: xs[i], y }));
|
|
28019
|
+
}
|
|
28020
|
+
return nodeIds.map((id) => positions.get(id));
|
|
28021
|
+
}
|
|
28022
|
+
function layoutRadial(nodeIds, adjacency, roots, width, height, margin) {
|
|
28023
|
+
const cx = width / 2;
|
|
28024
|
+
const cy = height / 2;
|
|
28025
|
+
const maxRadius = Math.min(width, height) / 2 - margin;
|
|
28026
|
+
if (roots.length === 0) {
|
|
28027
|
+
const order = edgeWalkOrder(nodeIds, adjacency);
|
|
28028
|
+
const k = order.length;
|
|
28029
|
+
const positions2 = /* @__PURE__ */ new Map();
|
|
28030
|
+
order.forEach((id, i) => {
|
|
28031
|
+
const angle = i / k * 2 * Math.PI;
|
|
28032
|
+
positions2.set(id, { id, x: cx + maxRadius * Math.cos(angle), y: cy + maxRadius * Math.sin(angle) });
|
|
28033
|
+
});
|
|
28034
|
+
return nodeIds.map((id) => positions2.get(id));
|
|
28035
|
+
}
|
|
28036
|
+
const { depth, visitOrder } = bfsDepthAndOrder(nodeIds, adjacency, roots);
|
|
28037
|
+
const maxDepth = Math.max(...Array.from(depth.values()));
|
|
28038
|
+
const ringGroups = groupByTier(nodeIds, depth, maxDepth);
|
|
28039
|
+
const positions = /* @__PURE__ */ new Map();
|
|
28040
|
+
for (let d = 0; d <= maxDepth; d++) {
|
|
28041
|
+
const ordered2 = [...ringGroups[d]].sort(
|
|
28042
|
+
(a, b) => (visitOrder.get(a) ?? 0) - (visitOrder.get(b) ?? 0)
|
|
28043
|
+
);
|
|
28044
|
+
const radius = d * maxRadius / Math.max(1, maxDepth);
|
|
28045
|
+
const k = ordered2.length;
|
|
28046
|
+
ordered2.forEach((id, i) => {
|
|
28047
|
+
const angle = i / k * 2 * Math.PI;
|
|
28048
|
+
positions.set(id, { id, x: cx + radius * Math.cos(angle), y: cy + radius * Math.sin(angle) });
|
|
28049
|
+
});
|
|
28050
|
+
}
|
|
28051
|
+
return nodeIds.map((id) => positions.get(id));
|
|
28052
|
+
}
|
|
28053
|
+
function computeStaticLayout(mode, input) {
|
|
28054
|
+
const { nodeIds, edges, width, height } = input;
|
|
28055
|
+
const margin = input.margin ?? 40;
|
|
28056
|
+
if (nodeIds.length === 0) return [];
|
|
28057
|
+
if (nodeIds.length === 1) return [{ id: nodeIds[0], x: width / 2, y: height / 2 }];
|
|
28058
|
+
const adjacency = buildAdjacency(nodeIds, edges);
|
|
28059
|
+
const roots = findRoots(nodeIds, adjacency);
|
|
28060
|
+
if (mode === "flow") return layoutFlow(nodeIds, adjacency, roots, width, height, margin);
|
|
28061
|
+
if (mode === "tree") return layoutTree(nodeIds, adjacency, roots, width, height, margin);
|
|
28062
|
+
return layoutRadial(nodeIds, adjacency, roots, width, height, margin);
|
|
28063
|
+
}
|
|
28064
|
+
var init_graphViewLayouts = __esm({
|
|
28065
|
+
"lib/graphViewLayouts.ts"() {
|
|
28066
|
+
}
|
|
28067
|
+
});
|
|
27774
28068
|
function resolveNodeColor(node, groups) {
|
|
27775
28069
|
if (node.color) return node.color;
|
|
27776
28070
|
if (node.group) {
|
|
@@ -27785,6 +28079,7 @@ var init_GraphView = __esm({
|
|
|
27785
28079
|
"use client";
|
|
27786
28080
|
init_cn();
|
|
27787
28081
|
init_atoms();
|
|
28082
|
+
init_graphViewLayouts();
|
|
27788
28083
|
GROUP_COLORS = [
|
|
27789
28084
|
"#3b82f6",
|
|
27790
28085
|
// blue-500
|
|
@@ -27815,11 +28110,13 @@ var init_GraphView = __esm({
|
|
|
27815
28110
|
height: propHeight,
|
|
27816
28111
|
className,
|
|
27817
28112
|
showLabels = true,
|
|
27818
|
-
zoomToFit = true
|
|
28113
|
+
zoomToFit = true,
|
|
28114
|
+
layout = "force"
|
|
27819
28115
|
}) => {
|
|
27820
28116
|
const { t } = hooks.useTranslate();
|
|
27821
28117
|
const containerRef = React85.useRef(null);
|
|
27822
28118
|
const animRef = React85.useRef(0);
|
|
28119
|
+
const arrowMarkerId = React85.useId();
|
|
27823
28120
|
const [simNodes, setSimNodes] = React85.useState([]);
|
|
27824
28121
|
const [settled, setSettled] = React85.useState(false);
|
|
27825
28122
|
const [hoveredId, setHoveredId] = React85.useState(null);
|
|
@@ -27876,6 +28173,22 @@ var init_GraphView = __esm({
|
|
|
27876
28173
|
fy: 0
|
|
27877
28174
|
};
|
|
27878
28175
|
});
|
|
28176
|
+
if (layout !== "force") {
|
|
28177
|
+
const points = computeStaticLayout(layout, {
|
|
28178
|
+
nodeIds: nodes.map((n) => n.id),
|
|
28179
|
+
edges,
|
|
28180
|
+
width: w,
|
|
28181
|
+
height: h
|
|
28182
|
+
});
|
|
28183
|
+
const pointById = new Map(points.map((p) => [p.id, p]));
|
|
28184
|
+
const laidOut = initialNodes.map((node) => {
|
|
28185
|
+
const point = pointById.get(node.id);
|
|
28186
|
+
return point ? { ...node, x: point.x, y: point.y } : node;
|
|
28187
|
+
});
|
|
28188
|
+
setSimNodes(laidOut);
|
|
28189
|
+
setSettled(true);
|
|
28190
|
+
return;
|
|
28191
|
+
}
|
|
27879
28192
|
let iterations = 0;
|
|
27880
28193
|
const maxIterations = 120;
|
|
27881
28194
|
let currentNodes = initialNodes;
|
|
@@ -27944,7 +28257,7 @@ var init_GraphView = __esm({
|
|
|
27944
28257
|
return () => {
|
|
27945
28258
|
cancelAnimationFrame(animRef.current);
|
|
27946
28259
|
};
|
|
27947
|
-
}, [nodes, edges, w, h, groups]);
|
|
28260
|
+
}, [nodes, edges, w, h, groups, layout]);
|
|
27948
28261
|
const viewBox = React85.useMemo(() => {
|
|
27949
28262
|
if (!zoomToFit || !settled || simNodes.length === 0) {
|
|
27950
28263
|
return `0 0 ${w} ${h}`;
|
|
@@ -28019,6 +28332,19 @@ var init_GraphView = __esm({
|
|
|
28019
28332
|
viewBox,
|
|
28020
28333
|
preserveAspectRatio: "xMidYMid meet",
|
|
28021
28334
|
children: [
|
|
28335
|
+
layout !== "force" && /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
28336
|
+
"marker",
|
|
28337
|
+
{
|
|
28338
|
+
id: arrowMarkerId,
|
|
28339
|
+
viewBox: "0 0 10 10",
|
|
28340
|
+
refX: "9",
|
|
28341
|
+
refY: "5",
|
|
28342
|
+
markerWidth: "6",
|
|
28343
|
+
markerHeight: "6",
|
|
28344
|
+
orient: "auto-start-reverse",
|
|
28345
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M0,0 L10,5 L0,10 z", fill: "currentColor" })
|
|
28346
|
+
}
|
|
28347
|
+
) }),
|
|
28022
28348
|
edges.map((edge, idx) => {
|
|
28023
28349
|
const source = nodeMap.get(edge.source);
|
|
28024
28350
|
const target = nodeMap.get(edge.target);
|
|
@@ -28033,8 +28359,10 @@ var init_GraphView = __esm({
|
|
|
28033
28359
|
x2: target.x,
|
|
28034
28360
|
y2: target.y,
|
|
28035
28361
|
stroke: edge.color ?? DEFAULT_EDGE_COLOR,
|
|
28362
|
+
color: edge.color ?? DEFAULT_EDGE_COLOR,
|
|
28036
28363
|
strokeWidth: 1.5,
|
|
28037
|
-
opacity: isHighlighted ? 0.8 : 0.15
|
|
28364
|
+
opacity: isHighlighted ? 0.8 : 0.15,
|
|
28365
|
+
markerEnd: layout !== "force" ? `url(#${arrowMarkerId})` : void 0
|
|
28038
28366
|
}
|
|
28039
28367
|
),
|
|
28040
28368
|
showLabels && edge.label && /* @__PURE__ */ jsxRuntime.jsx(
|