@yuneta/gobj-ui 7.23.25 → 7.23.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/gobj-ui.cjs.js +88 -13
- package/dist/gobj-ui.es.js +88 -13
- package/package.json +1 -1
- package/src/c_yui_gobj_tree_js.js +35 -11
- package/src/c_yui_json.css +32 -0
- package/src/c_yui_json_graph.js +96 -19
- package/src/lib_graph.css +8 -0
- package/src/yui_graph_camera.js +30 -0
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -9710,8 +9710,18 @@ function yui_graph_update_anchor($container, state) {
|
|
|
9710
9710
|
* an error worth a log line per notch, they are all "there is
|
|
9711
9711
|
* nothing to centre right now".
|
|
9712
9712
|
************************************************************/
|
|
9713
|
+
var __centring__ = /* @__PURE__ */ new WeakMap();
|
|
9713
9714
|
async function yui_graph_center_on(graph, node_id) {
|
|
9714
9715
|
if (!graph || !node_id) return false;
|
|
9716
|
+
let st = __centring__.get(graph);
|
|
9717
|
+
if (st && st.running) {
|
|
9718
|
+
st.again = node_id;
|
|
9719
|
+
return true;
|
|
9720
|
+
}
|
|
9721
|
+
__centring__.set(graph, {
|
|
9722
|
+
running: true,
|
|
9723
|
+
again: null
|
|
9724
|
+
});
|
|
9715
9725
|
try {
|
|
9716
9726
|
if (typeof graph.getElementData === "function" && !graph.getElementData(node_id)) return false;
|
|
9717
9727
|
if (typeof graph.getElementPosition !== "function" || typeof graph.getViewportByCanvas !== "function" || typeof graph.getCanvasCenter !== "function" || typeof graph.translateTo !== "function") return false;
|
|
@@ -9727,6 +9737,13 @@ async function yui_graph_center_on(graph, node_id) {
|
|
|
9727
9737
|
return true;
|
|
9728
9738
|
} catch (e) {
|
|
9729
9739
|
return false;
|
|
9740
|
+
} finally {
|
|
9741
|
+
let pending = __centring__.get(graph);
|
|
9742
|
+
__centring__.set(graph, {
|
|
9743
|
+
running: false,
|
|
9744
|
+
again: null
|
|
9745
|
+
});
|
|
9746
|
+
if (pending && pending.again) yui_graph_center_on(graph, pending.again);
|
|
9730
9747
|
}
|
|
9731
9748
|
}
|
|
9732
9749
|
/************************************************************
|
|
@@ -10941,11 +10958,7 @@ function build_graph$3(gobj) {
|
|
|
10941
10958
|
}
|
|
10942
10959
|
},
|
|
10943
10960
|
layout: layout_cfg.g6_layout,
|
|
10944
|
-
behaviors:
|
|
10945
|
-
"drag-canvas",
|
|
10946
|
-
"zoom-canvas",
|
|
10947
|
-
"drag-element"
|
|
10948
|
-
]
|
|
10961
|
+
behaviors: BEHAVIORS_READING$1.slice()
|
|
10949
10962
|
});
|
|
10950
10963
|
if (priv.theme) graph.setTheme(priv.theme);
|
|
10951
10964
|
graph.on(_antv_g6.NodeEvent.CLICK, (evt) => {
|
|
@@ -11052,6 +11065,12 @@ function build_cell_html(key, value, type, dark, matched, fold) {
|
|
|
11052
11065
|
* forever. `+3` and `−` need no language.
|
|
11053
11066
|
************************************************************/
|
|
11054
11067
|
var FOLD_SPACER = `<span style="width:24px; flex:0 0 auto;"></span>`;
|
|
11068
|
+
var BEHAVIORS_READING$1 = [
|
|
11069
|
+
"drag-canvas",
|
|
11070
|
+
"zoom-canvas",
|
|
11071
|
+
"drag-element"
|
|
11072
|
+
];
|
|
11073
|
+
var BEHAVIORS_PICKING$1 = ["drag-canvas", "zoom-canvas"];
|
|
11055
11074
|
var CARD_HEADER_H$1 = 24;
|
|
11056
11075
|
var CARD_ROW_H$1 = 22;
|
|
11057
11076
|
function fold_toggle_html(path, foldable, folded, branches, colors) {
|
|
@@ -11188,7 +11207,7 @@ function build_json_nodes(gobj, path, kw, nodes, edges, parent_id, parent_port)
|
|
|
11188
11207
|
let min_width = Math.max(180, label.length * 9);
|
|
11189
11208
|
let card_height = CARD_HEADER_H$1 + lines.length * CARD_ROW_H$1;
|
|
11190
11209
|
let node_html = `
|
|
11191
|
-
<div style="
|
|
11210
|
+
<div class="JSON_CARD" data-json-path="${(0, _yuneta_gobj_js.escapeHtml)(path)}" style="
|
|
11192
11211
|
min-width: ${min_width}px;
|
|
11193
11212
|
background: ${colors.bg};
|
|
11194
11213
|
border: ${border_width}px ${is_dict ? "dashed" : "solid"} ${border_color};
|
|
@@ -11292,6 +11311,7 @@ function load_json(gobj) {
|
|
|
11292
11311
|
});
|
|
11293
11312
|
graph.render().then(() => {
|
|
11294
11313
|
reanchor$1(gobj);
|
|
11314
|
+
paint_anchor_mark(gobj);
|
|
11295
11315
|
if (preserve_view) {
|
|
11296
11316
|
yui_graph_update_zoom((0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container"), priv.graph);
|
|
11297
11317
|
return;
|
|
@@ -11613,10 +11633,48 @@ function reanchor$1(gobj) {
|
|
|
11613
11633
|
yui_graph_update_anchor((0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container"), priv.anchor_state);
|
|
11614
11634
|
}
|
|
11615
11635
|
/************************************************************
|
|
11636
|
+
* Reading, or picking the node to anchor.
|
|
11637
|
+
*
|
|
11638
|
+
* Two visible consequences and one invisible: the cursor says
|
|
11639
|
+
* a click is expected, the mount says which mode it is in for
|
|
11640
|
+
* anyone reading the DOM, and node dragging stands aside so a
|
|
11641
|
+
* click that drifts is still a click.
|
|
11642
|
+
************************************************************/
|
|
11643
|
+
function set_picking_mode$1(gobj, picking) {
|
|
11644
|
+
let graph = gobj.priv.graph;
|
|
11645
|
+
if (graph && typeof graph.setBehaviors === "function") graph.setBehaviors((picking ? BEHAVIORS_PICKING$1 : BEHAVIORS_READING$1).slice());
|
|
11646
|
+
let $container = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container");
|
|
11647
|
+
if ($container) {
|
|
11648
|
+
let $mount = $container.querySelector(".json-graph-container");
|
|
11649
|
+
if ($mount) $mount.classList.toggle("JSON_GRAPH_PICKING", !!picking);
|
|
11650
|
+
}
|
|
11651
|
+
}
|
|
11652
|
+
/************************************************************
|
|
11653
|
+
* Mark the card the camera is holding.
|
|
11654
|
+
*
|
|
11655
|
+
* A class on the card's own element and not a G6 node state:
|
|
11656
|
+
* G6 paints no state style on an html node, so `setElementState`
|
|
11657
|
+
* would select it correctly and show nothing.
|
|
11658
|
+
*
|
|
11659
|
+
* Re-applied after every rebuild, because the cards are new DOM
|
|
11660
|
+
* each time and the mark would otherwise survive only until the
|
|
11661
|
+
* next fold.
|
|
11662
|
+
************************************************************/
|
|
11663
|
+
function paint_anchor_mark(gobj) {
|
|
11664
|
+
let priv = gobj.priv;
|
|
11665
|
+
let $container = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container");
|
|
11666
|
+
if (!$container) return;
|
|
11667
|
+
for (let $card of $container.querySelectorAll(".JSON_CARD_ANCHORED")) $card.classList.remove("JSON_CARD_ANCHORED");
|
|
11668
|
+
if (priv.anchor_state !== "on" || !priv.anchor_path) return;
|
|
11669
|
+
let $it = $container.querySelector(".JSON_CARD[data-json-path=\"" + CSS.escape(priv.anchor_path) + "\"]");
|
|
11670
|
+
if ($it) $it.classList.add("JSON_CARD_ANCHORED");
|
|
11671
|
+
}
|
|
11672
|
+
/************************************************************
|
|
11616
11673
|
* Centre on the anchor, one cycle after it was chosen.
|
|
11617
11674
|
************************************************************/
|
|
11618
11675
|
function ac_center_anchor$2(gobj, event, kw, src) {
|
|
11619
11676
|
let priv = gobj.priv;
|
|
11677
|
+
paint_anchor_mark(gobj);
|
|
11620
11678
|
if (priv.anchor_state === "on" && priv.anchor_id) yui_graph_center_on(priv.graph, priv.anchor_id);
|
|
11621
11679
|
return 0;
|
|
11622
11680
|
}
|
|
@@ -11637,6 +11695,8 @@ function ac_toggle_anchor$2(gobj, event, kw, src) {
|
|
|
11637
11695
|
priv.anchor_path = "";
|
|
11638
11696
|
}
|
|
11639
11697
|
yui_graph_update_anchor((0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container"), priv.anchor_state);
|
|
11698
|
+
paint_anchor_mark(gobj);
|
|
11699
|
+
set_picking_mode$1(gobj, priv.anchor_state === "arming");
|
|
11640
11700
|
return 0;
|
|
11641
11701
|
}
|
|
11642
11702
|
/************************************************************
|
|
@@ -11703,6 +11763,7 @@ function ac_node_click$4(gobj, event, kw, src) {
|
|
|
11703
11763
|
priv.anchor_path = nodedata && nodedata.data ? nodedata.data.path : "";
|
|
11704
11764
|
priv.anchor_state = "on";
|
|
11705
11765
|
yui_graph_update_anchor((0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container"), priv.anchor_state);
|
|
11766
|
+
set_picking_mode$1(gobj, false);
|
|
11706
11767
|
(0, _yuneta_gobj_js.gobj_post_event)(gobj, "EV_CENTER_ANCHOR", {}, gobj);
|
|
11707
11768
|
return 0;
|
|
11708
11769
|
}
|
|
@@ -13169,6 +13230,12 @@ var attrs_table$9 = [
|
|
|
13169
13230
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_INTEGER, "collapse_threshold", 0, 10, "Auto-collapse a node whose direct children exceed this number. 0 disables auto-collapse."),
|
|
13170
13231
|
(0, _yuneta_gobj_js.SDATA_END)()
|
|
13171
13232
|
];
|
|
13233
|
+
var BEHAVIORS_READING = [
|
|
13234
|
+
"drag-canvas",
|
|
13235
|
+
"zoom-canvas",
|
|
13236
|
+
"drag-element"
|
|
13237
|
+
];
|
|
13238
|
+
var BEHAVIORS_PICKING = ["drag-canvas", "zoom-canvas"];
|
|
13172
13239
|
var PRIVATE_DATA$9 = {
|
|
13173
13240
|
canvas_id: "",
|
|
13174
13241
|
graph: null,
|
|
@@ -13650,11 +13717,7 @@ function build_graph$2(gobj) {
|
|
|
13650
13717
|
}
|
|
13651
13718
|
},
|
|
13652
13719
|
layout: layout_cfg.g6_layout,
|
|
13653
|
-
behaviors:
|
|
13654
|
-
"drag-canvas",
|
|
13655
|
-
"zoom-canvas",
|
|
13656
|
-
"drag-element"
|
|
13657
|
-
]
|
|
13720
|
+
behaviors: BEHAVIORS_READING.slice()
|
|
13658
13721
|
});
|
|
13659
13722
|
if (priv.theme) graph.setTheme(priv.theme);
|
|
13660
13723
|
graph.on("aftertransform", () => {
|
|
@@ -14526,6 +14589,16 @@ function ac_center_anchor$1(gobj, event, kw, src) {
|
|
|
14526
14589
|
return 0;
|
|
14527
14590
|
}
|
|
14528
14591
|
/************************************************************
|
|
14592
|
+
* Reading, or picking the node to anchor.
|
|
14593
|
+
************************************************************/
|
|
14594
|
+
function set_picking_mode(gobj, picking) {
|
|
14595
|
+
let graph = gobj.priv.graph;
|
|
14596
|
+
if (graph && typeof graph.setBehaviors === "function") graph.setBehaviors((picking ? BEHAVIORS_PICKING : BEHAVIORS_READING).slice());
|
|
14597
|
+
let $container = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container");
|
|
14598
|
+
let $mount = $container ? $container.querySelector(".gobj-tree-container") : null;
|
|
14599
|
+
if ($mount) $mount.classList.toggle("GOBJ_TREE_PICKING", !!picking);
|
|
14600
|
+
}
|
|
14601
|
+
/************************************************************
|
|
14529
14602
|
* Arm the anchor, or let it go.
|
|
14530
14603
|
*
|
|
14531
14604
|
* Three states and one button, so a press ADVANCES: with no
|
|
@@ -14542,6 +14615,7 @@ function ac_toggle_anchor$1(gobj, event, kw, src) {
|
|
|
14542
14615
|
priv.anchor_name = "";
|
|
14543
14616
|
}
|
|
14544
14617
|
yui_graph_update_anchor((0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container"), priv.anchor_state);
|
|
14618
|
+
set_picking_mode(gobj, priv.anchor_state === "arming");
|
|
14545
14619
|
return 0;
|
|
14546
14620
|
}
|
|
14547
14621
|
/************************************************************
|
|
@@ -14610,6 +14684,7 @@ function ac_node_click$3(gobj, event, kw, src) {
|
|
|
14610
14684
|
priv.anchor_name = node_data.full_name || "";
|
|
14611
14685
|
priv.anchor_state = "on";
|
|
14612
14686
|
yui_graph_update_anchor((0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container"), priv.anchor_state);
|
|
14687
|
+
set_picking_mode(gobj, false);
|
|
14613
14688
|
(0, _yuneta_gobj_js.gobj_post_event)(gobj, "EV_CENTER_ANCHOR", {}, gobj);
|
|
14614
14689
|
return 0;
|
|
14615
14690
|
}
|
|
@@ -37605,7 +37680,7 @@ Text.PARSED_STYLE_LIST = new Set([].concat(_toConsumableArray(DisplayObject.PARS
|
|
|
37605
37680
|
* * register property @see https://developer.mozilla.org/en-US/docs/Web/API/CSS/RegisterProperty
|
|
37606
37681
|
* * CSS Layout API
|
|
37607
37682
|
*/
|
|
37608
|
-
var CSS = {
|
|
37683
|
+
var CSS$1 = {
|
|
37609
37684
|
/**
|
|
37610
37685
|
* <number>
|
|
37611
37686
|
* @see https://drafts.csswg.org/css-values-4/#number-value
|
|
@@ -47654,7 +47729,7 @@ var e = 1e-4;
|
|
|
47654
47729
|
syntax: PropertySyntax.ANGLE
|
|
47655
47730
|
}
|
|
47656
47731
|
].forEach(function(property) {
|
|
47657
|
-
CSS.registerProperty(property);
|
|
47732
|
+
CSS$1.registerProperty(property);
|
|
47658
47733
|
});
|
|
47659
47734
|
var polarToCartesian = function polarToCartesian(centerX, centerY, radius, angleInRadian) {
|
|
47660
47735
|
return {
|
package/dist/gobj-ui.es.js
CHANGED
|
@@ -9705,8 +9705,18 @@ function yui_graph_update_anchor($container, state) {
|
|
|
9705
9705
|
* an error worth a log line per notch, they are all "there is
|
|
9706
9706
|
* nothing to centre right now".
|
|
9707
9707
|
************************************************************/
|
|
9708
|
+
var __centring__ = /* @__PURE__ */ new WeakMap();
|
|
9708
9709
|
async function yui_graph_center_on(graph, node_id) {
|
|
9709
9710
|
if (!graph || !node_id) return false;
|
|
9711
|
+
let st = __centring__.get(graph);
|
|
9712
|
+
if (st && st.running) {
|
|
9713
|
+
st.again = node_id;
|
|
9714
|
+
return true;
|
|
9715
|
+
}
|
|
9716
|
+
__centring__.set(graph, {
|
|
9717
|
+
running: true,
|
|
9718
|
+
again: null
|
|
9719
|
+
});
|
|
9710
9720
|
try {
|
|
9711
9721
|
if (typeof graph.getElementData === "function" && !graph.getElementData(node_id)) return false;
|
|
9712
9722
|
if (typeof graph.getElementPosition !== "function" || typeof graph.getViewportByCanvas !== "function" || typeof graph.getCanvasCenter !== "function" || typeof graph.translateTo !== "function") return false;
|
|
@@ -9722,6 +9732,13 @@ async function yui_graph_center_on(graph, node_id) {
|
|
|
9722
9732
|
return true;
|
|
9723
9733
|
} catch (e) {
|
|
9724
9734
|
return false;
|
|
9735
|
+
} finally {
|
|
9736
|
+
let pending = __centring__.get(graph);
|
|
9737
|
+
__centring__.set(graph, {
|
|
9738
|
+
running: false,
|
|
9739
|
+
again: null
|
|
9740
|
+
});
|
|
9741
|
+
if (pending && pending.again) yui_graph_center_on(graph, pending.again);
|
|
9725
9742
|
}
|
|
9726
9743
|
}
|
|
9727
9744
|
/************************************************************
|
|
@@ -10936,11 +10953,7 @@ function build_graph$3(gobj) {
|
|
|
10936
10953
|
}
|
|
10937
10954
|
},
|
|
10938
10955
|
layout: layout_cfg.g6_layout,
|
|
10939
|
-
behaviors:
|
|
10940
|
-
"drag-canvas",
|
|
10941
|
-
"zoom-canvas",
|
|
10942
|
-
"drag-element"
|
|
10943
|
-
]
|
|
10956
|
+
behaviors: BEHAVIORS_READING$1.slice()
|
|
10944
10957
|
});
|
|
10945
10958
|
if (priv.theme) graph.setTheme(priv.theme);
|
|
10946
10959
|
graph.on(NodeEvent.CLICK, (evt) => {
|
|
@@ -11047,6 +11060,12 @@ function build_cell_html(key, value, type, dark, matched, fold) {
|
|
|
11047
11060
|
* forever. `+3` and `−` need no language.
|
|
11048
11061
|
************************************************************/
|
|
11049
11062
|
var FOLD_SPACER = `<span style="width:24px; flex:0 0 auto;"></span>`;
|
|
11063
|
+
var BEHAVIORS_READING$1 = [
|
|
11064
|
+
"drag-canvas",
|
|
11065
|
+
"zoom-canvas",
|
|
11066
|
+
"drag-element"
|
|
11067
|
+
];
|
|
11068
|
+
var BEHAVIORS_PICKING$1 = ["drag-canvas", "zoom-canvas"];
|
|
11050
11069
|
var CARD_HEADER_H$1 = 24;
|
|
11051
11070
|
var CARD_ROW_H$1 = 22;
|
|
11052
11071
|
function fold_toggle_html(path, foldable, folded, branches, colors) {
|
|
@@ -11183,7 +11202,7 @@ function build_json_nodes(gobj, path, kw, nodes, edges, parent_id, parent_port)
|
|
|
11183
11202
|
let min_width = Math.max(180, label.length * 9);
|
|
11184
11203
|
let card_height = CARD_HEADER_H$1 + lines.length * CARD_ROW_H$1;
|
|
11185
11204
|
let node_html = `
|
|
11186
|
-
<div style="
|
|
11205
|
+
<div class="JSON_CARD" data-json-path="${escapeHtml(path)}" style="
|
|
11187
11206
|
min-width: ${min_width}px;
|
|
11188
11207
|
background: ${colors.bg};
|
|
11189
11208
|
border: ${border_width}px ${is_dict ? "dashed" : "solid"} ${border_color};
|
|
@@ -11287,6 +11306,7 @@ function load_json(gobj) {
|
|
|
11287
11306
|
});
|
|
11288
11307
|
graph.render().then(() => {
|
|
11289
11308
|
reanchor$1(gobj);
|
|
11309
|
+
paint_anchor_mark(gobj);
|
|
11290
11310
|
if (preserve_view) {
|
|
11291
11311
|
yui_graph_update_zoom(gobj_read_attr(gobj, "$container"), priv.graph);
|
|
11292
11312
|
return;
|
|
@@ -11608,10 +11628,48 @@ function reanchor$1(gobj) {
|
|
|
11608
11628
|
yui_graph_update_anchor(gobj_read_attr(gobj, "$container"), priv.anchor_state);
|
|
11609
11629
|
}
|
|
11610
11630
|
/************************************************************
|
|
11631
|
+
* Reading, or picking the node to anchor.
|
|
11632
|
+
*
|
|
11633
|
+
* Two visible consequences and one invisible: the cursor says
|
|
11634
|
+
* a click is expected, the mount says which mode it is in for
|
|
11635
|
+
* anyone reading the DOM, and node dragging stands aside so a
|
|
11636
|
+
* click that drifts is still a click.
|
|
11637
|
+
************************************************************/
|
|
11638
|
+
function set_picking_mode$1(gobj, picking) {
|
|
11639
|
+
let graph = gobj.priv.graph;
|
|
11640
|
+
if (graph && typeof graph.setBehaviors === "function") graph.setBehaviors((picking ? BEHAVIORS_PICKING$1 : BEHAVIORS_READING$1).slice());
|
|
11641
|
+
let $container = gobj_read_attr(gobj, "$container");
|
|
11642
|
+
if ($container) {
|
|
11643
|
+
let $mount = $container.querySelector(".json-graph-container");
|
|
11644
|
+
if ($mount) $mount.classList.toggle("JSON_GRAPH_PICKING", !!picking);
|
|
11645
|
+
}
|
|
11646
|
+
}
|
|
11647
|
+
/************************************************************
|
|
11648
|
+
* Mark the card the camera is holding.
|
|
11649
|
+
*
|
|
11650
|
+
* A class on the card's own element and not a G6 node state:
|
|
11651
|
+
* G6 paints no state style on an html node, so `setElementState`
|
|
11652
|
+
* would select it correctly and show nothing.
|
|
11653
|
+
*
|
|
11654
|
+
* Re-applied after every rebuild, because the cards are new DOM
|
|
11655
|
+
* each time and the mark would otherwise survive only until the
|
|
11656
|
+
* next fold.
|
|
11657
|
+
************************************************************/
|
|
11658
|
+
function paint_anchor_mark(gobj) {
|
|
11659
|
+
let priv = gobj.priv;
|
|
11660
|
+
let $container = gobj_read_attr(gobj, "$container");
|
|
11661
|
+
if (!$container) return;
|
|
11662
|
+
for (let $card of $container.querySelectorAll(".JSON_CARD_ANCHORED")) $card.classList.remove("JSON_CARD_ANCHORED");
|
|
11663
|
+
if (priv.anchor_state !== "on" || !priv.anchor_path) return;
|
|
11664
|
+
let $it = $container.querySelector(".JSON_CARD[data-json-path=\"" + CSS.escape(priv.anchor_path) + "\"]");
|
|
11665
|
+
if ($it) $it.classList.add("JSON_CARD_ANCHORED");
|
|
11666
|
+
}
|
|
11667
|
+
/************************************************************
|
|
11611
11668
|
* Centre on the anchor, one cycle after it was chosen.
|
|
11612
11669
|
************************************************************/
|
|
11613
11670
|
function ac_center_anchor$2(gobj, event, kw, src) {
|
|
11614
11671
|
let priv = gobj.priv;
|
|
11672
|
+
paint_anchor_mark(gobj);
|
|
11615
11673
|
if (priv.anchor_state === "on" && priv.anchor_id) yui_graph_center_on(priv.graph, priv.anchor_id);
|
|
11616
11674
|
return 0;
|
|
11617
11675
|
}
|
|
@@ -11632,6 +11690,8 @@ function ac_toggle_anchor$2(gobj, event, kw, src) {
|
|
|
11632
11690
|
priv.anchor_path = "";
|
|
11633
11691
|
}
|
|
11634
11692
|
yui_graph_update_anchor(gobj_read_attr(gobj, "$container"), priv.anchor_state);
|
|
11693
|
+
paint_anchor_mark(gobj);
|
|
11694
|
+
set_picking_mode$1(gobj, priv.anchor_state === "arming");
|
|
11635
11695
|
return 0;
|
|
11636
11696
|
}
|
|
11637
11697
|
/************************************************************
|
|
@@ -11698,6 +11758,7 @@ function ac_node_click$4(gobj, event, kw, src) {
|
|
|
11698
11758
|
priv.anchor_path = nodedata && nodedata.data ? nodedata.data.path : "";
|
|
11699
11759
|
priv.anchor_state = "on";
|
|
11700
11760
|
yui_graph_update_anchor(gobj_read_attr(gobj, "$container"), priv.anchor_state);
|
|
11761
|
+
set_picking_mode$1(gobj, false);
|
|
11701
11762
|
gobj_post_event(gobj, "EV_CENTER_ANCHOR", {}, gobj);
|
|
11702
11763
|
return 0;
|
|
11703
11764
|
}
|
|
@@ -13164,6 +13225,12 @@ var attrs_table$9 = [
|
|
|
13164
13225
|
SDATA(data_type_t.DTP_INTEGER, "collapse_threshold", 0, 10, "Auto-collapse a node whose direct children exceed this number. 0 disables auto-collapse."),
|
|
13165
13226
|
SDATA_END()
|
|
13166
13227
|
];
|
|
13228
|
+
var BEHAVIORS_READING = [
|
|
13229
|
+
"drag-canvas",
|
|
13230
|
+
"zoom-canvas",
|
|
13231
|
+
"drag-element"
|
|
13232
|
+
];
|
|
13233
|
+
var BEHAVIORS_PICKING = ["drag-canvas", "zoom-canvas"];
|
|
13167
13234
|
var PRIVATE_DATA$9 = {
|
|
13168
13235
|
canvas_id: "",
|
|
13169
13236
|
graph: null,
|
|
@@ -13645,11 +13712,7 @@ function build_graph$2(gobj) {
|
|
|
13645
13712
|
}
|
|
13646
13713
|
},
|
|
13647
13714
|
layout: layout_cfg.g6_layout,
|
|
13648
|
-
behaviors:
|
|
13649
|
-
"drag-canvas",
|
|
13650
|
-
"zoom-canvas",
|
|
13651
|
-
"drag-element"
|
|
13652
|
-
]
|
|
13715
|
+
behaviors: BEHAVIORS_READING.slice()
|
|
13653
13716
|
});
|
|
13654
13717
|
if (priv.theme) graph.setTheme(priv.theme);
|
|
13655
13718
|
graph.on("aftertransform", () => {
|
|
@@ -14521,6 +14584,16 @@ function ac_center_anchor$1(gobj, event, kw, src) {
|
|
|
14521
14584
|
return 0;
|
|
14522
14585
|
}
|
|
14523
14586
|
/************************************************************
|
|
14587
|
+
* Reading, or picking the node to anchor.
|
|
14588
|
+
************************************************************/
|
|
14589
|
+
function set_picking_mode(gobj, picking) {
|
|
14590
|
+
let graph = gobj.priv.graph;
|
|
14591
|
+
if (graph && typeof graph.setBehaviors === "function") graph.setBehaviors((picking ? BEHAVIORS_PICKING : BEHAVIORS_READING).slice());
|
|
14592
|
+
let $container = gobj_read_attr(gobj, "$container");
|
|
14593
|
+
let $mount = $container ? $container.querySelector(".gobj-tree-container") : null;
|
|
14594
|
+
if ($mount) $mount.classList.toggle("GOBJ_TREE_PICKING", !!picking);
|
|
14595
|
+
}
|
|
14596
|
+
/************************************************************
|
|
14524
14597
|
* Arm the anchor, or let it go.
|
|
14525
14598
|
*
|
|
14526
14599
|
* Three states and one button, so a press ADVANCES: with no
|
|
@@ -14537,6 +14610,7 @@ function ac_toggle_anchor$1(gobj, event, kw, src) {
|
|
|
14537
14610
|
priv.anchor_name = "";
|
|
14538
14611
|
}
|
|
14539
14612
|
yui_graph_update_anchor(gobj_read_attr(gobj, "$container"), priv.anchor_state);
|
|
14613
|
+
set_picking_mode(gobj, priv.anchor_state === "arming");
|
|
14540
14614
|
return 0;
|
|
14541
14615
|
}
|
|
14542
14616
|
/************************************************************
|
|
@@ -14605,6 +14679,7 @@ function ac_node_click$3(gobj, event, kw, src) {
|
|
|
14605
14679
|
priv.anchor_name = node_data.full_name || "";
|
|
14606
14680
|
priv.anchor_state = "on";
|
|
14607
14681
|
yui_graph_update_anchor(gobj_read_attr(gobj, "$container"), priv.anchor_state);
|
|
14682
|
+
set_picking_mode(gobj, false);
|
|
14608
14683
|
gobj_post_event(gobj, "EV_CENTER_ANCHOR", {}, gobj);
|
|
14609
14684
|
return 0;
|
|
14610
14685
|
}
|
|
@@ -37600,7 +37675,7 @@ Text.PARSED_STYLE_LIST = new Set([].concat(_toConsumableArray(DisplayObject.PARS
|
|
|
37600
37675
|
* * register property @see https://developer.mozilla.org/en-US/docs/Web/API/CSS/RegisterProperty
|
|
37601
37676
|
* * CSS Layout API
|
|
37602
37677
|
*/
|
|
37603
|
-
var CSS = {
|
|
37678
|
+
var CSS$1 = {
|
|
37604
37679
|
/**
|
|
37605
37680
|
* <number>
|
|
37606
37681
|
* @see https://drafts.csswg.org/css-values-4/#number-value
|
|
@@ -47649,7 +47724,7 @@ var e = 1e-4;
|
|
|
47649
47724
|
syntax: PropertySyntax.ANGLE
|
|
47650
47725
|
}
|
|
47651
47726
|
].forEach(function(property) {
|
|
47652
|
-
CSS.registerProperty(property);
|
|
47727
|
+
CSS$1.registerProperty(property);
|
|
47653
47728
|
});
|
|
47654
47729
|
var polarToCartesian = function polarToCartesian(centerX, centerY, radius, angleInRadian) {
|
|
47655
47730
|
return {
|
package/package.json
CHANGED
|
@@ -90,6 +90,20 @@ SDATA(data_type_t.DTP_INTEGER, "collapse_threshold", 0, 10, "Auto-collapse a no
|
|
|
90
90
|
SDATA_END()
|
|
91
91
|
];
|
|
92
92
|
|
|
93
|
+
/*
|
|
94
|
+
* What the graph listens for while you are READING it, and while you
|
|
95
|
+
* are PICKING the node to anchor.
|
|
96
|
+
*
|
|
97
|
+
* The difference is `drag-element`: with it on, a click that drifts
|
|
98
|
+
* two pixels -- which is every click a hand makes -- becomes a drag,
|
|
99
|
+
* G6 fires no `node:click`, and the pick silently does not happen.
|
|
100
|
+
* Swapped with `setBehaviors()` and not with a behavior's `enable`,
|
|
101
|
+
* which REPLACES the behavior's own default test rather than adding
|
|
102
|
+
* to it.
|
|
103
|
+
*/
|
|
104
|
+
const BEHAVIORS_READING = ['drag-canvas', 'zoom-canvas', 'drag-element'];
|
|
105
|
+
const BEHAVIORS_PICKING = ['drag-canvas', 'zoom-canvas'];
|
|
106
|
+
|
|
93
107
|
let PRIVATE_DATA = {
|
|
94
108
|
canvas_id: "",
|
|
95
109
|
graph: null,
|
|
@@ -654,17 +668,7 @@ function build_graph(gobj)
|
|
|
654
668
|
|
|
655
669
|
layout: layout_cfg.g6_layout,
|
|
656
670
|
|
|
657
|
-
behaviors:
|
|
658
|
-
'drag-canvas',
|
|
659
|
-
'zoom-canvas',
|
|
660
|
-
/* Move a card by dragging it. The position is not kept --
|
|
661
|
-
* this tree is rebuilt from the live gobj tree on every
|
|
662
|
-
* refresh -- and it is still worth having: pulling two
|
|
663
|
-
* cards apart to read the lines between them is the whole
|
|
664
|
-
* use of it. `enable` REPLACES a behavior's default rather
|
|
665
|
-
* than adding to it, so it is not passed. */
|
|
666
|
-
'drag-element',
|
|
667
|
-
],
|
|
671
|
+
behaviors: BEHAVIORS_READING.slice(),
|
|
668
672
|
});
|
|
669
673
|
|
|
670
674
|
if(priv.theme) {
|
|
@@ -2014,6 +2018,24 @@ function ac_center_anchor(gobj, event, kw, src)
|
|
|
2014
2018
|
return 0;
|
|
2015
2019
|
}
|
|
2016
2020
|
|
|
2021
|
+
/************************************************************
|
|
2022
|
+
* Reading, or picking the node to anchor.
|
|
2023
|
+
************************************************************/
|
|
2024
|
+
function set_picking_mode(gobj, picking)
|
|
2025
|
+
{
|
|
2026
|
+
let graph = gobj.priv.graph;
|
|
2027
|
+
|
|
2028
|
+
if(graph && typeof graph.setBehaviors === "function") {
|
|
2029
|
+
graph.setBehaviors((picking? BEHAVIORS_PICKING: BEHAVIORS_READING).slice());
|
|
2030
|
+
}
|
|
2031
|
+
|
|
2032
|
+
let $container = gobj_read_attr(gobj, "$container");
|
|
2033
|
+
let $mount = $container? $container.querySelector('.gobj-tree-container'): null;
|
|
2034
|
+
if($mount) {
|
|
2035
|
+
$mount.classList.toggle('GOBJ_TREE_PICKING', !!picking);
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2017
2039
|
/************************************************************
|
|
2018
2040
|
* Arm the anchor, or let it go.
|
|
2019
2041
|
*
|
|
@@ -2035,6 +2057,7 @@ function ac_toggle_anchor(gobj, event, kw, src)
|
|
|
2035
2057
|
}
|
|
2036
2058
|
|
|
2037
2059
|
yui_graph_update_anchor(gobj_read_attr(gobj, "$container"), priv.anchor_state);
|
|
2060
|
+
set_picking_mode(gobj, priv.anchor_state === "arming");
|
|
2038
2061
|
return 0;
|
|
2039
2062
|
}
|
|
2040
2063
|
|
|
@@ -2139,6 +2162,7 @@ function ac_node_click(gobj, event, kw, src)
|
|
|
2139
2162
|
priv.anchor_name = node_data.full_name || "";
|
|
2140
2163
|
priv.anchor_state = "on";
|
|
2141
2164
|
yui_graph_update_anchor(gobj_read_attr(gobj, "$container"), priv.anchor_state);
|
|
2165
|
+
set_picking_mode(gobj, false);
|
|
2142
2166
|
|
|
2143
2167
|
/* POSTED, not made here: a camera move issued inside G6's click
|
|
2144
2168
|
* dispatch is swallowed -- see the note in yui_graph_center_on.
|
package/src/c_yui_json.css
CHANGED
|
@@ -293,6 +293,38 @@
|
|
|
293
293
|
z-index: 1;
|
|
294
294
|
}
|
|
295
295
|
|
|
296
|
+
/*
|
|
297
|
+
* Picking the node to anchor. The pointer says a click is expected --
|
|
298
|
+
* without it the only sign the graph is waiting for one is a button
|
|
299
|
+
* at the far end of a toolbar.
|
|
300
|
+
*/
|
|
301
|
+
.C_YUI_JSON .json-graph-container.JSON_GRAPH_PICKING,
|
|
302
|
+
.C_YUI_JSON .json-graph-container.JSON_GRAPH_PICKING * {
|
|
303
|
+
cursor: crosshair;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/*
|
|
307
|
+
* The card the camera is holding.
|
|
308
|
+
*
|
|
309
|
+
* It has to say so ON THE CARD: the toolbar button knows an anchor is
|
|
310
|
+
* set, and knowing WHICH node it is was left to the reader remembering
|
|
311
|
+
* what they clicked -- which is not a mark, it is a memory test.
|
|
312
|
+
*
|
|
313
|
+
* An outline and not a fill: the card's own colours mean things (a
|
|
314
|
+
* dashed border is a dict, a solid one a list, the header carries the
|
|
315
|
+
* group's hue), and a mark that repaints any of them would be saying
|
|
316
|
+
* two things with one channel. `outline` also draws OUTSIDE the box,
|
|
317
|
+
* so it cannot move a single row.
|
|
318
|
+
*
|
|
319
|
+
* Amber, the same "this one, right now" the toolbar's arming state
|
|
320
|
+
* uses. It is not one of the palette's action colours because it is
|
|
321
|
+
* not an action.
|
|
322
|
+
*/
|
|
323
|
+
.C_YUI_JSON .JSON_CARD_ANCHORED {
|
|
324
|
+
outline: 3px solid #fa8c16;
|
|
325
|
+
outline-offset: 2px;
|
|
326
|
+
}
|
|
327
|
+
|
|
296
328
|
/*
|
|
297
329
|
* The graph mount, once its cards can be DRAGGED.
|
|
298
330
|
*
|
package/src/c_yui_json_graph.js
CHANGED
|
@@ -692,24 +692,7 @@ function build_graph(gobj)
|
|
|
692
692
|
|
|
693
693
|
layout: layout_cfg.g6_layout,
|
|
694
694
|
|
|
695
|
-
behaviors:
|
|
696
|
-
'drag-canvas',
|
|
697
|
-
'zoom-canvas',
|
|
698
|
-
/*
|
|
699
|
-
* Move a card by dragging it. The position is NOT kept:
|
|
700
|
-
* the graph is rebuilt from the document on every refresh,
|
|
701
|
-
* fold and layout change, and there is nothing here to
|
|
702
|
-
* save it to -- this is a viewer over a value somebody
|
|
703
|
-
* handed it, not a document of its own. Deliberate: being
|
|
704
|
-
* able to pull two cards apart to read the lines between
|
|
705
|
-
* them is worth having even when it lasts one session.
|
|
706
|
-
*
|
|
707
|
-
* No `enable`: a behavior's `enable` REPLACES the default,
|
|
708
|
-
* it does not add to it, and the default here is exactly
|
|
709
|
-
* what is wanted.
|
|
710
|
-
*/
|
|
711
|
-
'drag-element',
|
|
712
|
-
],
|
|
695
|
+
behaviors: BEHAVIORS_READING.slice(),
|
|
713
696
|
});
|
|
714
697
|
|
|
715
698
|
if(priv.theme) {
|
|
@@ -899,6 +882,23 @@ function build_cell_html(key, value, type, dark, matched, fold)
|
|
|
899
882
|
************************************************************/
|
|
900
883
|
const FOLD_SPACER = `<span style="width:24px; flex:0 0 auto;"></span>`;
|
|
901
884
|
|
|
885
|
+
/*
|
|
886
|
+
* What the graph listens for while you are READING it, and while you
|
|
887
|
+
* are PICKING the node to anchor.
|
|
888
|
+
*
|
|
889
|
+
* The difference is `drag-element`, and dropping it is not a detail:
|
|
890
|
+
* with it on, a click that drifts two pixels -- which is every click a
|
|
891
|
+
* hand makes -- becomes a drag, G6 fires no `node:click`, and the pick
|
|
892
|
+
* silently does not happen. Measured: an instant click anchors, the
|
|
893
|
+
* same click with 2px of movement does not.
|
|
894
|
+
*
|
|
895
|
+
* Swapped with `setBehaviors()` and not with a behavior's `enable`,
|
|
896
|
+
* which REPLACES the behavior's own default test rather than adding to
|
|
897
|
+
* it -- the trap that made a card drag pan the canvas in 7.23.10.
|
|
898
|
+
*/
|
|
899
|
+
const BEHAVIORS_READING = ['drag-canvas', 'zoom-canvas', 'drag-element'];
|
|
900
|
+
const BEHAVIORS_PICKING = ['drag-canvas', 'zoom-canvas'];
|
|
901
|
+
|
|
902
902
|
/*
|
|
903
903
|
* The card's geometry, in ONE place.
|
|
904
904
|
*
|
|
@@ -1152,8 +1152,21 @@ function build_json_nodes(gobj, path, kw, nodes, edges, parent_id, parent_port)
|
|
|
1152
1152
|
let min_width = Math.max(180, label.length * 9);
|
|
1153
1153
|
let card_height = CARD_HEADER_H + lines.length * CARD_ROW_H;
|
|
1154
1154
|
|
|
1155
|
+
/*
|
|
1156
|
+
* The card carries its NAME and its PLACE in the document.
|
|
1157
|
+
*
|
|
1158
|
+
* `JSON_CARD` because a gclass that builds DOM has to leave a tree
|
|
1159
|
+
* somebody can read in the Inspector, and until now every card here
|
|
1160
|
+
* was an anonymous `<div>` among the anonymous `<div>`s G6 stacks.
|
|
1161
|
+
*
|
|
1162
|
+
* `data-json-path` because the anchor has to be able to find the
|
|
1163
|
+
* card it is holding: G6 paints no state style on an html node, so
|
|
1164
|
+
* the mark cannot be a node state and has to be a class on this
|
|
1165
|
+
* element -- and the path is what survives a rebuild, where the
|
|
1166
|
+
* node id does not.
|
|
1167
|
+
*/
|
|
1155
1168
|
let node_html = `
|
|
1156
|
-
<div style="
|
|
1169
|
+
<div class="JSON_CARD" data-json-path="${escapeHtml(path)}" style="
|
|
1157
1170
|
min-width: ${min_width}px;
|
|
1158
1171
|
background: ${colors.bg};
|
|
1159
1172
|
border: ${border_width}px ${is_dict ? 'dashed' : 'solid'} ${border_color};
|
|
@@ -1348,6 +1361,7 @@ function load_json(gobj)
|
|
|
1348
1361
|
/* Ids are generated per build: point the anchor at its path
|
|
1349
1362
|
* again before anybody asks the camera to go there. */
|
|
1350
1363
|
reanchor(gobj);
|
|
1364
|
+
paint_anchor_mark(gobj);
|
|
1351
1365
|
|
|
1352
1366
|
if(preserve_view) {
|
|
1353
1367
|
yui_graph_update_zoom(gobj_read_attr(gobj, "$container"), priv.graph);
|
|
@@ -1820,6 +1834,65 @@ function reanchor(gobj)
|
|
|
1820
1834
|
yui_graph_update_anchor(gobj_read_attr(gobj, "$container"), priv.anchor_state);
|
|
1821
1835
|
}
|
|
1822
1836
|
|
|
1837
|
+
/************************************************************
|
|
1838
|
+
* Reading, or picking the node to anchor.
|
|
1839
|
+
*
|
|
1840
|
+
* Two visible consequences and one invisible: the cursor says
|
|
1841
|
+
* a click is expected, the mount says which mode it is in for
|
|
1842
|
+
* anyone reading the DOM, and node dragging stands aside so a
|
|
1843
|
+
* click that drifts is still a click.
|
|
1844
|
+
************************************************************/
|
|
1845
|
+
function set_picking_mode(gobj, picking)
|
|
1846
|
+
{
|
|
1847
|
+
let priv = gobj.priv;
|
|
1848
|
+
let graph = priv.graph;
|
|
1849
|
+
|
|
1850
|
+
if(graph && typeof graph.setBehaviors === "function") {
|
|
1851
|
+
graph.setBehaviors((picking? BEHAVIORS_PICKING: BEHAVIORS_READING).slice());
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1854
|
+
let $container = gobj_read_attr(gobj, "$container");
|
|
1855
|
+
if($container) {
|
|
1856
|
+
let $mount = $container.querySelector('.json-graph-container');
|
|
1857
|
+
if($mount) {
|
|
1858
|
+
$mount.classList.toggle('JSON_GRAPH_PICKING', !!picking);
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1862
|
+
|
|
1863
|
+
/************************************************************
|
|
1864
|
+
* Mark the card the camera is holding.
|
|
1865
|
+
*
|
|
1866
|
+
* A class on the card's own element and not a G6 node state:
|
|
1867
|
+
* G6 paints no state style on an html node, so `setElementState`
|
|
1868
|
+
* would select it correctly and show nothing.
|
|
1869
|
+
*
|
|
1870
|
+
* Re-applied after every rebuild, because the cards are new DOM
|
|
1871
|
+
* each time and the mark would otherwise survive only until the
|
|
1872
|
+
* next fold.
|
|
1873
|
+
************************************************************/
|
|
1874
|
+
function paint_anchor_mark(gobj)
|
|
1875
|
+
{
|
|
1876
|
+
let priv = gobj.priv;
|
|
1877
|
+
let $container = gobj_read_attr(gobj, "$container");
|
|
1878
|
+
|
|
1879
|
+
if(!$container) {
|
|
1880
|
+
return;
|
|
1881
|
+
}
|
|
1882
|
+
for(let $card of $container.querySelectorAll('.JSON_CARD_ANCHORED')) {
|
|
1883
|
+
$card.classList.remove('JSON_CARD_ANCHORED');
|
|
1884
|
+
}
|
|
1885
|
+
if(priv.anchor_state !== "on" || !priv.anchor_path) {
|
|
1886
|
+
return;
|
|
1887
|
+
}
|
|
1888
|
+
let $it = $container.querySelector(
|
|
1889
|
+
'.JSON_CARD[data-json-path="' + CSS.escape(priv.anchor_path) + '"]'
|
|
1890
|
+
);
|
|
1891
|
+
if($it) {
|
|
1892
|
+
$it.classList.add('JSON_CARD_ANCHORED');
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1823
1896
|
/************************************************************
|
|
1824
1897
|
* Centre on the anchor, one cycle after it was chosen.
|
|
1825
1898
|
************************************************************/
|
|
@@ -1827,6 +1900,7 @@ function ac_center_anchor(gobj, event, kw, src)
|
|
|
1827
1900
|
{
|
|
1828
1901
|
let priv = gobj.priv;
|
|
1829
1902
|
|
|
1903
|
+
paint_anchor_mark(gobj);
|
|
1830
1904
|
if(priv.anchor_state === "on" && priv.anchor_id) {
|
|
1831
1905
|
yui_graph_center_on(priv.graph, priv.anchor_id);
|
|
1832
1906
|
}
|
|
@@ -1854,6 +1928,8 @@ function ac_toggle_anchor(gobj, event, kw, src)
|
|
|
1854
1928
|
}
|
|
1855
1929
|
|
|
1856
1930
|
yui_graph_update_anchor(gobj_read_attr(gobj, "$container"), priv.anchor_state);
|
|
1931
|
+
paint_anchor_mark(gobj);
|
|
1932
|
+
set_picking_mode(gobj, priv.anchor_state === "arming");
|
|
1857
1933
|
return 0;
|
|
1858
1934
|
}
|
|
1859
1935
|
|
|
@@ -1945,6 +2021,7 @@ function ac_node_click(gobj, event, kw, src)
|
|
|
1945
2021
|
priv.anchor_path = (nodedata && nodedata.data)? nodedata.data.path: "";
|
|
1946
2022
|
priv.anchor_state = "on";
|
|
1947
2023
|
yui_graph_update_anchor(gobj_read_attr(gobj, "$container"), priv.anchor_state);
|
|
2024
|
+
set_picking_mode(gobj, false);
|
|
1948
2025
|
|
|
1949
2026
|
/*
|
|
1950
2027
|
* The camera move is POSTED, not made here.
|
package/src/lib_graph.css
CHANGED
|
@@ -256,6 +256,14 @@
|
|
|
256
256
|
* pressed button hands it back to Bulma's rule and the toggle appears
|
|
257
257
|
* to switch off under the pointer.
|
|
258
258
|
*/
|
|
259
|
+
/* Picking the node to anchor, in the gobj tree: the pointer says a
|
|
260
|
+
* click is expected, which is otherwise only announced by a button at
|
|
261
|
+
* the far end of a toolbar. */
|
|
262
|
+
.gobj-tree-container.GOBJ_TREE_PICKING,
|
|
263
|
+
.gobj-tree-container.GOBJ_TREE_PICKING * {
|
|
264
|
+
cursor: crosshair;
|
|
265
|
+
}
|
|
266
|
+
|
|
259
267
|
.button.pressed_state,
|
|
260
268
|
.button.pressed_state:hover {
|
|
261
269
|
background-color: var(--bulma-text, #2e333d);
|
package/src/yui_graph_camera.js
CHANGED
|
@@ -233,11 +233,35 @@ export function yui_graph_update_anchor($container, state)
|
|
|
233
233
|
* an error worth a log line per notch, they are all "there is
|
|
234
234
|
* nothing to centre right now".
|
|
235
235
|
************************************************************/
|
|
236
|
+
const __centring__ = new WeakMap();
|
|
237
|
+
|
|
236
238
|
export async function yui_graph_center_on(graph, node_id)
|
|
237
239
|
{
|
|
238
240
|
if(!graph || !node_id) {
|
|
239
241
|
return false;
|
|
240
242
|
}
|
|
243
|
+
|
|
244
|
+
/*
|
|
245
|
+
* ONE centring at a time, per graph.
|
|
246
|
+
*
|
|
247
|
+
* This runs on every zoom notch, and one run is several awaited
|
|
248
|
+
* camera moves. A wheel gesture is a BURST of notches, so without
|
|
249
|
+
* this the runs overlap: each one measures a position another one
|
|
250
|
+
* is in the middle of changing, and they walk the camera around
|
|
251
|
+
* instead of converging -- which reads as a graph that pans and
|
|
252
|
+
* never centres.
|
|
253
|
+
*
|
|
254
|
+
* A request that arrives mid-run is not dropped, it is remembered:
|
|
255
|
+
* the last one wins and runs once at the end, which is the only
|
|
256
|
+
* one whose answer is still true.
|
|
257
|
+
*/
|
|
258
|
+
let st = __centring__.get(graph);
|
|
259
|
+
if(st && st.running) {
|
|
260
|
+
st.again = node_id;
|
|
261
|
+
return true;
|
|
262
|
+
}
|
|
263
|
+
__centring__.set(graph, {running: true, again: null});
|
|
264
|
+
|
|
241
265
|
try {
|
|
242
266
|
if(typeof graph.getElementData === "function" && !graph.getElementData(node_id)) {
|
|
243
267
|
return false;
|
|
@@ -289,6 +313,12 @@ export async function yui_graph_center_on(graph, node_id)
|
|
|
289
313
|
return true;
|
|
290
314
|
} catch(e) {
|
|
291
315
|
return false; /* the element is gone, or the graph is between renders */
|
|
316
|
+
} finally {
|
|
317
|
+
let pending = __centring__.get(graph);
|
|
318
|
+
__centring__.set(graph, {running: false, again: null});
|
|
319
|
+
if(pending && pending.again) {
|
|
320
|
+
yui_graph_center_on(graph, pending.again);
|
|
321
|
+
}
|
|
292
322
|
}
|
|
293
323
|
}
|
|
294
324
|
|