@yuneta/gobj-ui 7.23.136 → 7.23.137
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 +91 -60
- package/dist/gobj-ui.es.js +91 -60
- package/package.json +1 -1
- package/src/c_g6_nodes_tree.js +69 -1
- package/src/c_yui_treedb_graph.js +31 -15
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -57017,12 +57017,41 @@ var MIN_READABLE_ZOOM = .5;
|
|
|
57017
57017
|
* G6 reports them.
|
|
57018
57018
|
************************************************************/
|
|
57019
57019
|
var CAMERA_SETTLE_MS = 700;
|
|
57020
|
+
function node_nearest_view_centre(gobj) {
|
|
57021
|
+
let graph = gobj.priv.graph;
|
|
57022
|
+
let size;
|
|
57023
|
+
try {
|
|
57024
|
+
size = graph.getSize();
|
|
57025
|
+
} catch (e) {
|
|
57026
|
+
return "";
|
|
57027
|
+
}
|
|
57028
|
+
if (!(0, _yuneta_gobj_js.is_array)(size) || !(size[0] > 0) || !(size[1] > 0)) return "";
|
|
57029
|
+
let [w, h] = size;
|
|
57030
|
+
let best = "";
|
|
57031
|
+
let best_d = Infinity;
|
|
57032
|
+
for (let nd of graph.getNodeData() || []) {
|
|
57033
|
+
let vp = yui_graph_viewport_of(graph, nd.id);
|
|
57034
|
+
if (!vp || !(0, _yuneta_gobj_js.is_number)(vp[0]) || !(0, _yuneta_gobj_js.is_number)(vp[1])) continue;
|
|
57035
|
+
if (vp[0] < 0 || vp[1] < 0 || vp[0] > w || vp[1] > h) continue;
|
|
57036
|
+
let d = (vp[0] - w / 2) ** 2 + (vp[1] - h / 2) ** 2;
|
|
57037
|
+
if (d < best_d) {
|
|
57038
|
+
best_d = d;
|
|
57039
|
+
best = nd.id;
|
|
57040
|
+
}
|
|
57041
|
+
}
|
|
57042
|
+
return best;
|
|
57043
|
+
}
|
|
57044
|
+
function camera_anchor_node(gobj) {
|
|
57045
|
+
let priv = gobj.priv;
|
|
57046
|
+
if (priv.anchor_state === "on" && priv.anchor_id) return priv.anchor_id;
|
|
57047
|
+
return node_nearest_view_centre(gobj) || fold_keep_node(gobj);
|
|
57048
|
+
}
|
|
57020
57049
|
function read_camera(gobj) {
|
|
57021
57050
|
let graph = gobj.priv.graph;
|
|
57022
57051
|
if (!graph || typeof graph.getZoom !== "function") return null;
|
|
57023
57052
|
try {
|
|
57024
57053
|
let z = graph.getZoom();
|
|
57025
|
-
let node =
|
|
57054
|
+
let node = camera_anchor_node(gobj);
|
|
57026
57055
|
let vp = node ? yui_graph_viewport_of(graph, node) : null;
|
|
57027
57056
|
if (!(0, _yuneta_gobj_js.is_number)(z) || !node || !vp || !(0, _yuneta_gobj_js.is_number)(vp[0]) || !(0, _yuneta_gobj_js.is_number)(vp[1])) return null;
|
|
57028
57057
|
return {
|
|
@@ -57041,6 +57070,8 @@ async function restore_camera(gobj) {
|
|
|
57041
57070
|
let cam = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "camera");
|
|
57042
57071
|
if (!graph || (0, _yuneta_gobj_js.empty_json)(cam) || !(0, _yuneta_gobj_js.is_number)(cam.zoom) || !cam.node || !(0, _yuneta_gobj_js.is_number)(cam.x) || !(0, _yuneta_gobj_js.is_number)(cam.y)) return false;
|
|
57043
57072
|
if (!yui_graph_viewport_of(graph, cam.node)) return false;
|
|
57073
|
+
let size = graph.getSize() || [0, 0];
|
|
57074
|
+
if (cam.x < 0 || cam.y < 0 || cam.x > size[0] || cam.y > size[1]) return false;
|
|
57044
57075
|
priv._camera_restoring = true;
|
|
57045
57076
|
try {
|
|
57046
57077
|
await graph.zoomTo(cam.zoom);
|
|
@@ -61262,6 +61293,7 @@ async function reconcile_fold_apply(gobj, opts, visible) {
|
|
|
61262
61293
|
if (opts.fit) await graph_fit_readable(gobj);
|
|
61263
61294
|
else if (opts.keep && opts.keep_vp) await yui_graph_place_at(graph, opts.keep, opts.keep_vp);
|
|
61264
61295
|
}
|
|
61296
|
+
if ((graph.getNodeData() || []).length > 0 && !node_nearest_view_centre(gobj)) await graph_fit_readable(gobj);
|
|
61265
61297
|
priv._camera_placed = true;
|
|
61266
61298
|
update_resize_handles_position(gobj);
|
|
61267
61299
|
update_port_resize_handles_position(gobj);
|
|
@@ -63130,56 +63162,54 @@ function make_toolbar(gobj) {
|
|
|
63130
63162
|
evt.stopPropagation();
|
|
63131
63163
|
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_SET_OPERATION_MODE", { operation_mode: evt.target.value }, gobj);
|
|
63132
63164
|
} }
|
|
63133
|
-
]
|
|
63134
|
-
|
|
63135
|
-
|
|
63165
|
+
]
|
|
63166
|
+
];
|
|
63167
|
+
let center_items = [...yui_graph_fold_items(gobj, (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "wide")), ...node_shape_items(gobj, (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "wide"))];
|
|
63168
|
+
let backend_items = [[
|
|
63169
|
+
"button",
|
|
63170
|
+
{
|
|
63171
|
+
class: "GRAPH_REFRESH button",
|
|
63172
|
+
title: (0, i18next.t)("refresh"),
|
|
63173
|
+
"data-i18n-title": "refresh",
|
|
63174
|
+
"aria-label": (0, i18next.t)("refresh"),
|
|
63175
|
+
"data-i18n-aria-label": "refresh"
|
|
63176
|
+
},
|
|
63177
|
+
[yui_toolbar_icon("yi-arrows-rotate"), [
|
|
63178
|
+
"span",
|
|
63136
63179
|
{
|
|
63137
|
-
class: "
|
|
63138
|
-
|
|
63139
|
-
|
|
63140
|
-
"aria-label": (0, i18next.t)("refresh"),
|
|
63141
|
-
"data-i18n-aria-label": "refresh"
|
|
63180
|
+
class: "is-hidden-mobile",
|
|
63181
|
+
style: "padding-left:5px;",
|
|
63182
|
+
i18n: "refresh"
|
|
63142
63183
|
},
|
|
63143
|
-
|
|
63144
|
-
|
|
63145
|
-
|
|
63146
|
-
|
|
63147
|
-
|
|
63148
|
-
|
|
63149
|
-
|
|
63150
|
-
|
|
63151
|
-
|
|
63152
|
-
|
|
63153
|
-
|
|
63154
|
-
|
|
63155
|
-
|
|
63156
|
-
|
|
63157
|
-
|
|
63158
|
-
|
|
63159
|
-
|
|
63160
|
-
"button",
|
|
63184
|
+
"refresh"
|
|
63185
|
+
]],
|
|
63186
|
+
{ click: (evt) => {
|
|
63187
|
+
evt.stopPropagation();
|
|
63188
|
+
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_REFRESH_TREEDB", { evt }, gobj);
|
|
63189
|
+
} }
|
|
63190
|
+
], [
|
|
63191
|
+
"button",
|
|
63192
|
+
{
|
|
63193
|
+
class: "button ml-2 TREEDB_JSON_BTN",
|
|
63194
|
+
title: (0, i18next.t)("raw json"),
|
|
63195
|
+
"aria-label": (0, i18next.t)("raw json"),
|
|
63196
|
+
"data-i18n-title": "raw json",
|
|
63197
|
+
"data-i18n-aria-label": "raw json"
|
|
63198
|
+
},
|
|
63199
|
+
[yui_toolbar_icon("yi-eye"), [
|
|
63200
|
+
"span",
|
|
63161
63201
|
{
|
|
63162
|
-
class: "
|
|
63163
|
-
|
|
63164
|
-
|
|
63165
|
-
"data-i18n-title": "raw json",
|
|
63166
|
-
"data-i18n-aria-label": "raw json"
|
|
63202
|
+
class: "is-hidden-mobile",
|
|
63203
|
+
style: "padding-left:5px;",
|
|
63204
|
+
i18n: "raw json"
|
|
63167
63205
|
},
|
|
63168
|
-
|
|
63169
|
-
|
|
63170
|
-
|
|
63171
|
-
|
|
63172
|
-
|
|
63173
|
-
|
|
63174
|
-
|
|
63175
|
-
"raw json"
|
|
63176
|
-
]],
|
|
63177
|
-
{ click: (evt) => {
|
|
63178
|
-
evt.stopPropagation();
|
|
63179
|
-
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_OPEN_JSON", {}, gobj);
|
|
63180
|
-
} }
|
|
63181
|
-
]
|
|
63182
|
-
];
|
|
63206
|
+
"raw json"
|
|
63207
|
+
]],
|
|
63208
|
+
{ click: (evt) => {
|
|
63209
|
+
evt.stopPropagation();
|
|
63210
|
+
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_OPEN_JSON", {}, gobj);
|
|
63211
|
+
} }
|
|
63212
|
+
]];
|
|
63183
63213
|
let $find_input = (0, _yuneta_gobj_js.createElement2)([
|
|
63184
63214
|
"input",
|
|
63185
63215
|
{
|
|
@@ -63214,6 +63244,18 @@ function make_toolbar(gobj) {
|
|
|
63214
63244
|
]]
|
|
63215
63245
|
]);
|
|
63216
63246
|
attach_clear($find_control, $find_input);
|
|
63247
|
+
let right_items = [...[$find_control, [
|
|
63248
|
+
"div",
|
|
63249
|
+
{
|
|
63250
|
+
class: "GRAPH_FIND_RESULT is-hidden",
|
|
63251
|
+
style: "display:flex; align-items:center; gap:.3rem; margin-right:.5rem; font-size:.85rem;"
|
|
63252
|
+
},
|
|
63253
|
+
[[
|
|
63254
|
+
"span",
|
|
63255
|
+
{ class: "GRAPH_FIND_COUNT" },
|
|
63256
|
+
""
|
|
63257
|
+
]]
|
|
63258
|
+
]], ...backend_items];
|
|
63217
63259
|
const $toolbar_header = yui_toolbar({}, [
|
|
63218
63260
|
[
|
|
63219
63261
|
"div",
|
|
@@ -63223,23 +63265,12 @@ function make_toolbar(gobj) {
|
|
|
63223
63265
|
[
|
|
63224
63266
|
"div",
|
|
63225
63267
|
{ class: "yui-horizontal-toolbar-section center" },
|
|
63226
|
-
|
|
63227
|
-
"div",
|
|
63228
|
-
{
|
|
63229
|
-
class: "GRAPH_FIND_RESULT is-hidden",
|
|
63230
|
-
style: "display:flex; align-items:center; gap:.3rem; margin-right:.5rem; font-size:.85rem;"
|
|
63231
|
-
},
|
|
63232
|
-
[[
|
|
63233
|
-
"span",
|
|
63234
|
-
{ class: "GRAPH_FIND_COUNT" },
|
|
63235
|
-
""
|
|
63236
|
-
]]
|
|
63237
|
-
]]
|
|
63268
|
+
center_items
|
|
63238
63269
|
],
|
|
63239
63270
|
[
|
|
63240
63271
|
"div",
|
|
63241
63272
|
{ class: "GRAPH_MODE_BUTTONS yui-horizontal-toolbar-section right" },
|
|
63242
|
-
|
|
63273
|
+
right_items
|
|
63243
63274
|
]
|
|
63244
63275
|
]);
|
|
63245
63276
|
(0, _yuneta_gobj_js.refresh_language)($toolbar_header, i18next.t);
|
package/dist/gobj-ui.es.js
CHANGED
|
@@ -57012,12 +57012,41 @@ var MIN_READABLE_ZOOM = .5;
|
|
|
57012
57012
|
* G6 reports them.
|
|
57013
57013
|
************************************************************/
|
|
57014
57014
|
var CAMERA_SETTLE_MS = 700;
|
|
57015
|
+
function node_nearest_view_centre(gobj) {
|
|
57016
|
+
let graph = gobj.priv.graph;
|
|
57017
|
+
let size;
|
|
57018
|
+
try {
|
|
57019
|
+
size = graph.getSize();
|
|
57020
|
+
} catch (e) {
|
|
57021
|
+
return "";
|
|
57022
|
+
}
|
|
57023
|
+
if (!is_array(size) || !(size[0] > 0) || !(size[1] > 0)) return "";
|
|
57024
|
+
let [w, h] = size;
|
|
57025
|
+
let best = "";
|
|
57026
|
+
let best_d = Infinity;
|
|
57027
|
+
for (let nd of graph.getNodeData() || []) {
|
|
57028
|
+
let vp = yui_graph_viewport_of(graph, nd.id);
|
|
57029
|
+
if (!vp || !is_number(vp[0]) || !is_number(vp[1])) continue;
|
|
57030
|
+
if (vp[0] < 0 || vp[1] < 0 || vp[0] > w || vp[1] > h) continue;
|
|
57031
|
+
let d = (vp[0] - w / 2) ** 2 + (vp[1] - h / 2) ** 2;
|
|
57032
|
+
if (d < best_d) {
|
|
57033
|
+
best_d = d;
|
|
57034
|
+
best = nd.id;
|
|
57035
|
+
}
|
|
57036
|
+
}
|
|
57037
|
+
return best;
|
|
57038
|
+
}
|
|
57039
|
+
function camera_anchor_node(gobj) {
|
|
57040
|
+
let priv = gobj.priv;
|
|
57041
|
+
if (priv.anchor_state === "on" && priv.anchor_id) return priv.anchor_id;
|
|
57042
|
+
return node_nearest_view_centre(gobj) || fold_keep_node(gobj);
|
|
57043
|
+
}
|
|
57015
57044
|
function read_camera(gobj) {
|
|
57016
57045
|
let graph = gobj.priv.graph;
|
|
57017
57046
|
if (!graph || typeof graph.getZoom !== "function") return null;
|
|
57018
57047
|
try {
|
|
57019
57048
|
let z = graph.getZoom();
|
|
57020
|
-
let node =
|
|
57049
|
+
let node = camera_anchor_node(gobj);
|
|
57021
57050
|
let vp = node ? yui_graph_viewport_of(graph, node) : null;
|
|
57022
57051
|
if (!is_number(z) || !node || !vp || !is_number(vp[0]) || !is_number(vp[1])) return null;
|
|
57023
57052
|
return {
|
|
@@ -57036,6 +57065,8 @@ async function restore_camera(gobj) {
|
|
|
57036
57065
|
let cam = gobj_read_attr(gobj, "camera");
|
|
57037
57066
|
if (!graph || empty_json(cam) || !is_number(cam.zoom) || !cam.node || !is_number(cam.x) || !is_number(cam.y)) return false;
|
|
57038
57067
|
if (!yui_graph_viewport_of(graph, cam.node)) return false;
|
|
57068
|
+
let size = graph.getSize() || [0, 0];
|
|
57069
|
+
if (cam.x < 0 || cam.y < 0 || cam.x > size[0] || cam.y > size[1]) return false;
|
|
57039
57070
|
priv._camera_restoring = true;
|
|
57040
57071
|
try {
|
|
57041
57072
|
await graph.zoomTo(cam.zoom);
|
|
@@ -61257,6 +61288,7 @@ async function reconcile_fold_apply(gobj, opts, visible) {
|
|
|
61257
61288
|
if (opts.fit) await graph_fit_readable(gobj);
|
|
61258
61289
|
else if (opts.keep && opts.keep_vp) await yui_graph_place_at(graph, opts.keep, opts.keep_vp);
|
|
61259
61290
|
}
|
|
61291
|
+
if ((graph.getNodeData() || []).length > 0 && !node_nearest_view_centre(gobj)) await graph_fit_readable(gobj);
|
|
61260
61292
|
priv._camera_placed = true;
|
|
61261
61293
|
update_resize_handles_position(gobj);
|
|
61262
61294
|
update_port_resize_handles_position(gobj);
|
|
@@ -63125,56 +63157,54 @@ function make_toolbar(gobj) {
|
|
|
63125
63157
|
evt.stopPropagation();
|
|
63126
63158
|
gobj_send_event(gobj, "EV_SET_OPERATION_MODE", { operation_mode: evt.target.value }, gobj);
|
|
63127
63159
|
} }
|
|
63128
|
-
]
|
|
63129
|
-
|
|
63130
|
-
|
|
63160
|
+
]
|
|
63161
|
+
];
|
|
63162
|
+
let center_items = [...yui_graph_fold_items(gobj, gobj_read_str_attr(gobj, "wide")), ...node_shape_items(gobj, gobj_read_str_attr(gobj, "wide"))];
|
|
63163
|
+
let backend_items = [[
|
|
63164
|
+
"button",
|
|
63165
|
+
{
|
|
63166
|
+
class: "GRAPH_REFRESH button",
|
|
63167
|
+
title: t("refresh"),
|
|
63168
|
+
"data-i18n-title": "refresh",
|
|
63169
|
+
"aria-label": t("refresh"),
|
|
63170
|
+
"data-i18n-aria-label": "refresh"
|
|
63171
|
+
},
|
|
63172
|
+
[yui_toolbar_icon("yi-arrows-rotate"), [
|
|
63173
|
+
"span",
|
|
63131
63174
|
{
|
|
63132
|
-
class: "
|
|
63133
|
-
|
|
63134
|
-
|
|
63135
|
-
"aria-label": t("refresh"),
|
|
63136
|
-
"data-i18n-aria-label": "refresh"
|
|
63175
|
+
class: "is-hidden-mobile",
|
|
63176
|
+
style: "padding-left:5px;",
|
|
63177
|
+
i18n: "refresh"
|
|
63137
63178
|
},
|
|
63138
|
-
|
|
63139
|
-
|
|
63140
|
-
|
|
63141
|
-
|
|
63142
|
-
|
|
63143
|
-
|
|
63144
|
-
|
|
63145
|
-
|
|
63146
|
-
|
|
63147
|
-
|
|
63148
|
-
|
|
63149
|
-
|
|
63150
|
-
|
|
63151
|
-
|
|
63152
|
-
|
|
63153
|
-
|
|
63154
|
-
|
|
63155
|
-
"button",
|
|
63179
|
+
"refresh"
|
|
63180
|
+
]],
|
|
63181
|
+
{ click: (evt) => {
|
|
63182
|
+
evt.stopPropagation();
|
|
63183
|
+
gobj_send_event(gobj, "EV_REFRESH_TREEDB", { evt }, gobj);
|
|
63184
|
+
} }
|
|
63185
|
+
], [
|
|
63186
|
+
"button",
|
|
63187
|
+
{
|
|
63188
|
+
class: "button ml-2 TREEDB_JSON_BTN",
|
|
63189
|
+
title: t("raw json"),
|
|
63190
|
+
"aria-label": t("raw json"),
|
|
63191
|
+
"data-i18n-title": "raw json",
|
|
63192
|
+
"data-i18n-aria-label": "raw json"
|
|
63193
|
+
},
|
|
63194
|
+
[yui_toolbar_icon("yi-eye"), [
|
|
63195
|
+
"span",
|
|
63156
63196
|
{
|
|
63157
|
-
class: "
|
|
63158
|
-
|
|
63159
|
-
|
|
63160
|
-
"data-i18n-title": "raw json",
|
|
63161
|
-
"data-i18n-aria-label": "raw json"
|
|
63197
|
+
class: "is-hidden-mobile",
|
|
63198
|
+
style: "padding-left:5px;",
|
|
63199
|
+
i18n: "raw json"
|
|
63162
63200
|
},
|
|
63163
|
-
|
|
63164
|
-
|
|
63165
|
-
|
|
63166
|
-
|
|
63167
|
-
|
|
63168
|
-
|
|
63169
|
-
|
|
63170
|
-
"raw json"
|
|
63171
|
-
]],
|
|
63172
|
-
{ click: (evt) => {
|
|
63173
|
-
evt.stopPropagation();
|
|
63174
|
-
gobj_send_event(gobj, "EV_OPEN_JSON", {}, gobj);
|
|
63175
|
-
} }
|
|
63176
|
-
]
|
|
63177
|
-
];
|
|
63201
|
+
"raw json"
|
|
63202
|
+
]],
|
|
63203
|
+
{ click: (evt) => {
|
|
63204
|
+
evt.stopPropagation();
|
|
63205
|
+
gobj_send_event(gobj, "EV_OPEN_JSON", {}, gobj);
|
|
63206
|
+
} }
|
|
63207
|
+
]];
|
|
63178
63208
|
let $find_input = createElement2([
|
|
63179
63209
|
"input",
|
|
63180
63210
|
{
|
|
@@ -63209,6 +63239,18 @@ function make_toolbar(gobj) {
|
|
|
63209
63239
|
]]
|
|
63210
63240
|
]);
|
|
63211
63241
|
attach_clear($find_control, $find_input);
|
|
63242
|
+
let right_items = [...[$find_control, [
|
|
63243
|
+
"div",
|
|
63244
|
+
{
|
|
63245
|
+
class: "GRAPH_FIND_RESULT is-hidden",
|
|
63246
|
+
style: "display:flex; align-items:center; gap:.3rem; margin-right:.5rem; font-size:.85rem;"
|
|
63247
|
+
},
|
|
63248
|
+
[[
|
|
63249
|
+
"span",
|
|
63250
|
+
{ class: "GRAPH_FIND_COUNT" },
|
|
63251
|
+
""
|
|
63252
|
+
]]
|
|
63253
|
+
]], ...backend_items];
|
|
63212
63254
|
const $toolbar_header = yui_toolbar({}, [
|
|
63213
63255
|
[
|
|
63214
63256
|
"div",
|
|
@@ -63218,23 +63260,12 @@ function make_toolbar(gobj) {
|
|
|
63218
63260
|
[
|
|
63219
63261
|
"div",
|
|
63220
63262
|
{ class: "yui-horizontal-toolbar-section center" },
|
|
63221
|
-
|
|
63222
|
-
"div",
|
|
63223
|
-
{
|
|
63224
|
-
class: "GRAPH_FIND_RESULT is-hidden",
|
|
63225
|
-
style: "display:flex; align-items:center; gap:.3rem; margin-right:.5rem; font-size:.85rem;"
|
|
63226
|
-
},
|
|
63227
|
-
[[
|
|
63228
|
-
"span",
|
|
63229
|
-
{ class: "GRAPH_FIND_COUNT" },
|
|
63230
|
-
""
|
|
63231
|
-
]]
|
|
63232
|
-
]]
|
|
63263
|
+
center_items
|
|
63233
63264
|
],
|
|
63234
63265
|
[
|
|
63235
63266
|
"div",
|
|
63236
63267
|
{ class: "GRAPH_MODE_BUTTONS yui-horizontal-toolbar-section right" },
|
|
63237
|
-
|
|
63268
|
+
right_items
|
|
63238
63269
|
]
|
|
63239
63270
|
]);
|
|
63240
63271
|
refresh_language($toolbar_header, t);
|
package/package.json
CHANGED
package/src/c_g6_nodes_tree.js
CHANGED
|
@@ -3382,6 +3382,58 @@ const CAMERA_SETTLE_MS = 700;
|
|
|
3382
3382
|
*
|
|
3383
3383
|
* A node and a pixel is also the SAME thing the folds keep across a
|
|
3384
3384
|
* rebuild. One idea, used twice. */
|
|
3385
|
+
/* The drawn node nearest the middle of the VIEWPORT, among the ones
|
|
3386
|
+
* inside it; "" when there is none -- which is a blank view. */
|
|
3387
|
+
function node_nearest_view_centre(gobj)
|
|
3388
|
+
{
|
|
3389
|
+
let graph = gobj.priv.graph;
|
|
3390
|
+
let size;
|
|
3391
|
+
try {
|
|
3392
|
+
size = graph.getSize();
|
|
3393
|
+
} catch(e) {
|
|
3394
|
+
return ""; /* between renders: nothing is drawn */
|
|
3395
|
+
}
|
|
3396
|
+
if(!is_array(size) || !(size[0] > 0) || !(size[1] > 0)) {
|
|
3397
|
+
return "";
|
|
3398
|
+
}
|
|
3399
|
+
let [w, h] = size;
|
|
3400
|
+
let best = "";
|
|
3401
|
+
let best_d = Infinity;
|
|
3402
|
+
for(let nd of (graph.getNodeData() || [])) {
|
|
3403
|
+
let vp = yui_graph_viewport_of(graph, nd.id);
|
|
3404
|
+
if(!vp || !is_number(vp[0]) || !is_number(vp[1])) {
|
|
3405
|
+
continue;
|
|
3406
|
+
}
|
|
3407
|
+
if(vp[0] < 0 || vp[1] < 0 || vp[0] > w || vp[1] > h) {
|
|
3408
|
+
continue;
|
|
3409
|
+
}
|
|
3410
|
+
let d = (vp[0] - w / 2) ** 2 + (vp[1] - h / 2) ** 2;
|
|
3411
|
+
if(d < best_d) {
|
|
3412
|
+
best_d = d;
|
|
3413
|
+
best = nd.id;
|
|
3414
|
+
}
|
|
3415
|
+
}
|
|
3416
|
+
return best;
|
|
3417
|
+
}
|
|
3418
|
+
|
|
3419
|
+
/* The node a camera is SAVED by: the anchor when one is set, else the
|
|
3420
|
+
* node nearest the middle of the viewport.
|
|
3421
|
+
*
|
|
3422
|
+
* It used to be fold_keep_node() -- the first root of the tree,
|
|
3423
|
+
* wherever it was. A reader who had panned away saved a node OFF
|
|
3424
|
+
* screen at a pixel off screen, and a reload whose layout had moved
|
|
3425
|
+
* by a hair put that one node back at that pixel and nothing else in
|
|
3426
|
+
* view: a blank graph, with the whole tree sitting in the minimap. */
|
|
3427
|
+
function camera_anchor_node(gobj)
|
|
3428
|
+
{
|
|
3429
|
+
let priv = gobj.priv;
|
|
3430
|
+
|
|
3431
|
+
if(priv.anchor_state === "on" && priv.anchor_id) {
|
|
3432
|
+
return priv.anchor_id;
|
|
3433
|
+
}
|
|
3434
|
+
return node_nearest_view_centre(gobj) || fold_keep_node(gobj);
|
|
3435
|
+
}
|
|
3436
|
+
|
|
3385
3437
|
function read_camera(gobj)
|
|
3386
3438
|
{
|
|
3387
3439
|
let priv = gobj.priv;
|
|
@@ -3392,7 +3444,7 @@ function read_camera(gobj)
|
|
|
3392
3444
|
}
|
|
3393
3445
|
try {
|
|
3394
3446
|
let z = graph.getZoom();
|
|
3395
|
-
let node =
|
|
3447
|
+
let node = camera_anchor_node(gobj);
|
|
3396
3448
|
let vp = node? yui_graph_viewport_of(graph, node) : null;
|
|
3397
3449
|
if(!is_number(z) || !node || !vp || !is_number(vp[0]) || !is_number(vp[1])) {
|
|
3398
3450
|
return null;
|
|
@@ -3422,6 +3474,13 @@ async function restore_camera(gobj)
|
|
|
3422
3474
|
if(!yui_graph_viewport_of(graph, cam.node)) {
|
|
3423
3475
|
return false;
|
|
3424
3476
|
}
|
|
3477
|
+
/* A camera saved by a node OFF screen (before 7.23.137 the node was
|
|
3478
|
+
* the first root, wherever it was) frames nothing it can promise:
|
|
3479
|
+
* the opening fit instead. */
|
|
3480
|
+
let size = graph.getSize() || [0, 0];
|
|
3481
|
+
if(cam.x < 0 || cam.y < 0 || cam.x > size[0] || cam.y > size[1]) {
|
|
3482
|
+
return false;
|
|
3483
|
+
}
|
|
3425
3484
|
priv._camera_restoring = true;
|
|
3426
3485
|
try {
|
|
3427
3486
|
await graph.zoomTo(cam.zoom);
|
|
@@ -9709,6 +9768,15 @@ async function reconcile_fold_apply(gobj, opts, visible)
|
|
|
9709
9768
|
await yui_graph_place_at(graph, opts.keep, opts.keep_vp);
|
|
9710
9769
|
}
|
|
9711
9770
|
}
|
|
9771
|
+
/* And never a BLANK viewport. Every branch above can leave one: a
|
|
9772
|
+
* restore by a node whose surroundings moved, a refresh or a global
|
|
9773
|
+
* fold holding the first root still at a pixel off screen, a saved
|
|
9774
|
+
* arrangement opened with no camera (no fit: its owner's view is
|
|
9775
|
+
* part of it) far from where G6 starts looking. A view with nothing
|
|
9776
|
+
* in it is not a place anybody chose to be. */
|
|
9777
|
+
if((graph.getNodeData() || []).length > 0 && !node_nearest_view_centre(gobj)) {
|
|
9778
|
+
await graph_fit_readable(gobj);
|
|
9779
|
+
}
|
|
9712
9780
|
/* Whichever branch ran -- including none of them, which is a
|
|
9713
9781
|
* graph somebody had arranged and left where it was -- the
|
|
9714
9782
|
* opening viewport is decided from here on, and every move after
|
|
@@ -694,6 +694,11 @@ function make_toolbar(gobj)
|
|
|
694
694
|
);
|
|
695
695
|
|
|
696
696
|
/*
|
|
697
|
+
* Three sections, by what the control is ABOUT:
|
|
698
|
+
* left how the graph is built: layout and operation mode
|
|
699
|
+
* center how it is SHOWN: the fold pair and the node views
|
|
700
|
+
* right what it is asked: find, refresh, the raw json
|
|
701
|
+
*
|
|
697
702
|
* Left: layout and mode selectors
|
|
698
703
|
* Layout options are empty — populated after child creation
|
|
699
704
|
* via populate_nodes_tree_options()
|
|
@@ -730,6 +735,28 @@ function make_toolbar(gobj)
|
|
|
730
735
|
}
|
|
731
736
|
}],
|
|
732
737
|
|
|
738
|
+
];
|
|
739
|
+
|
|
740
|
+
/*
|
|
741
|
+
* Center: how the graph is SHOWN.
|
|
742
|
+
*/
|
|
743
|
+
let center_items = [
|
|
744
|
+
/* The fold pair, the same two chevrons the JSON graph and the
|
|
745
|
+
* lazy tree use: the graph opens folded (see the G6 child), and
|
|
746
|
+
* these are the whole thing and the roots alone. Refresh is the
|
|
747
|
+
* way back to the default depth. */
|
|
748
|
+
...yui_graph_fold_items(gobj, gobj_read_str_attr(gobj, "wide")),
|
|
749
|
+
|
|
750
|
+
/* The view of the nodes -- full cards, one-line pills or
|
|
751
|
+
* figures -- and the name under a figure. */
|
|
752
|
+
...node_shape_items(gobj, gobj_read_str_attr(gobj, "wide")),
|
|
753
|
+
];
|
|
754
|
+
|
|
755
|
+
/*
|
|
756
|
+
* Right, after the find box: ask the backend again, and read its
|
|
757
|
+
* raw json.
|
|
758
|
+
*/
|
|
759
|
+
let backend_items = [
|
|
733
760
|
/* Icon + label, and the label is `is-hidden-mobile`: on a phone
|
|
734
761
|
* this is a bare icon, so the name has to be on the button. */
|
|
735
762
|
['button', {class: 'GRAPH_REFRESH button',
|
|
@@ -744,16 +771,6 @@ function make_toolbar(gobj)
|
|
|
744
771
|
}
|
|
745
772
|
}],
|
|
746
773
|
|
|
747
|
-
/* The fold pair, the same two chevrons the JSON graph and the
|
|
748
|
-
* lazy tree use: the graph opens folded (see the G6 child), and
|
|
749
|
-
* these are the whole thing and the roots alone. Refresh is the
|
|
750
|
-
* way back to the default depth. */
|
|
751
|
-
...yui_graph_fold_items(gobj, gobj_read_str_attr(gobj, "wide")),
|
|
752
|
-
|
|
753
|
-
/* The view of the nodes -- full cards, one-line pills or
|
|
754
|
-
* figures -- and the name under a figure. */
|
|
755
|
-
...node_shape_items(gobj, gobj_read_str_attr(gobj, "wide")),
|
|
756
|
-
|
|
757
774
|
/* Inspect the treedb's raw tranger json in the lazy tree viewer
|
|
758
775
|
* (print-tranger on the C_NODE service). A treedb can be huge, so
|
|
759
776
|
* the viewer drills in on demand — see open_json_viewer. */
|
|
@@ -771,7 +788,7 @@ function make_toolbar(gobj)
|
|
|
771
788
|
];
|
|
772
789
|
|
|
773
790
|
/*
|
|
774
|
-
*
|
|
791
|
+
* Right: find a node.
|
|
775
792
|
*
|
|
776
793
|
* A graph of a few hundred records has no other way in: the only way
|
|
777
794
|
* to locate one was to read every card. The box highlights every
|
|
@@ -821,7 +838,7 @@ function make_toolbar(gobj)
|
|
|
821
838
|
]]);
|
|
822
839
|
attach_clear($find_control, $find_input);
|
|
823
840
|
|
|
824
|
-
let
|
|
841
|
+
let find_items = [
|
|
825
842
|
$find_control,
|
|
826
843
|
/* ONE counted span, not a number beside a word: "1 matches" is
|
|
827
844
|
* what two spans always produce, because nothing there can see
|
|
@@ -844,10 +861,9 @@ function make_toolbar(gobj)
|
|
|
844
861
|
]]
|
|
845
862
|
];
|
|
846
863
|
|
|
847
|
-
/*
|
|
848
|
-
* Right, fill in set_mode
|
|
849
|
-
*/
|
|
850
864
|
let right_items = [
|
|
865
|
+
...find_items,
|
|
866
|
+
...backend_items,
|
|
851
867
|
];
|
|
852
868
|
|
|
853
869
|
const $toolbar_header = yui_toolbar({}, [
|