@yuneta/gobj-ui 7.2.5 → 7.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/dist/gobj-ui.cjs.js +291 -40
- package/dist/gobj-ui.es.js +291 -40
- package/package.json +1 -1
- package/src/c_g6_nodes_tree.js +187 -44
- package/src/c_yui_treedb_graph.js +171 -7
package/README.md
CHANGED
|
@@ -582,6 +582,15 @@ Two details that are not decoration:
|
|
|
582
582
|
The find and the topic focus **share the highlight**: starting one clears the
|
|
583
583
|
other. Two amber sets at once would say nothing about either.
|
|
584
584
|
|
|
585
|
+
The highlight is painted **into the card's own html**, not with G6's `active`
|
|
586
|
+
element state. That state is an amber `stroke` + `halo`, both properties of a
|
|
587
|
+
node's KEY SHAPE — and every node here is an `html` node, whose key shape is a
|
|
588
|
+
DOM element. There was nothing for either property to paint on, so the amber
|
|
589
|
+
had never appeared, for the topic focus either. Only the cards whose state
|
|
590
|
+
changes are repainted, and a theme switch carries the highlight across (it
|
|
591
|
+
rebuilds every card, and rebuilding them without it would clear what is on
|
|
592
|
+
screen).
|
|
593
|
+
|
|
585
594
|
Wiring: the box sends `EV_FIND_NODES {text}` to the view, which forwards it to
|
|
586
595
|
`C_G6_NODES_TREE`; the graph answers `EV_FIND_RESULT {term, matches}`, which the
|
|
587
596
|
view declares like every other event its child publishes.
|
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -18594,6 +18594,8 @@ var PRIVATE_DATA$4 = {
|
|
|
18594
18594
|
topics: [],
|
|
18595
18595
|
records: {},
|
|
18596
18596
|
gobj_nodes_tree: null,
|
|
18597
|
+
find_timer: null,
|
|
18598
|
+
focus_topic: "",
|
|
18597
18599
|
gobj_treedb_tables: null,
|
|
18598
18600
|
hook_data_viewer: null,
|
|
18599
18601
|
json_gobj: null,
|
|
@@ -18668,6 +18670,11 @@ function mt_stop$4(gobj) {
|
|
|
18668
18670
|
* Framework Method: Destroy
|
|
18669
18671
|
***************************************************************/
|
|
18670
18672
|
function mt_destroy$4(gobj) {
|
|
18673
|
+
let priv = gobj.priv;
|
|
18674
|
+
if (priv.find_timer) {
|
|
18675
|
+
clearTimeout(priv.find_timer);
|
|
18676
|
+
priv.find_timer = null;
|
|
18677
|
+
}
|
|
18671
18678
|
destroy_ui$1(gobj);
|
|
18672
18679
|
}
|
|
18673
18680
|
/***************************
|
|
@@ -18687,26 +18694,37 @@ function build_ui$4(gobj) {
|
|
|
18687
18694
|
class: "C_YUI_TREEDB_GRAPH",
|
|
18688
18695
|
style: `height:100%; display:flex; flex-direction:column;`
|
|
18689
18696
|
},
|
|
18690
|
-
[
|
|
18691
|
-
|
|
18692
|
-
|
|
18693
|
-
|
|
18694
|
-
|
|
18695
|
-
|
|
18696
|
-
|
|
18697
|
-
class: `GRAPH_BODY is-flex-grow-1 ${padding}`,
|
|
18698
|
-
style: "height:100%; min-height:0; overflow:hidden;"
|
|
18699
|
-
},
|
|
18700
|
-
[[
|
|
18697
|
+
[
|
|
18698
|
+
[
|
|
18699
|
+
"div",
|
|
18700
|
+
{ class: "GRAPH_TOOLBAR_ROW is-flex-grow-0 is-flex is-align-items-center" },
|
|
18701
|
+
$back ? [$back, $toolbar] : [$toolbar]
|
|
18702
|
+
],
|
|
18703
|
+
[
|
|
18701
18704
|
"div",
|
|
18702
18705
|
{
|
|
18703
|
-
|
|
18704
|
-
|
|
18705
|
-
style: "height:100%; min-height:0;border: 1px solid var(--bulma-border-weak);border-radius:0.2rem;"
|
|
18706
|
+
class: "GRAPH_LEGEND is-hidden is-flex-grow-0",
|
|
18707
|
+
style: "display:flex; flex-wrap:wrap; align-items:center; gap:.4rem; padding:.35rem .5rem;"
|
|
18706
18708
|
},
|
|
18707
18709
|
[]
|
|
18708
|
-
]
|
|
18709
|
-
|
|
18710
|
+
],
|
|
18711
|
+
[
|
|
18712
|
+
"div",
|
|
18713
|
+
{
|
|
18714
|
+
class: `GRAPH_BODY is-flex-grow-1 ${padding}`,
|
|
18715
|
+
style: "height:100%; min-height:0; overflow:hidden;"
|
|
18716
|
+
},
|
|
18717
|
+
[[
|
|
18718
|
+
"div",
|
|
18719
|
+
{
|
|
18720
|
+
id: priv.canvas_id,
|
|
18721
|
+
class: `GRAPH_CANVAS graph-container`,
|
|
18722
|
+
style: "height:100%; min-height:0;border: 1px solid var(--bulma-border-weak);border-radius:0.2rem;"
|
|
18723
|
+
},
|
|
18724
|
+
[]
|
|
18725
|
+
]]
|
|
18726
|
+
]
|
|
18727
|
+
]
|
|
18710
18728
|
]);
|
|
18711
18729
|
(0, _yuneta_gobj_js.gobj_write_attr)(gobj, "$container", $container);
|
|
18712
18730
|
(0, _yuneta_gobj_js.refresh_language)($container, i18next.t);
|
|
@@ -18774,7 +18792,7 @@ function destroy_ui$1(gobj) {
|
|
|
18774
18792
|
*
|
|
18775
18793
|
************************************************************/
|
|
18776
18794
|
function make_toolbar(gobj) {
|
|
18777
|
-
gobj.priv;
|
|
18795
|
+
let priv = gobj.priv;
|
|
18778
18796
|
let modes = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "operation_modes");
|
|
18779
18797
|
if ((0, _yuneta_gobj_js.gobj_read_bool_attr)(gobj, "readonly")) modes = modes.filter((mode) => mode !== "edition");
|
|
18780
18798
|
let left_items = [
|
|
@@ -18839,6 +18857,29 @@ function make_toolbar(gobj) {
|
|
|
18839
18857
|
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_REFRESH_TREEDB", { evt }, gobj);
|
|
18840
18858
|
} }
|
|
18841
18859
|
],
|
|
18860
|
+
[
|
|
18861
|
+
"button",
|
|
18862
|
+
{
|
|
18863
|
+
class: "GRAPH_LEGEND_BTN button ml-2",
|
|
18864
|
+
title: (0, i18next.t)("legend"),
|
|
18865
|
+
"aria-label": (0, i18next.t)("legend"),
|
|
18866
|
+
"data-i18n-title": "legend",
|
|
18867
|
+
"data-i18n-aria-label": "legend"
|
|
18868
|
+
},
|
|
18869
|
+
[["i", { class: "yi-square" }], [
|
|
18870
|
+
"span",
|
|
18871
|
+
{
|
|
18872
|
+
class: "is-hidden-mobile",
|
|
18873
|
+
style: "padding-left:5px;",
|
|
18874
|
+
i18n: "legend"
|
|
18875
|
+
},
|
|
18876
|
+
"legend"
|
|
18877
|
+
]],
|
|
18878
|
+
{ click: (evt) => {
|
|
18879
|
+
evt.stopPropagation();
|
|
18880
|
+
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_TOGGLE_LEGEND", {}, gobj);
|
|
18881
|
+
} }
|
|
18882
|
+
],
|
|
18842
18883
|
[
|
|
18843
18884
|
"button",
|
|
18844
18885
|
{
|
|
@@ -18883,7 +18924,12 @@ function make_toolbar(gobj) {
|
|
|
18883
18924
|
]],
|
|
18884
18925
|
{ input: (evt) => {
|
|
18885
18926
|
evt.stopPropagation();
|
|
18886
|
-
|
|
18927
|
+
let text = evt.target.value.trim();
|
|
18928
|
+
if (priv.find_timer) clearTimeout(priv.find_timer);
|
|
18929
|
+
priv.find_timer = setTimeout(function() {
|
|
18930
|
+
priv.find_timer = null;
|
|
18931
|
+
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_FIND_NODES", { text }, gobj);
|
|
18932
|
+
}, 250);
|
|
18887
18933
|
} }
|
|
18888
18934
|
], [
|
|
18889
18935
|
"div",
|
|
@@ -19843,6 +19889,86 @@ function ac_set_operation_mode$1(gobj, event, kw, src) {
|
|
|
19843
19889
|
* until its data is loaded).
|
|
19844
19890
|
************************************************************/
|
|
19845
19891
|
/************************************************************
|
|
19892
|
+
* Fill the legend strip with one entry per topic: a swatch in the
|
|
19893
|
+
* topic's colour and its name. The colours belong to the graph child —
|
|
19894
|
+
* it assigns them from its palette when the schema arrives — so they
|
|
19895
|
+
* are read from there and never guessed twice.
|
|
19896
|
+
*
|
|
19897
|
+
* An entry is a BUTTON: clicking it focuses that topic, clicking the
|
|
19898
|
+
* focused one clears the focus. The focus travels the same way a topic
|
|
19899
|
+
* card's graph icon travels — as EV_TOPIC_SELECTED, which the host turns
|
|
19900
|
+
* into the URL, so what you are looking at stays linkable.
|
|
19901
|
+
************************************************************/
|
|
19902
|
+
function refresh_legend(gobj) {
|
|
19903
|
+
let priv = gobj.priv;
|
|
19904
|
+
let $container = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container");
|
|
19905
|
+
if (!$container) return;
|
|
19906
|
+
let $legend = $container.querySelector(".GRAPH_LEGEND");
|
|
19907
|
+
if (!$legend) return;
|
|
19908
|
+
let descs = priv.gobj_nodes_tree ? (0, _yuneta_gobj_js.gobj_read_attr)(priv.gobj_nodes_tree, "descs") : null;
|
|
19909
|
+
$legend.textContent = "";
|
|
19910
|
+
if (!descs) return;
|
|
19911
|
+
for (const [topic_name, desc] of Object.entries(descs)) {
|
|
19912
|
+
if (topic_name.substring(0, 2) === "__") continue;
|
|
19913
|
+
if (!desc || !desc.color) continue;
|
|
19914
|
+
let focused = priv.focus_topic === topic_name;
|
|
19915
|
+
let $item = (0, _yuneta_gobj_js.createElement2)([
|
|
19916
|
+
"button",
|
|
19917
|
+
{
|
|
19918
|
+
class: "GRAPH_LEGEND_ITEM button is-small" + (focused ? " is-primary" : ""),
|
|
19919
|
+
title: topic_name,
|
|
19920
|
+
"aria-label": topic_name,
|
|
19921
|
+
"aria-pressed": focused ? "true" : "false"
|
|
19922
|
+
},
|
|
19923
|
+
[["span", {
|
|
19924
|
+
class: "GRAPH_LEGEND_SWATCH",
|
|
19925
|
+
style: `display:inline-block; width:.8rem; height:.8rem; border-radius:3px; margin-right:.4rem; background:${desc.color}; border:1px solid rgba(0,0,0,.25);`
|
|
19926
|
+
}], [
|
|
19927
|
+
"span",
|
|
19928
|
+
{},
|
|
19929
|
+
topic_name
|
|
19930
|
+
]],
|
|
19931
|
+
{ click: (evt) => {
|
|
19932
|
+
evt.stopPropagation();
|
|
19933
|
+
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_LEGEND_TOPIC", { topic: topic_name }, gobj);
|
|
19934
|
+
} }
|
|
19935
|
+
]);
|
|
19936
|
+
$legend.appendChild($item);
|
|
19937
|
+
}
|
|
19938
|
+
}
|
|
19939
|
+
/************************************************************
|
|
19940
|
+
*
|
|
19941
|
+
************************************************************/
|
|
19942
|
+
function ac_toggle_legend(gobj, event, kw, src) {
|
|
19943
|
+
let $container = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container");
|
|
19944
|
+
if (!$container) return 0;
|
|
19945
|
+
let $legend = $container.querySelector(".GRAPH_LEGEND");
|
|
19946
|
+
if (!$legend) {
|
|
19947
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: no legend strip to toggle`);
|
|
19948
|
+
return -1;
|
|
19949
|
+
}
|
|
19950
|
+
if ($legend.classList.contains("is-hidden")) {
|
|
19951
|
+
refresh_legend(gobj);
|
|
19952
|
+
$legend.classList.remove("is-hidden");
|
|
19953
|
+
} else $legend.classList.add("is-hidden");
|
|
19954
|
+
return 0;
|
|
19955
|
+
}
|
|
19956
|
+
/************************************************************
|
|
19957
|
+
* A legend entry was clicked: focus that topic, or clear the focus if
|
|
19958
|
+
* it was already the focused one. Published UP rather than applied
|
|
19959
|
+
* here, so the URL follows — the host owns the route.
|
|
19960
|
+
************************************************************/
|
|
19961
|
+
function ac_legend_topic(gobj, event, kw, src) {
|
|
19962
|
+
let priv = gobj.priv;
|
|
19963
|
+
let topic = kw && kw.topic || "";
|
|
19964
|
+
if (!topic) {
|
|
19965
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: legend click with no topic`);
|
|
19966
|
+
return -1;
|
|
19967
|
+
}
|
|
19968
|
+
(0, _yuneta_gobj_js.gobj_publish_event)(gobj, "EV_TOPIC_SELECTED", { topic: priv.focus_topic === topic ? "" : topic });
|
|
19969
|
+
return 0;
|
|
19970
|
+
}
|
|
19971
|
+
/************************************************************
|
|
19846
19972
|
* Forward the find down to the graph child.
|
|
19847
19973
|
************************************************************/
|
|
19848
19974
|
function ac_find_nodes$1(gobj, event, kw, src) {
|
|
@@ -19871,7 +19997,11 @@ function ac_find_result(gobj, event, kw, src) {
|
|
|
19871
19997
|
}
|
|
19872
19998
|
function ac_set_focus_topic(gobj, event, kw, src) {
|
|
19873
19999
|
let priv = gobj.priv;
|
|
19874
|
-
|
|
20000
|
+
priv.focus_topic = kw && kw.topic || "";
|
|
20001
|
+
if (priv.gobj_nodes_tree) (0, _yuneta_gobj_js.gobj_send_event)(priv.gobj_nodes_tree, "EV_FOCUS_TOPIC", { topic: priv.focus_topic }, gobj);
|
|
20002
|
+
let $container = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container");
|
|
20003
|
+
let $legend = $container ? $container.querySelector(".GRAPH_LEGEND") : null;
|
|
20004
|
+
if ($legend && !$legend.classList.contains("is-hidden")) refresh_legend(gobj);
|
|
19875
20005
|
return 0;
|
|
19876
20006
|
}
|
|
19877
20007
|
/************************************************************
|
|
@@ -20039,6 +20169,16 @@ function create_gclass$4(gclass_name) {
|
|
|
20039
20169
|
ac_find_nodes$1,
|
|
20040
20170
|
null
|
|
20041
20171
|
],
|
|
20172
|
+
[
|
|
20173
|
+
"EV_TOGGLE_LEGEND",
|
|
20174
|
+
ac_toggle_legend,
|
|
20175
|
+
null
|
|
20176
|
+
],
|
|
20177
|
+
[
|
|
20178
|
+
"EV_LEGEND_TOPIC",
|
|
20179
|
+
ac_legend_topic,
|
|
20180
|
+
null
|
|
20181
|
+
],
|
|
20042
20182
|
[
|
|
20043
20183
|
"EV_FIND_RESULT",
|
|
20044
20184
|
ac_find_result,
|
|
@@ -20087,6 +20227,9 @@ function create_gclass$4(gclass_name) {
|
|
|
20087
20227
|
["EV_SET_FOCUS_TOPIC", 0],
|
|
20088
20228
|
["EV_FIND_NODES", 0],
|
|
20089
20229
|
["EV_FIND_RESULT", 0],
|
|
20230
|
+
["EV_TOGGLE_LEGEND", 0],
|
|
20231
|
+
["EV_LEGEND_TOPIC", 0],
|
|
20232
|
+
["EV_TOPIC_SELECTED", _yuneta_gobj_js.event_flag_t.EVF_OUTPUT_EVENT | _yuneta_gobj_js.event_flag_t.EVF_NO_WARN_SUBS],
|
|
20090
20233
|
["EV_OPERATION_MODE_CHANGED", _yuneta_gobj_js.event_flag_t.EVF_OUTPUT_EVENT | _yuneta_gobj_js.event_flag_t.EVF_NO_WARN_SUBS],
|
|
20091
20234
|
["EV_RECORD_WRITTEN", _yuneta_gobj_js.event_flag_t.EVF_OUTPUT_EVENT | _yuneta_gobj_js.event_flag_t.EVF_NO_WARN_SUBS],
|
|
20092
20235
|
["EV_SHOW", 0],
|
|
@@ -52642,6 +52785,8 @@ ensure_drag_canvas_patch();
|
|
|
52642
52785
|
* Constants
|
|
52643
52786
|
***************************************************************/
|
|
52644
52787
|
var GCLASS_NAME$1 = "C_G6_NODES_TREE";
|
|
52788
|
+
var HIGHLIGHT_COLOR = "#f0a020";
|
|
52789
|
+
var HIGHLIGHT_HALO = "rgba(240,160,32,0.35)";
|
|
52645
52790
|
/***************************************************************
|
|
52646
52791
|
* Internal layout and operation mode definitions
|
|
52647
52792
|
***************************************************************/
|
|
@@ -52691,6 +52836,7 @@ var attrs_table$1 = [
|
|
|
52691
52836
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_BOOLEAN, "with_gridline", 0, true, "Use gridline plugin"),
|
|
52692
52837
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_BOOLEAN, "with_fullscreen", 0, true, "Use fullscreen plugin"),
|
|
52693
52838
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_BOOLEAN, "with_toolbar", 0, true, "Use toolbar plugin"),
|
|
52839
|
+
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_INTEGER, "minimap_min_nodes", 0, 30, "Show the minimap from this many nodes on (0 = never). A minimap of a graph that fits on screen is decoration; one of two hundred cards is the only way to know where you are"),
|
|
52694
52840
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "toolbar_position", 0, "right-top", "Toolbar position: top-left, top-right, bottom-left, bottom-right, left-top, right-top"),
|
|
52695
52841
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_LIST, "layout_names", _yuneta_gobj_js.sdata_flag_t.SDF_RD, JSON.stringify(Object.keys(_layouts)), "Available layout names (read-only, for parent to query)"),
|
|
52696
52842
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "hook_port_position", 0, "bottom", "Hook port position"),
|
|
@@ -53918,10 +54064,12 @@ function graph_focus_topic(gobj, topic) {
|
|
|
53918
54064
|
if (ids.length === 0) (0, _yuneta_gobj_js.log_warning)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: focus topic '${topic}' has no nodes`);
|
|
53919
54065
|
for (let id of ids) states[id] = ["active"];
|
|
53920
54066
|
}
|
|
54067
|
+
let prev_ids = priv._focus_ids || [];
|
|
53921
54068
|
priv._focus_ids = ids;
|
|
53922
54069
|
priv._focus_topic = topic || null;
|
|
53923
54070
|
try {
|
|
53924
54071
|
if (typeof graph.setElementState === "function") graph.setElementState(states);
|
|
54072
|
+
apply_node_highlight(gobj, prev_ids, ids);
|
|
53925
54073
|
if (ids.length && typeof graph.focusElement === "function") graph.focusElement(ids);
|
|
53926
54074
|
} catch (e) {
|
|
53927
54075
|
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: focus topic apply failed: ${e}`);
|
|
@@ -53978,10 +54126,12 @@ function graph_find_nodes(gobj, term) {
|
|
|
53978
54126
|
}
|
|
53979
54127
|
for (let id of ids) states[id] = ["active"];
|
|
53980
54128
|
}
|
|
54129
|
+
let prev_ids = priv._focus_ids || [];
|
|
53981
54130
|
priv._focus_ids = ids;
|
|
53982
54131
|
priv._focus_topic = null;
|
|
53983
54132
|
try {
|
|
53984
54133
|
if (typeof graph.setElementState === "function") graph.setElementState(states);
|
|
54134
|
+
apply_node_highlight(gobj, prev_ids, ids);
|
|
53985
54135
|
if (ids.length && typeof graph.focusElement === "function") graph.focusElement(ids);
|
|
53986
54136
|
} catch (e) {
|
|
53987
54137
|
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: find apply failed: ${e}`);
|
|
@@ -55525,27 +55675,121 @@ function show_node_detail_popover(gobj, node_id) {
|
|
|
55525
55675
|
* not re-themed by setTheme()) are regenerated; structural
|
|
55526
55676
|
* junction diamonds get their neutral fill/stroke re-themed.
|
|
55527
55677
|
************************************************************/
|
|
55528
|
-
|
|
55678
|
+
/************************************************************
|
|
55679
|
+
* Show or hide the minimap, deciding by the SIZE of the graph.
|
|
55680
|
+
*
|
|
55681
|
+
* A minimap of a graph that already fits on screen is decoration; one
|
|
55682
|
+
* of two hundred cards is the only way to know where you are. So it is
|
|
55683
|
+
* not a preference the reader has to find and set — it appears when
|
|
55684
|
+
* there is something to be lost in, from `minimap_min_nodes` on.
|
|
55685
|
+
*
|
|
55686
|
+
* Its shapes are drawn by hand. G6's minimap clones each element's key
|
|
55687
|
+
* shape into its own canvas, and every node here is an `html` node
|
|
55688
|
+
* whose key shape is a DOM element — the same reason the `active`
|
|
55689
|
+
* state never painted (see HIGHLIGHT_COLOR). A block in the topic's
|
|
55690
|
+
* colour is also what a minimap of cards SHOULD show: at that scale a
|
|
55691
|
+
* card is a rectangle anyway.
|
|
55692
|
+
************************************************************/
|
|
55693
|
+
function refresh_minimap(gobj) {
|
|
55529
55694
|
let graph = gobj.priv.graph;
|
|
55530
55695
|
if (!graph) return;
|
|
55696
|
+
let threshold = (0, _yuneta_gobj_js.gobj_read_integer_attr)(gobj, "minimap_min_nodes");
|
|
55697
|
+
let n = 0;
|
|
55698
|
+
try {
|
|
55699
|
+
let data = graph.getData() || {};
|
|
55700
|
+
n = (0, _yuneta_gobj_js.is_array)(data.nodes) ? data.nodes.length : 0;
|
|
55701
|
+
} catch (e) {
|
|
55702
|
+
n = 0;
|
|
55703
|
+
}
|
|
55704
|
+
if (!threshold || n < threshold) {
|
|
55705
|
+
graph_remove_plugin(gobj, "minimap");
|
|
55706
|
+
return;
|
|
55707
|
+
}
|
|
55708
|
+
if (graph_get_plugin(gobj, "minimap")) return;
|
|
55709
|
+
graph_add_plugin(gobj, "minimap", {
|
|
55710
|
+
size: [200, 140],
|
|
55711
|
+
position: "bottom-left",
|
|
55712
|
+
shape: (id, element_type, element) => {
|
|
55713
|
+
if (element_type !== "node") return element;
|
|
55714
|
+
try {
|
|
55715
|
+
let nd = graph.getNodeData(id);
|
|
55716
|
+
let size = nd && nd.style && nd.style.size || [120, 60];
|
|
55717
|
+
let color = nd && nd.data && nd.data.desc && nd.data.desc.color || "#94a3b8";
|
|
55718
|
+
return new Rect({ style: {
|
|
55719
|
+
x: -size[0] / 2,
|
|
55720
|
+
y: -size[1] / 2,
|
|
55721
|
+
width: size[0],
|
|
55722
|
+
height: size[1],
|
|
55723
|
+
fill: color,
|
|
55724
|
+
radius: 4
|
|
55725
|
+
} });
|
|
55726
|
+
} catch (e) {
|
|
55727
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: minimap shape failed: ${e}`);
|
|
55728
|
+
return element;
|
|
55729
|
+
}
|
|
55730
|
+
}
|
|
55731
|
+
});
|
|
55732
|
+
}
|
|
55733
|
+
/************************************************************
|
|
55734
|
+
* The innerHTML of ONE node, in the given theme and highlight state.
|
|
55735
|
+
* The three treedb tiers (hierarchical / extended / child) each have
|
|
55736
|
+
* their own card, and both the theme refresh and the highlight need the
|
|
55737
|
+
* same three-way choice — it lived inline in the theme refresh and is
|
|
55738
|
+
* shared now. Returns null for a node that carries no desc.
|
|
55739
|
+
************************************************************/
|
|
55740
|
+
function node_innerHTML_of(nd, theme, highlight) {
|
|
55741
|
+
if (!nd || !nd.data || !nd.data.desc) return null;
|
|
55742
|
+
let desc = nd.data.desc;
|
|
55743
|
+
let record = nd.data.record || {};
|
|
55744
|
+
let label = node_label(desc, record);
|
|
55745
|
+
switch (desc.node_treedb_type) {
|
|
55746
|
+
case "child": return build_chip_innerHTML(desc.color, theme, record.icon, label, record.id, highlight);
|
|
55747
|
+
case "extended": return build_node_innerHTML(desc.color, theme, record.icon, label, desc.topic_name, true, record.id, highlight);
|
|
55748
|
+
case "hierarchical": return build_node_innerHTML(desc.color, theme, record.icon, label, desc.topic_name, false, record.id, highlight);
|
|
55749
|
+
}
|
|
55750
|
+
return null;
|
|
55751
|
+
}
|
|
55752
|
+
/************************************************************
|
|
55753
|
+
* Repaint the cards whose highlight state CHANGES: the ones that had it
|
|
55754
|
+
* and lose it, plus the ones that gain it. Only those — a treedb graph
|
|
55755
|
+
* is redrawn per keystroke of the find box otherwise.
|
|
55756
|
+
************************************************************/
|
|
55757
|
+
function apply_node_highlight(gobj, prev_ids, next_ids) {
|
|
55758
|
+
let priv = gobj.priv;
|
|
55759
|
+
let graph = priv.graph;
|
|
55760
|
+
if (!graph) return;
|
|
55761
|
+
let next = new Set(next_ids || []);
|
|
55762
|
+
let touched = /* @__PURE__ */ new Set([...prev_ids || [], ...next]);
|
|
55763
|
+
if (touched.size === 0) return;
|
|
55764
|
+
let updates = [];
|
|
55765
|
+
for (let id of touched) {
|
|
55766
|
+
let html = node_innerHTML_of(graph.getNodeData(id), priv.theme, next.has(id));
|
|
55767
|
+
if (html !== null) updates.push({
|
|
55768
|
+
id,
|
|
55769
|
+
style: { innerHTML: html }
|
|
55770
|
+
});
|
|
55771
|
+
}
|
|
55772
|
+
if (!updates.length) return;
|
|
55773
|
+
try {
|
|
55774
|
+
graph.updateNodeData(updates);
|
|
55775
|
+
graph.draw();
|
|
55776
|
+
} catch (e) {
|
|
55777
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: cannot repaint the highlight: ${e}`);
|
|
55778
|
+
}
|
|
55779
|
+
}
|
|
55780
|
+
function refresh_html_nodes_theme(gobj, theme) {
|
|
55781
|
+
let priv = gobj.priv;
|
|
55782
|
+
let graph = priv.graph;
|
|
55783
|
+
if (!graph) return;
|
|
55531
55784
|
let nodes = graph.getData().nodes || [];
|
|
55785
|
+
let highlighted = new Set(priv._focus_ids || []);
|
|
55532
55786
|
let updates = [];
|
|
55533
55787
|
for (let i = 0; i < nodes.length; i++) {
|
|
55534
|
-
let
|
|
55535
|
-
|
|
55536
|
-
|
|
55537
|
-
|
|
55538
|
-
|
|
55539
|
-
id: nodes[i].id,
|
|
55540
|
-
style: { innerHTML: build_node_innerHTML(nd.data.desc.color, theme, record.icon, node_label(nd.data.desc, record), nd.data.desc.topic_name, false, record.id) }
|
|
55541
|
-
});
|
|
55542
|
-
else if (tt === "child") updates.push({
|
|
55543
|
-
id: nodes[i].id,
|
|
55544
|
-
style: { innerHTML: build_chip_innerHTML(nd.data.desc.color, theme, record.icon, node_label(nd.data.desc, record), record.id) }
|
|
55545
|
-
});
|
|
55546
|
-
else if (tt === "extended") updates.push({
|
|
55547
|
-
id: nodes[i].id,
|
|
55548
|
-
style: { innerHTML: build_node_innerHTML(nd.data.desc.color, theme, record.icon, node_label(nd.data.desc, record), nd.data.desc.topic_name, true, record.id) }
|
|
55788
|
+
let id = nodes[i].id;
|
|
55789
|
+
let html = node_innerHTML_of(graph.getNodeData(id), theme, highlighted.has(id));
|
|
55790
|
+
if (html !== null) updates.push({
|
|
55791
|
+
id,
|
|
55792
|
+
style: { innerHTML: html }
|
|
55549
55793
|
});
|
|
55550
55794
|
}
|
|
55551
55795
|
if (updates.length > 0) graph.updateNodeData(updates);
|
|
@@ -55577,12 +55821,13 @@ function refresh_default_edges_theme(gobj, theme) {
|
|
|
55577
55821
|
* but lighter (1px border, no shadow, single line). The name is
|
|
55578
55822
|
* always legible (ellipsis + native title tooltip on overflow).
|
|
55579
55823
|
************************************************************/
|
|
55580
|
-
function build_chip_innerHTML(color, theme, icon, label, key) {
|
|
55824
|
+
function build_chip_innerHTML(color, theme, icon, label, key, highlight) {
|
|
55581
55825
|
let title = key || label;
|
|
55582
55826
|
let dark = theme === "dark";
|
|
55583
55827
|
let bg = dark ? `color-mix(in srgb, ${color} 30%, #2c3542)` : `color-mix(in srgb, ${color} 10%, ${dark ? "#1b2230" : "#ffffff"})`;
|
|
55584
55828
|
let border = dark ? `color-mix(in srgb, ${color} 85%, #ffffff)` : color;
|
|
55585
55829
|
let text_color = dark ? "#e8eaed" : "#0f172a";
|
|
55830
|
+
if (highlight) border = HIGHLIGHT_COLOR;
|
|
55586
55831
|
let icon_html = "";
|
|
55587
55832
|
if (icon) icon_html = `<img src="${(0, _yuneta_gobj_js.safeSrc)(icon)}" alt="" style="
|
|
55588
55833
|
width: 16px; height: 16px; object-fit: contain;
|
|
@@ -55594,7 +55839,8 @@ function build_chip_innerHTML(color, theme, icon, label, key) {
|
|
|
55594
55839
|
width: 100%;
|
|
55595
55840
|
height: 100%;
|
|
55596
55841
|
background: ${bg};
|
|
55597
|
-
border: 1px solid ${border};
|
|
55842
|
+
border: ${highlight ? "3px" : "1px"} solid ${border};
|
|
55843
|
+
${highlight ? `box-shadow: 0 0 0 4px ${HIGHLIGHT_HALO};` : ""}
|
|
55598
55844
|
border-radius: 8px;
|
|
55599
55845
|
color: ${text_color};
|
|
55600
55846
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
|
@@ -55620,7 +55866,7 @@ function build_chip_innerHTML(color, theme, icon, label, key) {
|
|
|
55620
55866
|
* colour is kept (per-topic differentiation) but softened via
|
|
55621
55867
|
* color-mix instead of a harsh saturated fill. Theme-aware.
|
|
55622
55868
|
************************************************************/
|
|
55623
|
-
function build_node_innerHTML(color, theme, icon, label, topic_name, structural, key) {
|
|
55869
|
+
function build_node_innerHTML(color, theme, icon, label, topic_name, structural, key, highlight) {
|
|
55624
55870
|
let title = key || label;
|
|
55625
55871
|
let dark = theme === "dark";
|
|
55626
55872
|
let surface = dark ? "#1b2230" : "#ffffff";
|
|
@@ -55634,6 +55880,10 @@ function build_node_innerHTML(color, theme, icon, label, topic_name, structural,
|
|
|
55634
55880
|
border = dark ? `color-mix(in srgb, ${color} 85%, #ffffff)` : color;
|
|
55635
55881
|
border_style = "solid";
|
|
55636
55882
|
}
|
|
55883
|
+
if (highlight) {
|
|
55884
|
+
border = HIGHLIGHT_COLOR;
|
|
55885
|
+
border_style = "solid";
|
|
55886
|
+
}
|
|
55637
55887
|
let title_color = dark ? "#e8eaed" : "#0f172a";
|
|
55638
55888
|
let sub_color = dark ? "#9aa4b2" : "#64748b";
|
|
55639
55889
|
let shadow = dark ? "0 1px 3px rgba(0,0,0,0.45), 0 1px 2px rgba(0,0,0,0.30)" : "0 1px 3px rgba(15,23,42,0.12), 0 1px 2px rgba(15,23,42,0.06)";
|
|
@@ -55656,9 +55906,9 @@ function build_node_innerHTML(color, theme, icon, label, topic_name, structural,
|
|
|
55656
55906
|
width: 100%;
|
|
55657
55907
|
height: 100%;
|
|
55658
55908
|
background: ${bg};
|
|
55659
|
-
border: 1.5px ${border_style} ${border};
|
|
55909
|
+
border: ${highlight ? "3px" : "1.5px"} ${border_style} ${border};
|
|
55660
55910
|
border-radius: 10px;
|
|
55661
|
-
box-shadow: ${shadow};
|
|
55911
|
+
box-shadow: ${highlight ? `0 0 0 4px ${HIGHLIGHT_HALO}, ${shadow}` : shadow};
|
|
55662
55912
|
color: ${title_color};
|
|
55663
55913
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
|
55664
55914
|
display: flex;
|
|
@@ -56277,6 +56527,7 @@ function ac_load_data(gobj, event, kw, src) {
|
|
|
56277
56527
|
graph_layout(gobj).then(() => {
|
|
56278
56528
|
if (priv.edit_mode) graph_add_plugin(gobj, "history");
|
|
56279
56529
|
else graph_remove_plugin(gobj, "history");
|
|
56530
|
+
refresh_minimap(gobj);
|
|
56280
56531
|
if (priv._pending_focus_topic !== null) {
|
|
56281
56532
|
let ft = priv._pending_focus_topic;
|
|
56282
56533
|
priv._pending_focus_topic = null;
|