@yuneta/gobj-ui 7.23.73 → 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 +498 -134
- package/dist/gobj-ui.es.js +498 -134
- package/package.json +1 -1
- package/src/c_g6_nodes_tree.js +433 -94
- package/src/c_yui_treedb_graph.js +118 -2
- package/src/treedb_layout.js +42 -52
- package/src/treedb_layout.test.js +45 -24
- package/src/yui_icons.css +6 -0
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -27373,7 +27373,7 @@ function fold_reveal(model, state, node_key) {
|
|
|
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,8 +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`) and
|
|
27398
|
-
* the SAME spanning tree, chosen deterministically:
|
|
27397
|
+
* So: a tidy tree (`tree`) and a radial tree (`radial`), both fed
|
|
27398
|
+
* by the SAME spanning tree, chosen deterministically:
|
|
27399
27399
|
*
|
|
27400
27400
|
* - roots are the nodes with no incoming edge, in node order;
|
|
27401
27401
|
* - a node belongs to the FIRST parent that reaches it in a
|
|
@@ -27407,16 +27407,21 @@ function fold_reveal(model, state, node_key) {
|
|
|
27407
27407
|
* and then by node order (record order, the pages' order);
|
|
27408
27408
|
* - a node nothing reaches (a cycle) is a root too.
|
|
27409
27409
|
*
|
|
27410
|
-
* `tree`: the classic tidy tree,
|
|
27411
|
-
*
|
|
27412
|
-
* block of its children; siblings
|
|
27413
|
-
* them. O(n), and opening a hook moves NOTHING that is
|
|
27414
|
-
* or beside it -- the cards keep their order, the eye
|
|
27415
|
-
* place.
|
|
27416
|
-
*
|
|
27417
|
-
*
|
|
27418
|
-
*
|
|
27419
|
-
*
|
|
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.)
|
|
27420
|
+
*
|
|
27421
|
+
* `radial`: the root in the middle and a ring per depth, each
|
|
27422
|
+
* subtree owning a sector proportional to its leaves; the radius
|
|
27423
|
+
* of a ring grows until its neighbours sit side by side, so
|
|
27424
|
+
* nothing overlaps by construction (see `layout_radial`).
|
|
27420
27425
|
*
|
|
27421
27426
|
* Pure: takes plain nodes and edges, returns positions. The G6
|
|
27422
27427
|
* classes in c_g6_nodes_tree.js are two thin adapters over it.
|
|
@@ -27426,8 +27431,8 @@ function fold_reveal(model, state, node_key) {
|
|
|
27426
27431
|
***********************************************************************/
|
|
27427
27432
|
var DEFAULTS = {
|
|
27428
27433
|
nodesep: 18,
|
|
27429
|
-
ranksep:
|
|
27430
|
-
|
|
27434
|
+
ranksep: 90,
|
|
27435
|
+
direction: "TB"
|
|
27431
27436
|
};
|
|
27432
27437
|
/************************************************************
|
|
27433
27438
|
* The spanning tree of a graph, deterministic.
|
|
@@ -27514,13 +27519,33 @@ function walk_order(t) {
|
|
|
27514
27519
|
return order;
|
|
27515
27520
|
}
|
|
27516
27521
|
/************************************************************
|
|
27517
|
-
* The tidy tree
|
|
27522
|
+
* The tidy tree.
|
|
27518
27523
|
*
|
|
27519
27524
|
* Returns Map<id, {x, y}> with the CENTRE of each node, the way G6
|
|
27520
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.
|
|
27521
27533
|
************************************************************/
|
|
27522
27534
|
function layout_tree(nodes, edges, opts) {
|
|
27523
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) {
|
|
27524
27549
|
let t = spanning_tree(nodes, edges);
|
|
27525
27550
|
let pos = /* @__PURE__ */ new Map();
|
|
27526
27551
|
let col_w = [];
|
|
@@ -27686,37 +27711,6 @@ function layout_radial(nodes, edges, opts) {
|
|
|
27686
27711
|
}
|
|
27687
27712
|
return pos;
|
|
27688
27713
|
}
|
|
27689
|
-
/************************************************************
|
|
27690
|
-
* The outline: one node per row, indented by depth, in the
|
|
27691
|
-
* pre-order of the spanning tree. Rows are left-aligned on
|
|
27692
|
-
* their indent, so a column of chips reads as a list.
|
|
27693
|
-
************************************************************/
|
|
27694
|
-
function layout_outline(nodes, edges, opts) {
|
|
27695
|
-
let o = Object.assign({}, DEFAULTS, opts || {});
|
|
27696
|
-
let t = spanning_tree(nodes, edges);
|
|
27697
|
-
let pos = /* @__PURE__ */ new Map();
|
|
27698
|
-
let y = 0;
|
|
27699
|
-
let visit = (root_id) => {
|
|
27700
|
-
let stack = [root_id];
|
|
27701
|
-
while (stack.length) {
|
|
27702
|
-
let id = stack.pop();
|
|
27703
|
-
let n = t.by_id.get(id);
|
|
27704
|
-
let d = t.depth.get(id);
|
|
27705
|
-
pos.set(id, {
|
|
27706
|
-
x: d * o.indent + n.w / 2,
|
|
27707
|
-
y: y + n.h / 2
|
|
27708
|
-
});
|
|
27709
|
-
y += n.h + o.nodesep;
|
|
27710
|
-
let kids = t.children.get(id) || [];
|
|
27711
|
-
for (let i = kids.length - 1; i >= 0; i--) stack.push(kids[i]);
|
|
27712
|
-
}
|
|
27713
|
-
};
|
|
27714
|
-
for (let root of t.roots) {
|
|
27715
|
-
visit(root);
|
|
27716
|
-
y += o.nodesep;
|
|
27717
|
-
}
|
|
27718
|
-
return pos;
|
|
27719
|
-
}
|
|
27720
27714
|
//#endregion
|
|
27721
27715
|
//#region node_modules/@babel/runtime/helpers/esm/typeof.js
|
|
27722
27716
|
function _typeof(o) {
|
|
@@ -54533,6 +54527,14 @@ var GCLASS_NAME$4 = "C_G6_NODES_TREE";
|
|
|
54533
54527
|
var HIGHLIGHT_COLOR = "#f0a020";
|
|
54534
54528
|
var HIGHLIGHT_HALO = "rgba(240,160,32,0.35)";
|
|
54535
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
|
+
};
|
|
54536
54538
|
/***************************************************************
|
|
54537
54539
|
* Internal layout and operation mode definitions
|
|
54538
54540
|
***************************************************************/
|
|
@@ -54540,13 +54542,9 @@ var _layouts = {
|
|
|
54540
54542
|
"manual": { type: "manual" },
|
|
54541
54543
|
"treedb-tree": {
|
|
54542
54544
|
type: "treedb-tree",
|
|
54545
|
+
direction: "TB",
|
|
54543
54546
|
nodesep: 18,
|
|
54544
|
-
ranksep:
|
|
54545
|
-
},
|
|
54546
|
-
"treedb-outline": {
|
|
54547
|
-
type: "treedb-outline",
|
|
54548
|
-
nodesep: 12,
|
|
54549
|
-
indent: 48
|
|
54547
|
+
ranksep: 90
|
|
54550
54548
|
},
|
|
54551
54549
|
"dagre": {
|
|
54552
54550
|
type: "dagre",
|
|
@@ -54617,6 +54615,8 @@ var attrs_table$4 = [
|
|
|
54617
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"),
|
|
54618
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"),
|
|
54619
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"),
|
|
54620
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"),
|
|
54621
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"),
|
|
54622
54622
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "wide", 0, "40px", "Height of header"),
|
|
@@ -54700,6 +54700,7 @@ var PRIVATE_DATA$4 = {
|
|
|
54700
54700
|
_fold_state: null,
|
|
54701
54701
|
_fold_listener: null,
|
|
54702
54702
|
_pill_sig: null,
|
|
54703
|
+
_open_nodes: null,
|
|
54703
54704
|
_fold_busy: false
|
|
54704
54705
|
};
|
|
54705
54706
|
var __gclass__$4 = null;
|
|
@@ -54845,7 +54846,6 @@ function register_layouts(gobj) {
|
|
|
54845
54846
|
_g6_extensions_registered = true;
|
|
54846
54847
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.LAYOUT, "manual", ManualLayout);
|
|
54847
54848
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.LAYOUT, "treedb-tree", TreedbTreeLayout);
|
|
54848
|
-
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.LAYOUT, "treedb-outline", TreedbOutlineLayout);
|
|
54849
54849
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.LAYOUT, "treedb-radial", TreedbRadialLayout);
|
|
54850
54850
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.NODE, "light", LightNode);
|
|
54851
54851
|
}
|
|
@@ -54928,6 +54928,9 @@ function configure_events(gobj) {
|
|
|
54928
54928
|
graph.on(_antv_g6.NodeEvent.CONTEXT_MENU, (evt) => {
|
|
54929
54929
|
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_NODE_CONTEXT_MENU", { evt }, gobj);
|
|
54930
54930
|
});
|
|
54931
|
+
graph.on(_antv_g6.NodeEvent.DBLCLICK, (evt) => {
|
|
54932
|
+
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_NODE_DBLCLICK", { evt }, gobj);
|
|
54933
|
+
});
|
|
54931
54934
|
graph.on(_antv_g6.EdgeEvent.CLICK, (evt) => {
|
|
54932
54935
|
if (consume_long_press_click(graph)) return;
|
|
54933
54936
|
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_EDGE_CLICK", { evt }, gobj);
|
|
@@ -55352,7 +55355,7 @@ function configure_behaviour(gobj) {
|
|
|
55352
55355
|
case "writing":
|
|
55353
55356
|
case "reading":
|
|
55354
55357
|
priv.edit_mode = false;
|
|
55355
|
-
behaviors = ["drag-canvas",
|
|
55358
|
+
behaviors = ["drag-canvas", ...camera_behaviors()];
|
|
55356
55359
|
break;
|
|
55357
55360
|
case "edition":
|
|
55358
55361
|
priv.edit_mode = true;
|
|
@@ -55366,7 +55369,7 @@ function configure_behaviour(gobj) {
|
|
|
55366
55369
|
return true;
|
|
55367
55370
|
}
|
|
55368
55371
|
},
|
|
55369
|
-
|
|
55372
|
+
...camera_behaviors(),
|
|
55370
55373
|
"drag-element",
|
|
55371
55374
|
{
|
|
55372
55375
|
type: BRUSH_SELECT_OWNED,
|
|
@@ -55384,7 +55387,7 @@ function configure_behaviour(gobj) {
|
|
|
55384
55387
|
break;
|
|
55385
55388
|
case "operation":
|
|
55386
55389
|
priv.edit_mode = false;
|
|
55387
|
-
behaviors = ["drag-canvas",
|
|
55390
|
+
behaviors = ["drag-canvas", ...camera_behaviors()];
|
|
55388
55391
|
break;
|
|
55389
55392
|
default: (0, _yuneta_gobj_js.log_error)(`operation mode unknown: ${operation_mode}`);
|
|
55390
55393
|
}
|
|
@@ -55456,13 +55459,33 @@ function build_ports(gobj, desc) {
|
|
|
55456
55459
|
* Which way the graph reads. `dagre` is the left-to-right
|
|
55457
55460
|
* layout; everything else keeps the top-down reading, `manual`
|
|
55458
55461
|
* included, because the saved arrangements were made with the
|
|
55459
|
-
* ports on the top and bottom edges.
|
|
55460
|
-
|
|
55461
|
-
|
|
55462
|
-
|
|
55463
|
-
|
|
55464
|
-
|
|
55465
|
-
|
|
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
|
+
}
|
|
55466
55489
|
function layout_direction(gobj) {
|
|
55467
55490
|
return (0, _yuneta_gobj_js.str_in_list)(LR_LAYOUTS, gobj.priv.layout) ? "LR" : "TB";
|
|
55468
55491
|
}
|
|
@@ -55530,83 +55553,101 @@ function apply_layout_direction(gobj) {
|
|
|
55530
55553
|
* Create a topic node in the G6 graph
|
|
55531
55554
|
************************************************************/
|
|
55532
55555
|
function create_topic_node(gobj, desc, record) {
|
|
55533
|
-
|
|
55534
|
-
const graph = priv.graph;
|
|
55556
|
+
const graph = gobj.priv.graph;
|
|
55535
55557
|
let node_name = build_node_name(gobj, desc.topic_name, record.id);
|
|
55536
55558
|
let xy = get_default_ne_xy(gobj);
|
|
55537
55559
|
let geometry = get_node_graph_props(gobj, desc.topic_name, record.id, record);
|
|
55538
55560
|
let x = (0, _yuneta_gobj_js.kw_get_int)(gobj, geometry, "x", xy, _yuneta_gobj_js.kw_flag_t.KW_CREATE);
|
|
55539
55561
|
let y = (0, _yuneta_gobj_js.kw_get_int)(gobj, geometry, "y", xy, _yuneta_gobj_js.kw_flag_t.KW_CREATE);
|
|
55540
|
-
let
|
|
55541
|
-
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;
|
|
55542
55609
|
let node_treedb_type = desc.node_treedb_type;
|
|
55610
|
+
let label = node_label(desc, record);
|
|
55611
|
+
let ports = build_ports(gobj, desc);
|
|
55543
55612
|
let style = {
|
|
55544
|
-
x,
|
|
55545
|
-
y,
|
|
55546
55613
|
fill: desc.color,
|
|
55547
55614
|
stroke: getStrokeColor(desc.color),
|
|
55548
|
-
lineWidth: 1
|
|
55615
|
+
lineWidth: 1,
|
|
55616
|
+
lineDash: [],
|
|
55617
|
+
halo: false,
|
|
55618
|
+
labelText: ""
|
|
55549
55619
|
};
|
|
55550
|
-
let pills_html = pills_html_of_key(gobj, fold_node_key(desc.topic_name, String(record.id)));
|
|
55551
55620
|
let size = card_size_for(node_treedb_type, !!pills_html);
|
|
55552
|
-
|
|
55553
|
-
|
|
55554
|
-
|
|
55555
|
-
|
|
55556
|
-
|
|
55557
|
-
|
|
55558
|
-
} else if (node_treedb_type === "extended") {
|
|
55559
|
-
node_graph_type = "html";
|
|
55560
|
-
style.size = size;
|
|
55561
|
-
style.dx = -size[0] / 2;
|
|
55562
|
-
style.dy = -size[1] / 2;
|
|
55563
|
-
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);
|
|
55564
|
-
} else {
|
|
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, false, record.id, false, false, false, pills_html);
|
|
55570
|
-
}
|
|
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);
|
|
55571
55627
|
let topic_props = priv._graph_properties[desc.topic_name];
|
|
55572
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;
|
|
55573
55629
|
if (topic_defaults) {
|
|
55574
55630
|
let def_size = topic_defaults.size;
|
|
55575
55631
|
if (!geometry.size && Array.isArray(def_size) && def_size.length > 0) {
|
|
55576
55632
|
style.size = [...def_size];
|
|
55577
|
-
|
|
55578
|
-
|
|
55579
|
-
style.dy = -(def_size.length > 1 ? def_size[1] : def_size[0]) / 2;
|
|
55580
|
-
}
|
|
55633
|
+
style.dx = -def_size[0] / 2;
|
|
55634
|
+
style.dy = -(def_size.length > 1 ? def_size[1] : def_size[0]) / 2;
|
|
55581
55635
|
}
|
|
55582
55636
|
if (!geometry.portR && topic_defaults.portR > 0) style.portR = topic_defaults.portR;
|
|
55583
55637
|
}
|
|
55584
55638
|
let saved_size = geometry.size;
|
|
55585
55639
|
if (Array.isArray(saved_size) && saved_size.length > 0) {
|
|
55586
55640
|
style.size = saved_size;
|
|
55587
|
-
|
|
55588
|
-
|
|
55589
|
-
style.dy = -(saved_size.length > 1 ? saved_size[1] : saved_size[0]) / 2;
|
|
55590
|
-
}
|
|
55641
|
+
style.dx = -saved_size[0] / 2;
|
|
55642
|
+
style.dy = -(saved_size.length > 1 ? saved_size[1] : saved_size[0]) / 2;
|
|
55591
55643
|
}
|
|
55592
55644
|
if (geometry.portR > 0) style.portR = geometry.portR;
|
|
55593
|
-
let node_def = {
|
|
55594
|
-
id: node_name,
|
|
55595
|
-
type: node_graph_type,
|
|
55596
|
-
style,
|
|
55597
|
-
data: {
|
|
55598
|
-
topic_name: desc.topic_name,
|
|
55599
|
-
desc,
|
|
55600
|
-
record,
|
|
55601
|
-
graph_props: geometry
|
|
55602
|
-
}
|
|
55603
|
-
};
|
|
55604
55645
|
if ((0, _yuneta_gobj_js.json_size)(ports)) {
|
|
55605
55646
|
(0, _yuneta_gobj_js.json_object_update_missing)(style, {
|
|
55606
55647
|
port: true,
|
|
55607
55648
|
ports,
|
|
55608
|
-
portR: node_treedb_type === "child" ?
|
|
55609
|
-
portLineWidth:
|
|
55649
|
+
portR: node_treedb_type === "child" ? PORT_R_CHILD : PORT_R_ENTITY,
|
|
55650
|
+
portLineWidth: PORT_LINE_WIDTH
|
|
55610
55651
|
});
|
|
55611
55652
|
let port_sizes = geometry.port_sizes;
|
|
55612
55653
|
let default_port_sizes = topic_defaults ? topic_defaults.port_sizes : null;
|
|
@@ -55616,8 +55657,117 @@ function create_topic_node(gobj, desc, record) {
|
|
|
55616
55657
|
if (r == null && (0, _yuneta_gobj_js.is_object)(default_port_sizes)) r = default_port_sizes[key];
|
|
55617
55658
|
if (r != null) style.ports[i].r = r;
|
|
55618
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;
|
|
55619
55763
|
}
|
|
55620
|
-
|
|
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;
|
|
55621
55771
|
}
|
|
55622
55772
|
/************************************************************
|
|
55623
55773
|
* Update topic node data
|
|
@@ -56464,7 +56614,7 @@ var ManualLayout = class extends _antv_g6.BaseLayout {
|
|
|
56464
56614
|
}
|
|
56465
56615
|
};
|
|
56466
56616
|
/************************************************************
|
|
56467
|
-
* Custom G6 layouts: TreedbTreeLayout /
|
|
56617
|
+
* Custom G6 layouts: TreedbTreeLayout / TreedbRadialLayout.
|
|
56468
56618
|
*
|
|
56469
56619
|
* Thin adapters over treedb_layout.js: the nodes with their sizes,
|
|
56470
56620
|
* the edges with the RANK of the hook they leave by (the position
|
|
@@ -56482,7 +56632,8 @@ function treedb_layout_input(data) {
|
|
|
56482
56632
|
let w = (0, _yuneta_gobj_js.is_array)(size) ? size[0] : size;
|
|
56483
56633
|
let h = (0, _yuneta_gobj_js.is_array)(size) ? size.length > 1 ? size[1] : size[0] : size;
|
|
56484
56634
|
let ports = node.style && (0, _yuneta_gobj_js.is_array)(node.style.ports) ? node.style.ports : [];
|
|
56485
|
-
|
|
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);
|
|
56486
56637
|
return {
|
|
56487
56638
|
id: node.id,
|
|
56488
56639
|
w,
|
|
@@ -56518,12 +56669,6 @@ var TreedbTreeLayout = class extends _antv_g6.BaseLayout {
|
|
|
56518
56669
|
return treedb_layout_output(layout_tree(input.nodes, input.edges, options));
|
|
56519
56670
|
}
|
|
56520
56671
|
};
|
|
56521
|
-
var TreedbOutlineLayout = class extends _antv_g6.BaseLayout {
|
|
56522
|
-
async execute(data, options) {
|
|
56523
|
-
let input = treedb_layout_input(data);
|
|
56524
|
-
return treedb_layout_output(layout_outline(input.nodes, input.edges, options));
|
|
56525
|
-
}
|
|
56526
|
-
};
|
|
56527
56672
|
var TreedbRadialLayout = class extends _antv_g6.BaseLayout {
|
|
56528
56673
|
async execute(data, options) {
|
|
56529
56674
|
let input = treedb_layout_input(data);
|
|
@@ -57215,7 +57360,7 @@ function get_port_radius(gobj, node_id, port_key) {
|
|
|
57215
57360
|
if (ports[i].r != null) return ports[i].r;
|
|
57216
57361
|
break;
|
|
57217
57362
|
}
|
|
57218
|
-
return style.portR ||
|
|
57363
|
+
return style.portR || PORT_R_ENTITY;
|
|
57219
57364
|
}
|
|
57220
57365
|
/************************************************************
|
|
57221
57366
|
* How much wider than the port itself its hit area is,
|
|
@@ -57247,7 +57392,7 @@ function detect_port_click(gobj, node_id, canvasX, canvasY) {
|
|
|
57247
57392
|
const style = graph.getNodeData(node_id).style || {};
|
|
57248
57393
|
const { w, h } = extract_size(style);
|
|
57249
57394
|
const ports = style.ports || [];
|
|
57250
|
-
const defaultR = style.portR ||
|
|
57395
|
+
const defaultR = style.portR || PORT_R_ENTITY;
|
|
57251
57396
|
let best_key = null;
|
|
57252
57397
|
let best_dist = Infinity;
|
|
57253
57398
|
let slop = port_hit_slop_world(graph);
|
|
@@ -57404,7 +57549,7 @@ function enter_linking_mode(gobj) {
|
|
|
57404
57549
|
p.stroke = "#52c41a";
|
|
57405
57550
|
p.lineWidth = 3;
|
|
57406
57551
|
if (p.r != null) p.r = p.r + 4;
|
|
57407
|
-
else p.r = (style.portR ||
|
|
57552
|
+
else p.r = (style.portR || PORT_R_ENTITY) + 4;
|
|
57408
57553
|
}
|
|
57409
57554
|
graph.updateNodeData([{
|
|
57410
57555
|
id: vh.node_id,
|
|
@@ -57556,7 +57701,7 @@ function find_hook_at_point(gobj, canvasX, canvasY) {
|
|
|
57556
57701
|
let pl = p.placement || [.5, .5];
|
|
57557
57702
|
let px = pos[0] + (pl[0] - .5) * w;
|
|
57558
57703
|
let py = pos[1] + (pl[1] - .5) * h;
|
|
57559
|
-
let r = p.r != null ? p.r : style.portR ||
|
|
57704
|
+
let r = p.r != null ? p.r : style.portR || PORT_R_ENTITY;
|
|
57560
57705
|
let dx = canvasX - px;
|
|
57561
57706
|
let dy = canvasY - py;
|
|
57562
57707
|
if (Math.sqrt(dx * dx + dy * dy) <= r + 6) return {
|
|
@@ -58314,7 +58459,19 @@ function repaint_cards(gobj, ids) {
|
|
|
58314
58459
|
} catch (e) {
|
|
58315
58460
|
continue;
|
|
58316
58461
|
}
|
|
58317
|
-
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));
|
|
58318
58475
|
if (html !== null) updates.push({
|
|
58319
58476
|
id,
|
|
58320
58477
|
style: { innerHTML: html }
|
|
@@ -58351,7 +58508,19 @@ function refresh_html_nodes_theme(gobj, theme) {
|
|
|
58351
58508
|
for (let i = 0; i < nodes.length; i++) {
|
|
58352
58509
|
let id = nodes[i].id;
|
|
58353
58510
|
let nd = graph.getNodeData(id);
|
|
58354
|
-
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));
|
|
58355
58524
|
if (html === null) html = more_innerHTML_of(gobj, nd, theme);
|
|
58356
58525
|
if (html !== null) updates.push({
|
|
58357
58526
|
id,
|
|
@@ -58971,8 +59140,10 @@ function ctx_item(icon_id, label, value) {
|
|
|
58971
59140
|
************************************************************/
|
|
58972
59141
|
function build_node_context_menu(gobj, node_id) {
|
|
58973
59142
|
let items = [];
|
|
58974
|
-
|
|
58975
|
-
|
|
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)) {
|
|
58976
59147
|
items.push(ctx_item("g6-icon-resize", (0, i18next.t)("resize all"), "resize_all_nodes"));
|
|
58977
59148
|
items.push(ctx_item("g6-icon-resize", (0, i18next.t)("resize topic nodes"), "resize_topic_nodes"));
|
|
58978
59149
|
}
|
|
@@ -59000,8 +59171,11 @@ function build_edge_context_menu(gobj) {
|
|
|
59000
59171
|
* Handle context menu click: dispatch by value.
|
|
59001
59172
|
************************************************************/
|
|
59002
59173
|
function handle_context_menu_click(gobj, value) {
|
|
59003
|
-
gobj.priv;
|
|
59174
|
+
let priv = gobj.priv;
|
|
59004
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;
|
|
59005
59179
|
case "resize_all_nodes":
|
|
59006
59180
|
copy_size_to_nodes(gobj, false);
|
|
59007
59181
|
break;
|
|
@@ -59532,7 +59706,7 @@ async function reconcile_fold_apply(gobj, opts, visible) {
|
|
|
59532
59706
|
let nd = graph.getNodeData(id);
|
|
59533
59707
|
let desc = nd && nd.data && nd.data.desc;
|
|
59534
59708
|
let geometry = nd && nd.data && nd.data.graph_props || {};
|
|
59535
|
-
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)) {
|
|
59536
59710
|
let size = card_size_for(desc.node_treedb_type, !!sig);
|
|
59537
59711
|
resize.push({
|
|
59538
59712
|
id,
|
|
@@ -59617,6 +59791,7 @@ function ac_clear_data(gobj, event, kw, src) {
|
|
|
59617
59791
|
priv._fold_model = null;
|
|
59618
59792
|
priv._fold_state = null;
|
|
59619
59793
|
priv._pill_sig = null;
|
|
59794
|
+
priv._open_nodes = null;
|
|
59620
59795
|
graph_remove_plugin(gobj, "history");
|
|
59621
59796
|
update_history_buttons(gobj);
|
|
59622
59797
|
graph_clear(gobj);
|
|
@@ -60115,6 +60290,79 @@ function ac_set_loose_topics(gobj, event, kw, src) {
|
|
|
60115
60290
|
return 0;
|
|
60116
60291
|
}
|
|
60117
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
|
+
/************************************************************
|
|
60118
60366
|
* Tell whoever asked how many nodes the term matched. The count is
|
|
60119
60367
|
* the answer to the question the box asks; without it "nothing moved"
|
|
60120
60368
|
* and "nothing matched" look the same.
|
|
@@ -60604,6 +60852,26 @@ function create_gclass$4(gclass_name) {
|
|
|
60604
60852
|
ac_set_loose_topics,
|
|
60605
60853
|
null
|
|
60606
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
|
+
],
|
|
60607
60875
|
[
|
|
60608
60876
|
"EV_CENTER",
|
|
60609
60877
|
ac_center,
|
|
@@ -60708,6 +60976,10 @@ function create_gclass$4(gclass_name) {
|
|
|
60708
60976
|
["EV_SET_HIDDEN_TOPICS", 0],
|
|
60709
60977
|
["EV_SET_MAIN_TOPIC", 0],
|
|
60710
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],
|
|
60711
60983
|
["EV_LEGEND_STATE", _yuneta_gobj_js.event_flag_t.EVF_OUTPUT_EVENT],
|
|
60712
60984
|
["EV_CENTER", 0],
|
|
60713
60985
|
["EV_FULLSCREEN", 0],
|
|
@@ -60773,6 +61045,8 @@ var attrs_table$3 = [
|
|
|
60773
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"),
|
|
60774
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"),
|
|
60775
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"),
|
|
60776
61050
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_POINTER, "gobj_remote_yuno", 0, null, "Remote Yuno to request data"),
|
|
60777
61051
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "treedb_name", 0, null, "Remote service treedb name"),
|
|
60778
61052
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_DICT, "descs", 0, null, "Descriptions of topics obtained"),
|
|
@@ -60850,7 +61124,9 @@ function mt_create$3(gobj) {
|
|
|
60850
61124
|
fold_page_size: (0, _yuneta_gobj_js.gobj_read_integer_attr)(gobj, "fold_page_size"),
|
|
60851
61125
|
hidden_topics: (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "hidden_topics") || [],
|
|
60852
61126
|
main_topic: (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "main_topic") || "",
|
|
60853
|
-
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")
|
|
60854
61130
|
}, gobj);
|
|
60855
61131
|
populate_nodes_tree_options(gobj);
|
|
60856
61132
|
if (priv.with_treedb_tables) {}
|
|
@@ -60901,6 +61177,7 @@ function build_ui$3(gobj) {
|
|
|
60901
61177
|
let priv = gobj.priv;
|
|
60902
61178
|
let padding = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "padding");
|
|
60903
61179
|
let $toolbar = make_toolbar(gobj);
|
|
61180
|
+
refresh_node_shape_buttons(gobj, $toolbar);
|
|
60904
61181
|
let $back = make_back_to_topics(gobj);
|
|
60905
61182
|
let $container = (0, _yuneta_gobj_js.createElement2)([
|
|
60906
61183
|
"div",
|
|
@@ -61042,6 +61319,57 @@ function option_label(name) {
|
|
|
61042
61319
|
/************************************************************
|
|
61043
61320
|
*
|
|
61044
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
|
+
}
|
|
61045
61373
|
function make_toolbar(gobj) {
|
|
61046
61374
|
let priv = gobj.priv;
|
|
61047
61375
|
let modes = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "operation_modes");
|
|
@@ -61112,6 +61440,7 @@ function make_toolbar(gobj) {
|
|
|
61112
61440
|
} }
|
|
61113
61441
|
],
|
|
61114
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")),
|
|
61115
61444
|
[
|
|
61116
61445
|
"button",
|
|
61117
61446
|
{
|
|
@@ -62175,9 +62504,9 @@ function refresh_legend(gobj) {
|
|
|
62175
62504
|
hidden ? `${entry.total}` : `${entry.visible}/${entry.total}`
|
|
62176
62505
|
]);
|
|
62177
62506
|
let body_attrs = {
|
|
62178
|
-
class: "GRAPH_LEGEND_ITEM button is-small" + (focused ? "
|
|
62507
|
+
class: "GRAPH_LEGEND_ITEM button is-small" + (focused ? " GRAPH_LEGEND_FOCUSED" : "") + (is_main ? " GRAPH_LEGEND_MAIN" : ""),
|
|
62179
62508
|
type: "button",
|
|
62180
|
-
style: "gap:0; flex:0 0 auto;",
|
|
62509
|
+
style: "gap:0; flex:0 0 auto;" + (focused ? " box-shadow: inset 0 0 0 2px var(--bulma-text, #2e333d);" : ""),
|
|
62181
62510
|
title: is_main ? (0, i18next.t)("main topic") : hidden ? (0, i18next.t)("show topic") : (0, i18next.t)("hide topic"),
|
|
62182
62511
|
"aria-label": topic_name,
|
|
62183
62512
|
"aria-pressed": hidden ? "false" : "true"
|
|
@@ -62426,6 +62755,29 @@ function ac_collapse_all(gobj, event, kw, src) {
|
|
|
62426
62755
|
return 0;
|
|
62427
62756
|
}
|
|
62428
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
|
+
/************************************************************
|
|
62429
62781
|
* How many nodes the term matched, from the graph child. Zero with a
|
|
62430
62782
|
* term typed is an ANSWER and is shown; an empty box shows nothing.
|
|
62431
62783
|
************************************************************/
|
|
@@ -62639,6 +62991,16 @@ function create_gclass$3(gclass_name) {
|
|
|
62639
62991
|
ac_collapse_all,
|
|
62640
62992
|
null
|
|
62641
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
|
+
],
|
|
62642
63004
|
[
|
|
62643
63005
|
"EV_LAYOUT_AUTOSET",
|
|
62644
63006
|
ac_layout_autoset,
|
|
@@ -62703,6 +63065,8 @@ function create_gclass$3(gclass_name) {
|
|
|
62703
63065
|
["EV_FIND_NODES", 0],
|
|
62704
63066
|
["EV_EXPAND_ALL", 0],
|
|
62705
63067
|
["EV_COLLAPSE_ALL", 0],
|
|
63068
|
+
["EV_TOGGLE_NODE_MODE", 0],
|
|
63069
|
+
["EV_TOGGLE_NODE_LABELS", 0],
|
|
62706
63070
|
["EV_FIND_RESULT", 0],
|
|
62707
63071
|
["EV_LAYOUT_AUTOSET", 0],
|
|
62708
63072
|
["EV_LEGEND_TOPIC", 0],
|