@yuneta/gobj-ui 7.23.74 → 7.23.75
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/README.md +66 -12
- package/dist/gobj-ui.cjs.js +493 -135
- package/dist/gobj-ui.es.js +493 -135
- package/package.json +1 -1
- package/src/c_g6_nodes_tree.js +433 -94
- package/src/c_yui_treedb_graph.js +104 -0
- package/src/treedb_layout.js +40 -56
- package/src/treedb_layout.test.js +45 -24
- package/src/yui_icons.css +6 -0
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -27370,10 +27370,10 @@ function fold_reveal(model, state, node_key) {
|
|
|
27370
27370
|
/***********************************************************************
|
|
27371
27371
|
* treedb_layout.js
|
|
27372
27372
|
*
|
|
27373
|
-
*
|
|
27373
|
+
* Two layouts made for a treedb, and nothing else.
|
|
27374
27374
|
*
|
|
27375
27375
|
* What a treedb graph IS, once it is folded (treedb_fold_model.js):
|
|
27376
|
-
* a forest read
|
|
27376
|
+
* a forest read top to bottom. A main topic is a tree (places:
|
|
27377
27377
|
* country, region, site, hall), the other topics hang from its
|
|
27378
27378
|
* nodes through hooks (devices, users, controllers), a record may
|
|
27379
27379
|
* hang from two parents (a device from its place AND its
|
|
@@ -27394,9 +27394,8 @@ function fold_reveal(model, state, node_key) {
|
|
|
27394
27394
|
* - the force family scatters a tree, which is the pile with
|
|
27395
27395
|
* physics.
|
|
27396
27396
|
*
|
|
27397
|
-
* So: a tidy tree (`tree`)
|
|
27398
|
-
*
|
|
27399
|
-
* deterministically:
|
|
27397
|
+
* So: a tidy tree (`tree`) and a radial tree (`radial`), both fed
|
|
27398
|
+
* by the SAME spanning tree, chosen deterministically:
|
|
27400
27399
|
*
|
|
27401
27400
|
* - roots are the nodes with no incoming edge, in node order;
|
|
27402
27401
|
* - a node belongs to the FIRST parent that reaches it in a
|
|
@@ -27408,16 +27407,16 @@ function fold_reveal(model, state, node_key) {
|
|
|
27408
27407
|
* and then by node order (record order, the pages' order);
|
|
27409
27408
|
* - a node nothing reaches (a cycle) is a root too.
|
|
27410
27409
|
*
|
|
27411
|
-
* `tree`: the classic tidy tree,
|
|
27412
|
-
*
|
|
27413
|
-
* block of its children; siblings
|
|
27414
|
-
* them. O(n), and opening a hook moves NOTHING that is
|
|
27415
|
-
* or beside it -- the cards keep their order, the eye
|
|
27416
|
-
* place.
|
|
27417
|
-
*
|
|
27418
|
-
*
|
|
27419
|
-
*
|
|
27420
|
-
*
|
|
27410
|
+
* `tree`: the classic tidy tree, top to bottom. Each depth is a
|
|
27411
|
+
* row as tall as its tallest card; a node is centred over the
|
|
27412
|
+
* block of its children; siblings sit side by side with `nodesep`
|
|
27413
|
+
* between them. O(n), and opening a hook moves NOTHING that is
|
|
27414
|
+
* not below or beside it -- the cards keep their order, the eye
|
|
27415
|
+
* keeps its place. It reads DOWN because that is the direction a
|
|
27416
|
+
* tree with many children has room in: a hall with a hundred
|
|
27417
|
+
* devices is a wide row, not a tall column beside a card. (The
|
|
27418
|
+
* left-to-right reading is `direction: "LR"`, kept for a host
|
|
27419
|
+
* that wants it; `dagre` reads that way in the graph.)
|
|
27421
27420
|
*
|
|
27422
27421
|
* `radial`: the root in the middle and a ring per depth, each
|
|
27423
27422
|
* subtree owning a sector proportional to its leaves; the radius
|
|
@@ -27425,15 +27424,15 @@ function fold_reveal(model, state, node_key) {
|
|
|
27425
27424
|
* nothing overlaps by construction (see `layout_radial`).
|
|
27426
27425
|
*
|
|
27427
27426
|
* Pure: takes plain nodes and edges, returns positions. The G6
|
|
27428
|
-
* classes in c_g6_nodes_tree.js are
|
|
27427
|
+
* classes in c_g6_nodes_tree.js are two thin adapters over it.
|
|
27429
27428
|
*
|
|
27430
27429
|
* Copyright (c) 2026, ArtGins.
|
|
27431
27430
|
* All Rights Reserved.
|
|
27432
27431
|
***********************************************************************/
|
|
27433
27432
|
var DEFAULTS = {
|
|
27434
27433
|
nodesep: 18,
|
|
27435
|
-
ranksep:
|
|
27436
|
-
|
|
27434
|
+
ranksep: 90,
|
|
27435
|
+
direction: "TB"
|
|
27437
27436
|
};
|
|
27438
27437
|
/************************************************************
|
|
27439
27438
|
* The spanning tree of a graph, deterministic.
|
|
@@ -27520,13 +27519,33 @@ function walk_order(t) {
|
|
|
27520
27519
|
return order;
|
|
27521
27520
|
}
|
|
27522
27521
|
/************************************************************
|
|
27523
|
-
* The tidy tree
|
|
27522
|
+
* The tidy tree.
|
|
27524
27523
|
*
|
|
27525
27524
|
* Returns Map<id, {x, y}> with the CENTRE of each node, the way G6
|
|
27526
27525
|
* positions a node.
|
|
27526
|
+
*
|
|
27527
|
+
* The algorithm is written ONCE, reading left to right (depths are
|
|
27528
|
+
* columns, siblings stack down). Top to bottom -- the default -- is
|
|
27529
|
+
* the same tree with the axes swapped: every card is fed in
|
|
27530
|
+
* transposed (its height as its width), and every position comes
|
|
27531
|
+
* back transposed. That is the whole difference, and it is the
|
|
27532
|
+
* reason the code is not duplicated for a second direction.
|
|
27527
27533
|
************************************************************/
|
|
27528
27534
|
function layout_tree(nodes, edges, opts) {
|
|
27529
27535
|
let o = Object.assign({}, DEFAULTS, opts || {});
|
|
27536
|
+
if (o.direction === "LR") return tidy_tree_lr(nodes, edges, o);
|
|
27537
|
+
let lr = tidy_tree_lr(nodes.map((n) => Object.assign({}, n, {
|
|
27538
|
+
w: n.h,
|
|
27539
|
+
h: n.w
|
|
27540
|
+
})), edges, o);
|
|
27541
|
+
let pos = /* @__PURE__ */ new Map();
|
|
27542
|
+
for (let [id, p] of lr) pos.set(id, {
|
|
27543
|
+
x: p.y,
|
|
27544
|
+
y: p.x
|
|
27545
|
+
});
|
|
27546
|
+
return pos;
|
|
27547
|
+
}
|
|
27548
|
+
function tidy_tree_lr(nodes, edges, o) {
|
|
27530
27549
|
let t = spanning_tree(nodes, edges);
|
|
27531
27550
|
let pos = /* @__PURE__ */ new Map();
|
|
27532
27551
|
let col_w = [];
|
|
@@ -27692,37 +27711,6 @@ function layout_radial(nodes, edges, opts) {
|
|
|
27692
27711
|
}
|
|
27693
27712
|
return pos;
|
|
27694
27713
|
}
|
|
27695
|
-
/************************************************************
|
|
27696
|
-
* The outline: one node per row, indented by depth, in the
|
|
27697
|
-
* pre-order of the spanning tree. Rows are left-aligned on
|
|
27698
|
-
* their indent, so a column of chips reads as a list.
|
|
27699
|
-
************************************************************/
|
|
27700
|
-
function layout_outline(nodes, edges, opts) {
|
|
27701
|
-
let o = Object.assign({}, DEFAULTS, opts || {});
|
|
27702
|
-
let t = spanning_tree(nodes, edges);
|
|
27703
|
-
let pos = /* @__PURE__ */ new Map();
|
|
27704
|
-
let y = 0;
|
|
27705
|
-
let visit = (root_id) => {
|
|
27706
|
-
let stack = [root_id];
|
|
27707
|
-
while (stack.length) {
|
|
27708
|
-
let id = stack.pop();
|
|
27709
|
-
let n = t.by_id.get(id);
|
|
27710
|
-
let d = t.depth.get(id);
|
|
27711
|
-
pos.set(id, {
|
|
27712
|
-
x: d * o.indent + n.w / 2,
|
|
27713
|
-
y: y + n.h / 2
|
|
27714
|
-
});
|
|
27715
|
-
y += n.h + o.nodesep;
|
|
27716
|
-
let kids = t.children.get(id) || [];
|
|
27717
|
-
for (let i = kids.length - 1; i >= 0; i--) stack.push(kids[i]);
|
|
27718
|
-
}
|
|
27719
|
-
};
|
|
27720
|
-
for (let root of t.roots) {
|
|
27721
|
-
visit(root);
|
|
27722
|
-
y += o.nodesep;
|
|
27723
|
-
}
|
|
27724
|
-
return pos;
|
|
27725
|
-
}
|
|
27726
27714
|
//#endregion
|
|
27727
27715
|
//#region node_modules/@babel/runtime/helpers/esm/typeof.js
|
|
27728
27716
|
function _typeof(o) {
|
|
@@ -54539,6 +54527,14 @@ var GCLASS_NAME$4 = "C_G6_NODES_TREE";
|
|
|
54539
54527
|
var HIGHLIGHT_COLOR = "#f0a020";
|
|
54540
54528
|
var HIGHLIGHT_HALO = "rgba(240,160,32,0.35)";
|
|
54541
54529
|
var SELECT_RING = "rgba(59,130,246,0.95)";
|
|
54530
|
+
var PORT_R_ENTITY = 10;
|
|
54531
|
+
var PORT_R_CHILD = 5;
|
|
54532
|
+
var PORT_LINE_WIDTH = 2;
|
|
54533
|
+
var COMPACT_SIZE = {
|
|
54534
|
+
hierarchical: 32,
|
|
54535
|
+
extended: 28,
|
|
54536
|
+
child: 22
|
|
54537
|
+
};
|
|
54542
54538
|
/***************************************************************
|
|
54543
54539
|
* Internal layout and operation mode definitions
|
|
54544
54540
|
***************************************************************/
|
|
@@ -54546,13 +54542,9 @@ var _layouts = {
|
|
|
54546
54542
|
"manual": { type: "manual" },
|
|
54547
54543
|
"treedb-tree": {
|
|
54548
54544
|
type: "treedb-tree",
|
|
54545
|
+
direction: "TB",
|
|
54549
54546
|
nodesep: 18,
|
|
54550
|
-
ranksep:
|
|
54551
|
-
},
|
|
54552
|
-
"treedb-outline": {
|
|
54553
|
-
type: "treedb-outline",
|
|
54554
|
-
nodesep: 12,
|
|
54555
|
-
indent: 48
|
|
54547
|
+
ranksep: 90
|
|
54556
54548
|
},
|
|
54557
54549
|
"dagre": {
|
|
54558
54550
|
type: "dagre",
|
|
@@ -54623,6 +54615,8 @@ var attrs_table$4 = [
|
|
|
54623
54615
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_LIST, "hidden_topics", 0, "[]", "Topics left out of the tree: no card, no pill counts them, no edge reaches them"),
|
|
54624
54616
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "main_topic", 0, "", "The topic the tree hangs from; empty = deduced (the one whose hooks reach the most others). Its parentless records are the roots; a parentless record of a topic linked to it is LOOSE and shown only on request"),
|
|
54625
54617
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_LIST, "loose_topics", 0, "[]", "Topics whose loose records (no parent, in a topic the schema hangs from the main one) are shown as roots"),
|
|
54618
|
+
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "node_mode", 0, "expanded", "How a record is drawn: `expanded` = the card with its ports (the only shape a link can be edited on); `compact` = a rounded square of the topic's colour, no ports, no text -- the topology alone. One node can be toggled against it (EV_TOGGLE_NODE_MODE)"),
|
|
54619
|
+
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_BOOLEAN, "node_labels", 0, true, "A compact node says its name under the square. Off, it is a coloured square and nothing else"),
|
|
54626
54620
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_BOOLEAN, "confirm_delete_node", 0, true, "Ask confirmation before deleting a node"),
|
|
54627
54621
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_BOOLEAN, "confirm_unlink_edge", 0, true, "Ask confirmation before unlinking an edge"),
|
|
54628
54622
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "wide", 0, "40px", "Height of header"),
|
|
@@ -54706,6 +54700,7 @@ var PRIVATE_DATA$4 = {
|
|
|
54706
54700
|
_fold_state: null,
|
|
54707
54701
|
_fold_listener: null,
|
|
54708
54702
|
_pill_sig: null,
|
|
54703
|
+
_open_nodes: null,
|
|
54709
54704
|
_fold_busy: false
|
|
54710
54705
|
};
|
|
54711
54706
|
var __gclass__$4 = null;
|
|
@@ -54851,7 +54846,6 @@ function register_layouts(gobj) {
|
|
|
54851
54846
|
_g6_extensions_registered = true;
|
|
54852
54847
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.LAYOUT, "manual", ManualLayout);
|
|
54853
54848
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.LAYOUT, "treedb-tree", TreedbTreeLayout);
|
|
54854
|
-
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.LAYOUT, "treedb-outline", TreedbOutlineLayout);
|
|
54855
54849
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.LAYOUT, "treedb-radial", TreedbRadialLayout);
|
|
54856
54850
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.NODE, "light", LightNode);
|
|
54857
54851
|
}
|
|
@@ -54934,6 +54928,9 @@ function configure_events(gobj) {
|
|
|
54934
54928
|
graph.on(_antv_g6.NodeEvent.CONTEXT_MENU, (evt) => {
|
|
54935
54929
|
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_NODE_CONTEXT_MENU", { evt }, gobj);
|
|
54936
54930
|
});
|
|
54931
|
+
graph.on(_antv_g6.NodeEvent.DBLCLICK, (evt) => {
|
|
54932
|
+
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_NODE_DBLCLICK", { evt }, gobj);
|
|
54933
|
+
});
|
|
54937
54934
|
graph.on(_antv_g6.EdgeEvent.CLICK, (evt) => {
|
|
54938
54935
|
if (consume_long_press_click(graph)) return;
|
|
54939
54936
|
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_EDGE_CLICK", { evt }, gobj);
|
|
@@ -55358,7 +55355,7 @@ function configure_behaviour(gobj) {
|
|
|
55358
55355
|
case "writing":
|
|
55359
55356
|
case "reading":
|
|
55360
55357
|
priv.edit_mode = false;
|
|
55361
|
-
behaviors = ["drag-canvas",
|
|
55358
|
+
behaviors = ["drag-canvas", ...camera_behaviors()];
|
|
55362
55359
|
break;
|
|
55363
55360
|
case "edition":
|
|
55364
55361
|
priv.edit_mode = true;
|
|
@@ -55372,7 +55369,7 @@ function configure_behaviour(gobj) {
|
|
|
55372
55369
|
return true;
|
|
55373
55370
|
}
|
|
55374
55371
|
},
|
|
55375
|
-
|
|
55372
|
+
...camera_behaviors(),
|
|
55376
55373
|
"drag-element",
|
|
55377
55374
|
{
|
|
55378
55375
|
type: BRUSH_SELECT_OWNED,
|
|
@@ -55390,7 +55387,7 @@ function configure_behaviour(gobj) {
|
|
|
55390
55387
|
break;
|
|
55391
55388
|
case "operation":
|
|
55392
55389
|
priv.edit_mode = false;
|
|
55393
|
-
behaviors = ["drag-canvas",
|
|
55390
|
+
behaviors = ["drag-canvas", ...camera_behaviors()];
|
|
55394
55391
|
break;
|
|
55395
55392
|
default: (0, _yuneta_gobj_js.log_error)(`operation mode unknown: ${operation_mode}`);
|
|
55396
55393
|
}
|
|
@@ -55462,13 +55459,33 @@ function build_ports(gobj, desc) {
|
|
|
55462
55459
|
* Which way the graph reads. `dagre` is the left-to-right
|
|
55463
55460
|
* layout; everything else keeps the top-down reading, `manual`
|
|
55464
55461
|
* included, because the saved arrangements were made with the
|
|
55465
|
-
* ports on the top and bottom edges.
|
|
55466
|
-
|
|
55467
|
-
|
|
55468
|
-
|
|
55469
|
-
|
|
55470
|
-
|
|
55471
|
-
|
|
55462
|
+
* ports on the top and bottom edges. The treedb tree reads down
|
|
55463
|
+
* too, since 7.23.75: read right it was dagre's twin.
|
|
55464
|
+
************************************************************/
|
|
55465
|
+
var LR_LAYOUTS = ["dagre"];
|
|
55466
|
+
/************************************************************
|
|
55467
|
+
* The camera behaviors every operation mode shares.
|
|
55468
|
+
*
|
|
55469
|
+
* The wheel SCROLLS, as it does on a map and on every page: a
|
|
55470
|
+
* graph of many nodes is taller than the screen, and a wheel
|
|
55471
|
+
* that zoomed instead made it a thing to be looked at from afar
|
|
55472
|
+
* or read through a keyhole -- never scrolled. Zoom is Ctrl +
|
|
55473
|
+
* wheel (which is also what a trackpad pinch arrives as), the
|
|
55474
|
+
* toolbar's +/-, and the two-finger pinch of g6_touch_gestures.
|
|
55475
|
+
* `enable` on the scroll keeps the two apart: a Ctrl wheel is
|
|
55476
|
+
* the zoom's, so the scroll stands aside for it.
|
|
55477
|
+
************************************************************/
|
|
55478
|
+
function camera_behaviors() {
|
|
55479
|
+
return [{
|
|
55480
|
+
type: "scroll-canvas",
|
|
55481
|
+
key: "scroll-canvas",
|
|
55482
|
+
enable: (event) => !(event && (event.ctrlKey || event.metaKey))
|
|
55483
|
+
}, {
|
|
55484
|
+
type: "zoom-canvas",
|
|
55485
|
+
key: "zoom-canvas",
|
|
55486
|
+
trigger: ["Control"]
|
|
55487
|
+
}];
|
|
55488
|
+
}
|
|
55472
55489
|
function layout_direction(gobj) {
|
|
55473
55490
|
return (0, _yuneta_gobj_js.str_in_list)(LR_LAYOUTS, gobj.priv.layout) ? "LR" : "TB";
|
|
55474
55491
|
}
|
|
@@ -55536,83 +55553,101 @@ function apply_layout_direction(gobj) {
|
|
|
55536
55553
|
* Create a topic node in the G6 graph
|
|
55537
55554
|
************************************************************/
|
|
55538
55555
|
function create_topic_node(gobj, desc, record) {
|
|
55539
|
-
|
|
55540
|
-
const graph = priv.graph;
|
|
55556
|
+
const graph = gobj.priv.graph;
|
|
55541
55557
|
let node_name = build_node_name(gobj, desc.topic_name, record.id);
|
|
55542
55558
|
let xy = get_default_ne_xy(gobj);
|
|
55543
55559
|
let geometry = get_node_graph_props(gobj, desc.topic_name, record.id, record);
|
|
55544
55560
|
let x = (0, _yuneta_gobj_js.kw_get_int)(gobj, geometry, "x", xy, _yuneta_gobj_js.kw_flag_t.KW_CREATE);
|
|
55545
55561
|
let y = (0, _yuneta_gobj_js.kw_get_int)(gobj, geometry, "y", xy, _yuneta_gobj_js.kw_flag_t.KW_CREATE);
|
|
55546
|
-
let
|
|
55547
|
-
let
|
|
55562
|
+
let shape = node_shape_of(gobj, node_name, desc, record, geometry, pills_html_of_key(gobj, fold_node_key(desc.topic_name, String(record.id))));
|
|
55563
|
+
let node_def = {
|
|
55564
|
+
id: node_name,
|
|
55565
|
+
type: shape.type,
|
|
55566
|
+
style: Object.assign({
|
|
55567
|
+
x,
|
|
55568
|
+
y
|
|
55569
|
+
}, shape.style),
|
|
55570
|
+
data: {
|
|
55571
|
+
topic_name: desc.topic_name,
|
|
55572
|
+
desc,
|
|
55573
|
+
record,
|
|
55574
|
+
graph_props: geometry,
|
|
55575
|
+
port_keys: build_ports(gobj, desc).map((p) => p.key)
|
|
55576
|
+
}
|
|
55577
|
+
};
|
|
55578
|
+
graph.addNodeData([node_def]);
|
|
55579
|
+
}
|
|
55580
|
+
/************************************************************
|
|
55581
|
+
* The shape of a record node: OPEN (the card, with its ports)
|
|
55582
|
+
* or CLOSED (a coloured square), by `node_mode` and the nodes
|
|
55583
|
+
* toggled against it.
|
|
55584
|
+
*
|
|
55585
|
+
* Both answer {type, style} WITHOUT x/y, which belong to the node
|
|
55586
|
+
* and not to its shape, and a node moves between the two on the
|
|
55587
|
+
* fly: G6 rebuilds the element when `type` changes, and the
|
|
55588
|
+
* style is MERGED, which is why each shape also writes the keys
|
|
55589
|
+
* the other one would leave behind (`labelText`, `ports`).
|
|
55590
|
+
************************************************************/
|
|
55591
|
+
function node_shape_of(gobj, node_id, desc, record, geometry, pills_html) {
|
|
55592
|
+
if (node_is_compact(gobj, node_id)) return compact_shape_of(gobj, desc, record, {});
|
|
55593
|
+
return card_shape_of(gobj, desc, record, geometry, pills_html);
|
|
55594
|
+
}
|
|
55595
|
+
function node_is_compact(gobj, node_id) {
|
|
55596
|
+
let priv = gobj.priv;
|
|
55597
|
+
if (!priv._open_nodes) priv._open_nodes = /* @__PURE__ */ new Set();
|
|
55598
|
+
let compact = (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "node_mode") === "compact";
|
|
55599
|
+
return priv._open_nodes.has(node_id) ? !compact : compact;
|
|
55600
|
+
}
|
|
55601
|
+
/************************************************************
|
|
55602
|
+
* The CARD: an html node, the tier's size, the ports, the
|
|
55603
|
+
* saved geometry on top. The flags (focus, selection, anchor)
|
|
55604
|
+
* are not painted here: repaint_cards() reads them where they
|
|
55605
|
+
* live and rebuilds the html.
|
|
55606
|
+
************************************************************/
|
|
55607
|
+
function card_shape_of(gobj, desc, record, geometry, pills_html) {
|
|
55608
|
+
let priv = gobj.priv;
|
|
55548
55609
|
let node_treedb_type = desc.node_treedb_type;
|
|
55610
|
+
let label = node_label(desc, record);
|
|
55611
|
+
let ports = build_ports(gobj, desc);
|
|
55549
55612
|
let style = {
|
|
55550
|
-
x,
|
|
55551
|
-
y,
|
|
55552
55613
|
fill: desc.color,
|
|
55553
55614
|
stroke: getStrokeColor(desc.color),
|
|
55554
|
-
lineWidth: 1
|
|
55615
|
+
lineWidth: 1,
|
|
55616
|
+
lineDash: [],
|
|
55617
|
+
halo: false,
|
|
55618
|
+
labelText: ""
|
|
55555
55619
|
};
|
|
55556
|
-
let pills_html = pills_html_of_key(gobj, fold_node_key(desc.topic_name, String(record.id)));
|
|
55557
55620
|
let size = card_size_for(node_treedb_type, !!pills_html);
|
|
55558
|
-
|
|
55559
|
-
|
|
55560
|
-
|
|
55561
|
-
|
|
55562
|
-
|
|
55563
|
-
|
|
55564
|
-
} else if (node_treedb_type === "extended") {
|
|
55565
|
-
node_graph_type = "html";
|
|
55566
|
-
style.size = size;
|
|
55567
|
-
style.dx = -size[0] / 2;
|
|
55568
|
-
style.dy = -size[1] / 2;
|
|
55569
|
-
style.innerHTML = build_node_innerHTML(desc.color, priv.theme, record.icon, node_label(desc, record), desc.topic_name, true, record.id, false, false, false, pills_html);
|
|
55570
|
-
} else {
|
|
55571
|
-
node_graph_type = "html";
|
|
55572
|
-
style.size = size;
|
|
55573
|
-
style.dx = -size[0] / 2;
|
|
55574
|
-
style.dy = -size[1] / 2;
|
|
55575
|
-
style.innerHTML = build_node_innerHTML(desc.color, priv.theme, record.icon, node_label(desc, record), desc.topic_name, false, record.id, false, false, false, pills_html);
|
|
55576
|
-
}
|
|
55621
|
+
style.size = size;
|
|
55622
|
+
style.dx = -size[0] / 2;
|
|
55623
|
+
style.dy = -size[1] / 2;
|
|
55624
|
+
if (node_treedb_type === "child") style.innerHTML = build_chip_innerHTML(desc.color, priv.theme, record.icon, label, record.id);
|
|
55625
|
+
else if (node_treedb_type === "extended") style.innerHTML = build_node_innerHTML(desc.color, priv.theme, record.icon, label, desc.topic_name, true, record.id, false, false, false, pills_html);
|
|
55626
|
+
else style.innerHTML = build_node_innerHTML(desc.color, priv.theme, record.icon, label, desc.topic_name, false, record.id, false, false, false, pills_html);
|
|
55577
55627
|
let topic_props = priv._graph_properties[desc.topic_name];
|
|
55578
55628
|
let topic_defaults = (0, _yuneta_gobj_js.is_object)(topic_props) && (0, _yuneta_gobj_js.is_object)(topic_props.defaults) ? topic_props.defaults : null;
|
|
55579
55629
|
if (topic_defaults) {
|
|
55580
55630
|
let def_size = topic_defaults.size;
|
|
55581
55631
|
if (!geometry.size && Array.isArray(def_size) && def_size.length > 0) {
|
|
55582
55632
|
style.size = [...def_size];
|
|
55583
|
-
|
|
55584
|
-
|
|
55585
|
-
style.dy = -(def_size.length > 1 ? def_size[1] : def_size[0]) / 2;
|
|
55586
|
-
}
|
|
55633
|
+
style.dx = -def_size[0] / 2;
|
|
55634
|
+
style.dy = -(def_size.length > 1 ? def_size[1] : def_size[0]) / 2;
|
|
55587
55635
|
}
|
|
55588
55636
|
if (!geometry.portR && topic_defaults.portR > 0) style.portR = topic_defaults.portR;
|
|
55589
55637
|
}
|
|
55590
55638
|
let saved_size = geometry.size;
|
|
55591
55639
|
if (Array.isArray(saved_size) && saved_size.length > 0) {
|
|
55592
55640
|
style.size = saved_size;
|
|
55593
|
-
|
|
55594
|
-
|
|
55595
|
-
style.dy = -(saved_size.length > 1 ? saved_size[1] : saved_size[0]) / 2;
|
|
55596
|
-
}
|
|
55641
|
+
style.dx = -saved_size[0] / 2;
|
|
55642
|
+
style.dy = -(saved_size.length > 1 ? saved_size[1] : saved_size[0]) / 2;
|
|
55597
55643
|
}
|
|
55598
55644
|
if (geometry.portR > 0) style.portR = geometry.portR;
|
|
55599
|
-
let node_def = {
|
|
55600
|
-
id: node_name,
|
|
55601
|
-
type: node_graph_type,
|
|
55602
|
-
style,
|
|
55603
|
-
data: {
|
|
55604
|
-
topic_name: desc.topic_name,
|
|
55605
|
-
desc,
|
|
55606
|
-
record,
|
|
55607
|
-
graph_props: geometry
|
|
55608
|
-
}
|
|
55609
|
-
};
|
|
55610
55645
|
if ((0, _yuneta_gobj_js.json_size)(ports)) {
|
|
55611
55646
|
(0, _yuneta_gobj_js.json_object_update_missing)(style, {
|
|
55612
55647
|
port: true,
|
|
55613
55648
|
ports,
|
|
55614
|
-
portR: node_treedb_type === "child" ?
|
|
55615
|
-
portLineWidth:
|
|
55649
|
+
portR: node_treedb_type === "child" ? PORT_R_CHILD : PORT_R_ENTITY,
|
|
55650
|
+
portLineWidth: PORT_LINE_WIDTH
|
|
55616
55651
|
});
|
|
55617
55652
|
let port_sizes = geometry.port_sizes;
|
|
55618
55653
|
let default_port_sizes = topic_defaults ? topic_defaults.port_sizes : null;
|
|
@@ -55622,8 +55657,117 @@ function create_topic_node(gobj, desc, record) {
|
|
|
55622
55657
|
if (r == null && (0, _yuneta_gobj_js.is_object)(default_port_sizes)) r = default_port_sizes[key];
|
|
55623
55658
|
if (r != null) style.ports[i].r = r;
|
|
55624
55659
|
}
|
|
55660
|
+
} else {
|
|
55661
|
+
style.port = false;
|
|
55662
|
+
style.ports = [];
|
|
55663
|
+
}
|
|
55664
|
+
return {
|
|
55665
|
+
type: "html",
|
|
55666
|
+
style
|
|
55667
|
+
};
|
|
55668
|
+
}
|
|
55669
|
+
/************************************************************
|
|
55670
|
+
* The SQUARE: a G6 `rect` of the topic's colour, no ports, the
|
|
55671
|
+
* name as a label under it when `node_labels` says so. A native
|
|
55672
|
+
* shape and not html on purpose: G6's own stroke and halo paint
|
|
55673
|
+
* on it, so the focus, the selection and the anchor are three
|
|
55674
|
+
* keys of the style instead of a rebuilt innerHTML.
|
|
55675
|
+
*
|
|
55676
|
+
* flags {highlight, selected, anchored}
|
|
55677
|
+
************************************************************/
|
|
55678
|
+
function compact_shape_of(gobj, desc, record, flags) {
|
|
55679
|
+
let dark = gobj.priv.theme === "dark";
|
|
55680
|
+
let f = flags || {};
|
|
55681
|
+
let tier = desc.node_treedb_type;
|
|
55682
|
+
let side = COMPACT_SIZE[tier] || COMPACT_SIZE.hierarchical;
|
|
55683
|
+
let labels = (0, _yuneta_gobj_js.gobj_read_bool_attr)(gobj, "node_labels");
|
|
55684
|
+
let stroke = getStrokeColor(desc.color);
|
|
55685
|
+
let line_width = 1.5;
|
|
55686
|
+
if (f.selected) {
|
|
55687
|
+
stroke = SELECT_RING;
|
|
55688
|
+
line_width = 3;
|
|
55689
|
+
}
|
|
55690
|
+
if (f.highlight) {
|
|
55691
|
+
stroke = HIGHLIGHT_COLOR;
|
|
55692
|
+
line_width = 3;
|
|
55693
|
+
}
|
|
55694
|
+
let dash = [];
|
|
55695
|
+
if (tier === "extended") dash = [4, 3];
|
|
55696
|
+
if (f.anchored) {
|
|
55697
|
+
dash = [2, 2];
|
|
55698
|
+
line_width = Math.max(line_width, 2.5);
|
|
55699
|
+
}
|
|
55700
|
+
return {
|
|
55701
|
+
type: "rect",
|
|
55702
|
+
style: {
|
|
55703
|
+
size: [side, side],
|
|
55704
|
+
radius: Math.round(side / 5),
|
|
55705
|
+
fill: desc.color,
|
|
55706
|
+
stroke,
|
|
55707
|
+
lineWidth: line_width,
|
|
55708
|
+
lineDash: dash,
|
|
55709
|
+
halo: !!f.highlight,
|
|
55710
|
+
haloStroke: HIGHLIGHT_HALO,
|
|
55711
|
+
haloLineWidth: 8,
|
|
55712
|
+
port: false,
|
|
55713
|
+
ports: [],
|
|
55714
|
+
labelText: labels ? node_label(desc, record) : "",
|
|
55715
|
+
labelPlacement: "bottom",
|
|
55716
|
+
labelFontSize: 11,
|
|
55717
|
+
labelFill: dark ? "#e6e9ef" : "#2e333d",
|
|
55718
|
+
labelMaxWidth: 150,
|
|
55719
|
+
labelWordWrap: true,
|
|
55720
|
+
labelMaxLines: 1,
|
|
55721
|
+
labelTextOverflow: "ellipsis",
|
|
55722
|
+
labelBackground: true,
|
|
55723
|
+
labelBackgroundFill: dark ? "#1b2230" : "#ffffff",
|
|
55724
|
+
labelBackgroundOpacity: .85,
|
|
55725
|
+
labelBackgroundRadius: 3,
|
|
55726
|
+
labelPadding: [1, 3]
|
|
55727
|
+
}
|
|
55728
|
+
};
|
|
55729
|
+
}
|
|
55730
|
+
/************************************************************
|
|
55731
|
+
* Give these record nodes the shape their mode says, then
|
|
55732
|
+
* repaint them with the flags they carry. A `+N` chip is not a
|
|
55733
|
+
* record and keeps its own shape.
|
|
55734
|
+
************************************************************/
|
|
55735
|
+
function reshape_nodes(gobj, ids) {
|
|
55736
|
+
let graph = gobj.priv.graph;
|
|
55737
|
+
if (!graph) return;
|
|
55738
|
+
let updates = [];
|
|
55739
|
+
let touched = /* @__PURE__ */ new Set();
|
|
55740
|
+
for (let id of ids) {
|
|
55741
|
+
let nd;
|
|
55742
|
+
try {
|
|
55743
|
+
nd = graph.getNodeData(id);
|
|
55744
|
+
} catch (e) {
|
|
55745
|
+
continue;
|
|
55746
|
+
}
|
|
55747
|
+
if (!nd || !nd.data || !nd.data.desc || is_more_node(nd)) continue;
|
|
55748
|
+
let geometry = nd.data.graph_props || {};
|
|
55749
|
+
let shape = node_shape_of(gobj, id, nd.data.desc, nd.data.record || {}, geometry, pills_html_of(gobj, nd));
|
|
55750
|
+
updates.push({
|
|
55751
|
+
id,
|
|
55752
|
+
type: shape.type,
|
|
55753
|
+
style: shape.style
|
|
55754
|
+
});
|
|
55755
|
+
touched.add(id);
|
|
55756
|
+
}
|
|
55757
|
+
if (!updates.length) return;
|
|
55758
|
+
try {
|
|
55759
|
+
graph.updateNodeData(updates);
|
|
55760
|
+
} catch (e) {
|
|
55761
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: cannot reshape the nodes: ${e}`);
|
|
55762
|
+
return;
|
|
55625
55763
|
}
|
|
55626
|
-
|
|
55764
|
+
repaint_cards(gobj, touched);
|
|
55765
|
+
}
|
|
55766
|
+
function all_record_node_ids(gobj) {
|
|
55767
|
+
let graph = gobj.priv.graph;
|
|
55768
|
+
let ids = [];
|
|
55769
|
+
for (let nd of graph && graph.getNodeData() || []) if (nd && nd.data && nd.data.desc && !is_more_node(nd)) ids.push(nd.id);
|
|
55770
|
+
return ids;
|
|
55627
55771
|
}
|
|
55628
55772
|
/************************************************************
|
|
55629
55773
|
* Update topic node data
|
|
@@ -56470,7 +56614,7 @@ var ManualLayout = class extends _antv_g6.BaseLayout {
|
|
|
56470
56614
|
}
|
|
56471
56615
|
};
|
|
56472
56616
|
/************************************************************
|
|
56473
|
-
* Custom G6 layouts: TreedbTreeLayout /
|
|
56617
|
+
* Custom G6 layouts: TreedbTreeLayout / TreedbRadialLayout.
|
|
56474
56618
|
*
|
|
56475
56619
|
* Thin adapters over treedb_layout.js: the nodes with their sizes,
|
|
56476
56620
|
* the edges with the RANK of the hook they leave by (the position
|
|
@@ -56488,7 +56632,8 @@ function treedb_layout_input(data) {
|
|
|
56488
56632
|
let w = (0, _yuneta_gobj_js.is_array)(size) ? size[0] : size;
|
|
56489
56633
|
let h = (0, _yuneta_gobj_js.is_array)(size) ? size.length > 1 ? size[1] : size[0] : size;
|
|
56490
56634
|
let ports = node.style && (0, _yuneta_gobj_js.is_array)(node.style.ports) ? node.style.ports : [];
|
|
56491
|
-
|
|
56635
|
+
let keys = node.data && (0, _yuneta_gobj_js.is_array)(node.data.port_keys) ? node.data.port_keys : ports.map((p) => p.key);
|
|
56636
|
+
ports_of.set(node.id, keys);
|
|
56492
56637
|
return {
|
|
56493
56638
|
id: node.id,
|
|
56494
56639
|
w,
|
|
@@ -56524,12 +56669,6 @@ var TreedbTreeLayout = class extends _antv_g6.BaseLayout {
|
|
|
56524
56669
|
return treedb_layout_output(layout_tree(input.nodes, input.edges, options));
|
|
56525
56670
|
}
|
|
56526
56671
|
};
|
|
56527
|
-
var TreedbOutlineLayout = class extends _antv_g6.BaseLayout {
|
|
56528
|
-
async execute(data, options) {
|
|
56529
|
-
let input = treedb_layout_input(data);
|
|
56530
|
-
return treedb_layout_output(layout_outline(input.nodes, input.edges, options));
|
|
56531
|
-
}
|
|
56532
|
-
};
|
|
56533
56672
|
var TreedbRadialLayout = class extends _antv_g6.BaseLayout {
|
|
56534
56673
|
async execute(data, options) {
|
|
56535
56674
|
let input = treedb_layout_input(data);
|
|
@@ -57221,7 +57360,7 @@ function get_port_radius(gobj, node_id, port_key) {
|
|
|
57221
57360
|
if (ports[i].r != null) return ports[i].r;
|
|
57222
57361
|
break;
|
|
57223
57362
|
}
|
|
57224
|
-
return style.portR ||
|
|
57363
|
+
return style.portR || PORT_R_ENTITY;
|
|
57225
57364
|
}
|
|
57226
57365
|
/************************************************************
|
|
57227
57366
|
* How much wider than the port itself its hit area is,
|
|
@@ -57253,7 +57392,7 @@ function detect_port_click(gobj, node_id, canvasX, canvasY) {
|
|
|
57253
57392
|
const style = graph.getNodeData(node_id).style || {};
|
|
57254
57393
|
const { w, h } = extract_size(style);
|
|
57255
57394
|
const ports = style.ports || [];
|
|
57256
|
-
const defaultR = style.portR ||
|
|
57395
|
+
const defaultR = style.portR || PORT_R_ENTITY;
|
|
57257
57396
|
let best_key = null;
|
|
57258
57397
|
let best_dist = Infinity;
|
|
57259
57398
|
let slop = port_hit_slop_world(graph);
|
|
@@ -57410,7 +57549,7 @@ function enter_linking_mode(gobj) {
|
|
|
57410
57549
|
p.stroke = "#52c41a";
|
|
57411
57550
|
p.lineWidth = 3;
|
|
57412
57551
|
if (p.r != null) p.r = p.r + 4;
|
|
57413
|
-
else p.r = (style.portR ||
|
|
57552
|
+
else p.r = (style.portR || PORT_R_ENTITY) + 4;
|
|
57414
57553
|
}
|
|
57415
57554
|
graph.updateNodeData([{
|
|
57416
57555
|
id: vh.node_id,
|
|
@@ -57562,7 +57701,7 @@ function find_hook_at_point(gobj, canvasX, canvasY) {
|
|
|
57562
57701
|
let pl = p.placement || [.5, .5];
|
|
57563
57702
|
let px = pos[0] + (pl[0] - .5) * w;
|
|
57564
57703
|
let py = pos[1] + (pl[1] - .5) * h;
|
|
57565
|
-
let r = p.r != null ? p.r : style.portR ||
|
|
57704
|
+
let r = p.r != null ? p.r : style.portR || PORT_R_ENTITY;
|
|
57566
57705
|
let dx = canvasX - px;
|
|
57567
57706
|
let dy = canvasY - py;
|
|
57568
57707
|
if (Math.sqrt(dx * dx + dy * dy) <= r + 6) return {
|
|
@@ -58320,7 +58459,19 @@ function repaint_cards(gobj, ids) {
|
|
|
58320
58459
|
} catch (e) {
|
|
58321
58460
|
continue;
|
|
58322
58461
|
}
|
|
58323
|
-
let
|
|
58462
|
+
let anchored = priv.anchor_state === "on" && id === priv.anchor_id;
|
|
58463
|
+
if (nd && nd.data && nd.data.desc && node_is_compact(gobj, id)) {
|
|
58464
|
+
updates.push({
|
|
58465
|
+
id,
|
|
58466
|
+
style: compact_shape_of(gobj, nd.data.desc, nd.data.record || {}, {
|
|
58467
|
+
highlight: focus.has(id),
|
|
58468
|
+
selected: selected.has(id),
|
|
58469
|
+
anchored
|
|
58470
|
+
}).style
|
|
58471
|
+
});
|
|
58472
|
+
continue;
|
|
58473
|
+
}
|
|
58474
|
+
let html = node_innerHTML_of(nd, priv.theme, focus.has(id), selected.has(id), anchored, pills_html_of(gobj, nd));
|
|
58324
58475
|
if (html !== null) updates.push({
|
|
58325
58476
|
id,
|
|
58326
58477
|
style: { innerHTML: html }
|
|
@@ -58357,7 +58508,19 @@ function refresh_html_nodes_theme(gobj, theme) {
|
|
|
58357
58508
|
for (let i = 0; i < nodes.length; i++) {
|
|
58358
58509
|
let id = nodes[i].id;
|
|
58359
58510
|
let nd = graph.getNodeData(id);
|
|
58360
|
-
let
|
|
58511
|
+
let anchored = priv.anchor_state === "on" && id === priv.anchor_id;
|
|
58512
|
+
if (nd && nd.data && nd.data.desc && node_is_compact(gobj, id)) {
|
|
58513
|
+
updates.push({
|
|
58514
|
+
id,
|
|
58515
|
+
style: compact_shape_of(gobj, nd.data.desc, nd.data.record || {}, {
|
|
58516
|
+
highlight: highlighted.has(id),
|
|
58517
|
+
selected: selected.has(id),
|
|
58518
|
+
anchored
|
|
58519
|
+
}).style
|
|
58520
|
+
});
|
|
58521
|
+
continue;
|
|
58522
|
+
}
|
|
58523
|
+
let html = node_innerHTML_of(nd, theme, highlighted.has(id), selected.has(id), anchored, pills_html_of(gobj, nd));
|
|
58361
58524
|
if (html === null) html = more_innerHTML_of(gobj, nd, theme);
|
|
58362
58525
|
if (html !== null) updates.push({
|
|
58363
58526
|
id,
|
|
@@ -58977,8 +59140,10 @@ function ctx_item(icon_id, label, value) {
|
|
|
58977
59140
|
************************************************************/
|
|
58978
59141
|
function build_node_context_menu(gobj, node_id) {
|
|
58979
59142
|
let items = [];
|
|
58980
|
-
|
|
58981
|
-
|
|
59143
|
+
inject_svg_icons();
|
|
59144
|
+
if (node_is_compact(gobj, node_id)) items.push(ctx_item("g6-icon-fullscreen", (0, i18next.t)("open node"), "toggle_node_mode"));
|
|
59145
|
+
else items.push(ctx_item("g6-icon-fullscreen-exit", (0, i18next.t)("close node"), "toggle_node_mode"));
|
|
59146
|
+
if (gobj.priv.edit_mode && !node_is_compact(gobj, node_id)) {
|
|
58982
59147
|
items.push(ctx_item("g6-icon-resize", (0, i18next.t)("resize all"), "resize_all_nodes"));
|
|
58983
59148
|
items.push(ctx_item("g6-icon-resize", (0, i18next.t)("resize topic nodes"), "resize_topic_nodes"));
|
|
58984
59149
|
}
|
|
@@ -59006,8 +59171,11 @@ function build_edge_context_menu(gobj) {
|
|
|
59006
59171
|
* Handle context menu click: dispatch by value.
|
|
59007
59172
|
************************************************************/
|
|
59008
59173
|
function handle_context_menu_click(gobj, value) {
|
|
59009
|
-
gobj.priv;
|
|
59174
|
+
let priv = gobj.priv;
|
|
59010
59175
|
switch (value) {
|
|
59176
|
+
case "toggle_node_mode":
|
|
59177
|
+
if (priv._context_node_id) (0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_TOGGLE_NODE_MODE", { id: priv._context_node_id }, gobj);
|
|
59178
|
+
break;
|
|
59011
59179
|
case "resize_all_nodes":
|
|
59012
59180
|
copy_size_to_nodes(gobj, false);
|
|
59013
59181
|
break;
|
|
@@ -59538,7 +59706,7 @@ async function reconcile_fold_apply(gobj, opts, visible) {
|
|
|
59538
59706
|
let nd = graph.getNodeData(id);
|
|
59539
59707
|
let desc = nd && nd.data && nd.data.desc;
|
|
59540
59708
|
let geometry = nd && nd.data && nd.data.graph_props || {};
|
|
59541
|
-
if (desc && !(0, _yuneta_gobj_js.is_array)(geometry.size)) {
|
|
59709
|
+
if (desc && !(0, _yuneta_gobj_js.is_array)(geometry.size) && !node_is_compact(gobj, id)) {
|
|
59542
59710
|
let size = card_size_for(desc.node_treedb_type, !!sig);
|
|
59543
59711
|
resize.push({
|
|
59544
59712
|
id,
|
|
@@ -59623,6 +59791,7 @@ function ac_clear_data(gobj, event, kw, src) {
|
|
|
59623
59791
|
priv._fold_model = null;
|
|
59624
59792
|
priv._fold_state = null;
|
|
59625
59793
|
priv._pill_sig = null;
|
|
59794
|
+
priv._open_nodes = null;
|
|
59626
59795
|
graph_remove_plugin(gobj, "history");
|
|
59627
59796
|
update_history_buttons(gobj);
|
|
59628
59797
|
graph_clear(gobj);
|
|
@@ -60121,6 +60290,79 @@ function ac_set_loose_topics(gobj, event, kw, src) {
|
|
|
60121
60290
|
return 0;
|
|
60122
60291
|
}
|
|
60123
60292
|
/************************************************************
|
|
60293
|
+
* The shape of every record: open cards or closed squares.
|
|
60294
|
+
* A change of mode forgets the nodes toggled against the old
|
|
60295
|
+
* one -- they were exceptions to a rule that no longer holds --
|
|
60296
|
+
* and lays the graph out again, because a square and a card
|
|
60297
|
+
* do not occupy the same room.
|
|
60298
|
+
************************************************************/
|
|
60299
|
+
function ac_set_node_mode(gobj, event, kw, src) {
|
|
60300
|
+
let priv = gobj.priv;
|
|
60301
|
+
let mode = kw && kw.node_mode === "compact" ? "compact" : "expanded";
|
|
60302
|
+
(0, _yuneta_gobj_js.gobj_write_str_attr)(gobj, "node_mode", mode);
|
|
60303
|
+
priv._open_nodes = /* @__PURE__ */ new Set();
|
|
60304
|
+
if (!priv.graph || !priv._fold_model) return 0;
|
|
60305
|
+
reshape_nodes(gobj, all_record_node_ids(gobj));
|
|
60306
|
+
reconcile_fold(gobj, {
|
|
60307
|
+
relayout: true,
|
|
60308
|
+
fit: true
|
|
60309
|
+
});
|
|
60310
|
+
return 0;
|
|
60311
|
+
}
|
|
60312
|
+
/************************************************************
|
|
60313
|
+
* The name under a closed square, on or off. Only the closed
|
|
60314
|
+
* nodes change, and nothing moves: the label hangs outside the
|
|
60315
|
+
* square and the layout measures the square.
|
|
60316
|
+
************************************************************/
|
|
60317
|
+
function ac_set_node_labels(gobj, event, kw, src) {
|
|
60318
|
+
let priv = gobj.priv;
|
|
60319
|
+
(0, _yuneta_gobj_js.gobj_write_bool_attr)(gobj, "node_labels", !!(kw && kw.node_labels));
|
|
60320
|
+
if (!priv.graph) return 0;
|
|
60321
|
+
reshape_nodes(gobj, all_record_node_ids(gobj).filter((id) => node_is_compact(gobj, id)));
|
|
60322
|
+
return 0;
|
|
60323
|
+
}
|
|
60324
|
+
/************************************************************
|
|
60325
|
+
* ONE node opened or closed against the mode (a double click,
|
|
60326
|
+
* or the context menu). It holds still on screen while the
|
|
60327
|
+
* rest of the graph makes room, as a fold does.
|
|
60328
|
+
************************************************************/
|
|
60329
|
+
function ac_toggle_node_mode$1(gobj, event, kw, src) {
|
|
60330
|
+
let priv = gobj.priv;
|
|
60331
|
+
let node_id = kw && kw.id || "";
|
|
60332
|
+
if (!priv.graph || !node_id) {
|
|
60333
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: toggle node mode without a node`);
|
|
60334
|
+
return -1;
|
|
60335
|
+
}
|
|
60336
|
+
if (!priv._open_nodes) priv._open_nodes = /* @__PURE__ */ new Set();
|
|
60337
|
+
if (priv._open_nodes.has(node_id)) priv._open_nodes.delete(node_id);
|
|
60338
|
+
else priv._open_nodes.add(node_id);
|
|
60339
|
+
let vp = yui_graph_viewport_of(priv.graph, node_id);
|
|
60340
|
+
reshape_nodes(gobj, [node_id]);
|
|
60341
|
+
if (priv._fold_model) reconcile_fold(gobj, {
|
|
60342
|
+
relayout: true,
|
|
60343
|
+
keep: node_id,
|
|
60344
|
+
keep_vp: vp
|
|
60345
|
+
});
|
|
60346
|
+
return 0;
|
|
60347
|
+
}
|
|
60348
|
+
/************************************************************
|
|
60349
|
+
* A double click on a node: open it if closed, close it if open.
|
|
60350
|
+
* A `+N` chip is not a record and has no shape to toggle.
|
|
60351
|
+
************************************************************/
|
|
60352
|
+
function ac_node_dblclick(gobj, event, kw, src) {
|
|
60353
|
+
let priv = gobj.priv;
|
|
60354
|
+
let node_id = kw && kw.evt && kw.evt.target ? kw.evt.target.id : "";
|
|
60355
|
+
let nd = null;
|
|
60356
|
+
try {
|
|
60357
|
+
nd = priv.graph.getNodeData(node_id);
|
|
60358
|
+
} catch (e) {
|
|
60359
|
+
nd = null;
|
|
60360
|
+
}
|
|
60361
|
+
if (!nd || !nd.data || !nd.data.desc || is_more_node(nd)) return 0;
|
|
60362
|
+
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_TOGGLE_NODE_MODE", { id: node_id }, gobj);
|
|
60363
|
+
return 0;
|
|
60364
|
+
}
|
|
60365
|
+
/************************************************************
|
|
60124
60366
|
* Tell whoever asked how many nodes the term matched. The count is
|
|
60125
60367
|
* the answer to the question the box asks; without it "nothing moved"
|
|
60126
60368
|
* and "nothing matched" look the same.
|
|
@@ -60610,6 +60852,26 @@ function create_gclass$4(gclass_name) {
|
|
|
60610
60852
|
ac_set_loose_topics,
|
|
60611
60853
|
null
|
|
60612
60854
|
],
|
|
60855
|
+
[
|
|
60856
|
+
"EV_SET_NODE_MODE",
|
|
60857
|
+
ac_set_node_mode,
|
|
60858
|
+
null
|
|
60859
|
+
],
|
|
60860
|
+
[
|
|
60861
|
+
"EV_SET_NODE_LABELS",
|
|
60862
|
+
ac_set_node_labels,
|
|
60863
|
+
null
|
|
60864
|
+
],
|
|
60865
|
+
[
|
|
60866
|
+
"EV_TOGGLE_NODE_MODE",
|
|
60867
|
+
ac_toggle_node_mode$1,
|
|
60868
|
+
null
|
|
60869
|
+
],
|
|
60870
|
+
[
|
|
60871
|
+
"EV_NODE_DBLCLICK",
|
|
60872
|
+
ac_node_dblclick,
|
|
60873
|
+
null
|
|
60874
|
+
],
|
|
60613
60875
|
[
|
|
60614
60876
|
"EV_CENTER",
|
|
60615
60877
|
ac_center,
|
|
@@ -60714,6 +60976,10 @@ function create_gclass$4(gclass_name) {
|
|
|
60714
60976
|
["EV_SET_HIDDEN_TOPICS", 0],
|
|
60715
60977
|
["EV_SET_MAIN_TOPIC", 0],
|
|
60716
60978
|
["EV_SET_LOOSE_TOPICS", 0],
|
|
60979
|
+
["EV_SET_NODE_MODE", 0],
|
|
60980
|
+
["EV_SET_NODE_LABELS", 0],
|
|
60981
|
+
["EV_TOGGLE_NODE_MODE", 0],
|
|
60982
|
+
["EV_NODE_DBLCLICK", 0],
|
|
60717
60983
|
["EV_LEGEND_STATE", _yuneta_gobj_js.event_flag_t.EVF_OUTPUT_EVENT],
|
|
60718
60984
|
["EV_CENTER", 0],
|
|
60719
60985
|
["EV_FULLSCREEN", 0],
|
|
@@ -60779,6 +61045,8 @@ var attrs_table$3 = [
|
|
|
60779
61045
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_LIST, "hidden_topics", _yuneta_gobj_js.sdata_flag_t.SDF_PERSIST, "[]", "Topics hidden from the graph (legend). User preference, per treedb"),
|
|
60780
61046
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "main_topic", _yuneta_gobj_js.sdata_flag_t.SDF_PERSIST, "", "The topic the tree hangs from; empty = deduced by the graph. User preference, per treedb"),
|
|
60781
61047
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_LIST, "loose_topics", _yuneta_gobj_js.sdata_flag_t.SDF_PERSIST, "[]", "Topics whose LOOSE records (no parent) are shown. User preference, per treedb"),
|
|
61048
|
+
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "node_mode", _yuneta_gobj_js.sdata_flag_t.SDF_PERSIST, "expanded", "How the records are drawn: `expanded` = the cards with their ports, `compact` = coloured squares, the topology alone. User preference"),
|
|
61049
|
+
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_BOOLEAN, "node_labels", _yuneta_gobj_js.sdata_flag_t.SDF_PERSIST, true, "A compact node says its name under its square. User preference"),
|
|
60782
61050
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_POINTER, "gobj_remote_yuno", 0, null, "Remote Yuno to request data"),
|
|
60783
61051
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "treedb_name", 0, null, "Remote service treedb name"),
|
|
60784
61052
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_DICT, "descs", 0, null, "Descriptions of topics obtained"),
|
|
@@ -60856,7 +61124,9 @@ function mt_create$3(gobj) {
|
|
|
60856
61124
|
fold_page_size: (0, _yuneta_gobj_js.gobj_read_integer_attr)(gobj, "fold_page_size"),
|
|
60857
61125
|
hidden_topics: (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "hidden_topics") || [],
|
|
60858
61126
|
main_topic: (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "main_topic") || "",
|
|
60859
|
-
loose_topics: (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "loose_topics") || []
|
|
61127
|
+
loose_topics: (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "loose_topics") || [],
|
|
61128
|
+
node_mode: (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "node_mode") || "expanded",
|
|
61129
|
+
node_labels: (0, _yuneta_gobj_js.gobj_read_bool_attr)(gobj, "node_labels")
|
|
60860
61130
|
}, gobj);
|
|
60861
61131
|
populate_nodes_tree_options(gobj);
|
|
60862
61132
|
if (priv.with_treedb_tables) {}
|
|
@@ -60907,6 +61177,7 @@ function build_ui$3(gobj) {
|
|
|
60907
61177
|
let priv = gobj.priv;
|
|
60908
61178
|
let padding = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "padding");
|
|
60909
61179
|
let $toolbar = make_toolbar(gobj);
|
|
61180
|
+
refresh_node_shape_buttons(gobj, $toolbar);
|
|
60910
61181
|
let $back = make_back_to_topics(gobj);
|
|
60911
61182
|
let $container = (0, _yuneta_gobj_js.createElement2)([
|
|
60912
61183
|
"div",
|
|
@@ -61048,6 +61319,57 @@ function option_label(name) {
|
|
|
61048
61319
|
/************************************************************
|
|
61049
61320
|
*
|
|
61050
61321
|
************************************************************/
|
|
61322
|
+
/************************************************************
|
|
61323
|
+
* The two toggles of the nodes' shape.
|
|
61324
|
+
*
|
|
61325
|
+
* Closed nodes: every record a rounded square of its topic's
|
|
61326
|
+
* colour, no ports, no text -- the topology of a graph of many
|
|
61327
|
+
* nodes, which the cards hide behind their own size. Labels:
|
|
61328
|
+
* the name under each square, when the squares alone do not say
|
|
61329
|
+
* enough. Both persist, both are forwarded to the G6 child, and
|
|
61330
|
+
* one node can be opened against the rule with a double click or
|
|
61331
|
+
* its context menu (the child's business).
|
|
61332
|
+
************************************************************/
|
|
61333
|
+
function node_shape_items(gobj, wide) {
|
|
61334
|
+
let toggle = (cls, icon, event_name, label_key) => {
|
|
61335
|
+
return [
|
|
61336
|
+
"button",
|
|
61337
|
+
{
|
|
61338
|
+
class: `${cls} button`,
|
|
61339
|
+
type: "button",
|
|
61340
|
+
style: {
|
|
61341
|
+
height: wide,
|
|
61342
|
+
width: "2.5em"
|
|
61343
|
+
},
|
|
61344
|
+
title: (0, i18next.t)(label_key),
|
|
61345
|
+
"data-i18n-title": label_key,
|
|
61346
|
+
"aria-label": (0, i18next.t)(label_key),
|
|
61347
|
+
"data-i18n-aria-label": label_key,
|
|
61348
|
+
"aria-pressed": "false"
|
|
61349
|
+
},
|
|
61350
|
+
["i", {
|
|
61351
|
+
style: "font-size:1.5em; color:inherit;",
|
|
61352
|
+
class: icon
|
|
61353
|
+
}],
|
|
61354
|
+
{ click: (evt) => {
|
|
61355
|
+
evt.stopPropagation();
|
|
61356
|
+
(0, _yuneta_gobj_js.gobj_send_event)(gobj, event_name, {}, gobj);
|
|
61357
|
+
} }
|
|
61358
|
+
];
|
|
61359
|
+
};
|
|
61360
|
+
return [toggle("GRAPH_NODE_MODE", "yi-hexagon-nodes", "EV_TOGGLE_NODE_MODE", "closed nodes"), toggle("GRAPH_NODE_LABELS", "yi-font", "EV_TOGGLE_NODE_LABELS", "node labels")];
|
|
61361
|
+
}
|
|
61362
|
+
function refresh_node_shape_buttons(gobj, $root) {
|
|
61363
|
+
if (!$root) return;
|
|
61364
|
+
let compact = (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "node_mode") === "compact";
|
|
61365
|
+
let labels = (0, _yuneta_gobj_js.gobj_read_bool_attr)(gobj, "node_labels");
|
|
61366
|
+
set_pressed_state($root, ".GRAPH_NODE_MODE", compact);
|
|
61367
|
+
set_pressed_state($root, ".GRAPH_NODE_LABELS", labels);
|
|
61368
|
+
let $mode = $root.querySelector(".GRAPH_NODE_MODE");
|
|
61369
|
+
if ($mode) $mode.setAttribute("aria-pressed", compact ? "true" : "false");
|
|
61370
|
+
let $labels = $root.querySelector(".GRAPH_NODE_LABELS");
|
|
61371
|
+
if ($labels) $labels.setAttribute("aria-pressed", labels ? "true" : "false");
|
|
61372
|
+
}
|
|
61051
61373
|
function make_toolbar(gobj) {
|
|
61052
61374
|
let priv = gobj.priv;
|
|
61053
61375
|
let modes = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "operation_modes");
|
|
@@ -61118,6 +61440,7 @@ function make_toolbar(gobj) {
|
|
|
61118
61440
|
} }
|
|
61119
61441
|
],
|
|
61120
61442
|
...yui_graph_fold_items(gobj, (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "wide")),
|
|
61443
|
+
...node_shape_items(gobj, (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "wide")),
|
|
61121
61444
|
[
|
|
61122
61445
|
"button",
|
|
61123
61446
|
{
|
|
@@ -62432,6 +62755,29 @@ function ac_collapse_all(gobj, event, kw, src) {
|
|
|
62432
62755
|
return 0;
|
|
62433
62756
|
}
|
|
62434
62757
|
/************************************************************
|
|
62758
|
+
* The shape pair of the toolbar: the attr flips, persists,
|
|
62759
|
+
* shows on the button, and reaches the G6 child, which owns
|
|
62760
|
+
* the nodes.
|
|
62761
|
+
************************************************************/
|
|
62762
|
+
function ac_toggle_node_mode(gobj, event, kw, src) {
|
|
62763
|
+
let priv = gobj.priv;
|
|
62764
|
+
let mode = (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "node_mode") === "compact" ? "expanded" : "compact";
|
|
62765
|
+
(0, _yuneta_gobj_js.gobj_write_str_attr)(gobj, "node_mode", mode);
|
|
62766
|
+
(0, _yuneta_gobj_js.gobj_save_persistent_attrs)(gobj, "node_mode");
|
|
62767
|
+
refresh_node_shape_buttons(gobj, priv.$container);
|
|
62768
|
+
if (priv.gobj_nodes_tree) (0, _yuneta_gobj_js.gobj_send_event)(priv.gobj_nodes_tree, "EV_SET_NODE_MODE", { node_mode: mode }, gobj);
|
|
62769
|
+
return 0;
|
|
62770
|
+
}
|
|
62771
|
+
function ac_toggle_node_labels(gobj, event, kw, src) {
|
|
62772
|
+
let priv = gobj.priv;
|
|
62773
|
+
let labels = !(0, _yuneta_gobj_js.gobj_read_bool_attr)(gobj, "node_labels");
|
|
62774
|
+
(0, _yuneta_gobj_js.gobj_write_bool_attr)(gobj, "node_labels", labels);
|
|
62775
|
+
(0, _yuneta_gobj_js.gobj_save_persistent_attrs)(gobj, "node_labels");
|
|
62776
|
+
refresh_node_shape_buttons(gobj, priv.$container);
|
|
62777
|
+
if (priv.gobj_nodes_tree) (0, _yuneta_gobj_js.gobj_send_event)(priv.gobj_nodes_tree, "EV_SET_NODE_LABELS", { node_labels: labels }, gobj);
|
|
62778
|
+
return 0;
|
|
62779
|
+
}
|
|
62780
|
+
/************************************************************
|
|
62435
62781
|
* How many nodes the term matched, from the graph child. Zero with a
|
|
62436
62782
|
* term typed is an ANSWER and is shown; an empty box shows nothing.
|
|
62437
62783
|
************************************************************/
|
|
@@ -62645,6 +62991,16 @@ function create_gclass$3(gclass_name) {
|
|
|
62645
62991
|
ac_collapse_all,
|
|
62646
62992
|
null
|
|
62647
62993
|
],
|
|
62994
|
+
[
|
|
62995
|
+
"EV_TOGGLE_NODE_MODE",
|
|
62996
|
+
ac_toggle_node_mode,
|
|
62997
|
+
null
|
|
62998
|
+
],
|
|
62999
|
+
[
|
|
63000
|
+
"EV_TOGGLE_NODE_LABELS",
|
|
63001
|
+
ac_toggle_node_labels,
|
|
63002
|
+
null
|
|
63003
|
+
],
|
|
62648
63004
|
[
|
|
62649
63005
|
"EV_LAYOUT_AUTOSET",
|
|
62650
63006
|
ac_layout_autoset,
|
|
@@ -62709,6 +63065,8 @@ function create_gclass$3(gclass_name) {
|
|
|
62709
63065
|
["EV_FIND_NODES", 0],
|
|
62710
63066
|
["EV_EXPAND_ALL", 0],
|
|
62711
63067
|
["EV_COLLAPSE_ALL", 0],
|
|
63068
|
+
["EV_TOGGLE_NODE_MODE", 0],
|
|
63069
|
+
["EV_TOGGLE_NODE_LABELS", 0],
|
|
62712
63070
|
["EV_FIND_RESULT", 0],
|
|
62713
63071
|
["EV_LAYOUT_AUTOSET", 0],
|
|
62714
63072
|
["EV_LEGEND_TOPIC", 0],
|