@yuneta/gobj-ui 7.23.3 → 7.23.4
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 +10 -6
- package/dist/gobj-ui.cjs.js +181 -217
- package/dist/gobj-ui.es.js +181 -217
- package/package.json +1 -1
- package/src/c_yui_gobj_tree_js.js +24 -34
- package/src/c_yui_json_graph.js +15 -126
- package/src/yui_graph_camera.js +150 -0
package/README.md
CHANGED
|
@@ -448,12 +448,16 @@ stays. Note the close contract: `C_YUI_WINDOW.close_window()` calls `on_close`
|
|
|
448
448
|
and THEN destroys itself, so a host must drop its reference rather than destroy
|
|
449
449
|
the window too.
|
|
450
450
|
|
|
451
|
-
Its camera
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
451
|
+
Its camera comes from **`yui_graph_camera.js`** (`7.23.4`), the one place every
|
|
452
|
+
DOM-toolbar graph asks for one — this gclass and the gobj tree both, so a
|
|
453
|
+
cloned toolbar cannot drift apart again. The vocabulary is the treedb graph's
|
|
454
|
+
(`c_g6_nodes_tree.js`, which draws its toolbar as a G6 plugin over an SVG
|
|
455
|
+
sprite and so cannot share the code, only the decisions): zoom in / zoom out, a
|
|
456
|
+
live **zoom readout**, `yi-fit` for fit — the same corner brackets the sprite
|
|
457
|
+
draws for `g6-icon-fit` — and the WRITTEN `1:1` for actual size, which is
|
|
458
|
+
written in every editor that offers it and never drawn. Fold is the chevron
|
|
459
|
+
pair, from the lazy tree viewer's own toolbar. The readout hangs off G6's
|
|
460
|
+
`aftertransform`, the one hook that also covers the wheel.
|
|
457
461
|
|
|
458
462
|
The graph carries **its own** toolbar, a **layout picker**
|
|
459
463
|
(`EV_CHANGE_LAYOUT {layout}`: `vertical tree`, `dagre top-down`,
|
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -9350,6 +9350,160 @@ function yui_toolbar(attrs = {}, items = []) {
|
|
|
9350
9350
|
return $toolbar;
|
|
9351
9351
|
}
|
|
9352
9352
|
//#endregion
|
|
9353
|
+
//#region src/yui_graph_camera.js
|
|
9354
|
+
/***********************************************************************
|
|
9355
|
+
* yui_graph_camera.js
|
|
9356
|
+
*
|
|
9357
|
+
* The camera and fold controls a G6 graph puts in a DOM toolbar,
|
|
9358
|
+
* built in ONE place.
|
|
9359
|
+
*
|
|
9360
|
+
* This module exists because the same action was drawn three
|
|
9361
|
+
* different ways across sibling views — actual size as a bare
|
|
9362
|
+
* magnifier here and as `1:1` there, fit as `arrows-to-eye` here and
|
|
9363
|
+
* as corner brackets there, fold as chevrons here and as an eye
|
|
9364
|
+
* there. A user sees two of these graphs side by side in the same
|
|
9365
|
+
* console, so a copied-and-drifted toolbar is not a detail.
|
|
9366
|
+
*
|
|
9367
|
+
* The VOCABULARY is not invented here. It is the one
|
|
9368
|
+
* `c_g6_nodes_tree.js` settled on for the treedb graph, which draws
|
|
9369
|
+
* its toolbar as a G6 plugin over an SVG sprite and therefore cannot
|
|
9370
|
+
* share this code — only its decisions:
|
|
9371
|
+
*
|
|
9372
|
+
* zoom in / zoom out magnifiers
|
|
9373
|
+
* zoom level a READOUT, because without it "1:1" is
|
|
9374
|
+
* a jump to a value nobody was told
|
|
9375
|
+
* fit corner brackets (`yi-fit`, the same
|
|
9376
|
+
* path as the sprite's `g6-icon-fit`)
|
|
9377
|
+
* actual size the WRITTEN `1:1` — the action is
|
|
9378
|
+
* `zoomTo(1)`, and actual size is written
|
|
9379
|
+
* in every editor that offers it, never
|
|
9380
|
+
* drawn, because there is no glyph for it
|
|
9381
|
+
*
|
|
9382
|
+
* Fold is the one the treedb graph does not have, so its vocabulary
|
|
9383
|
+
* comes from the other side of the family: the lazy tree viewer's own
|
|
9384
|
+
* toolbar (`c_yui_json.js`) uses chevrons — open pointing down, closed
|
|
9385
|
+
* pointing right — which is also the direction the per-node handles
|
|
9386
|
+
* speak. An eye means show/hide, which is a different idea.
|
|
9387
|
+
*
|
|
9388
|
+
* Copyright (c) 2026, ArtGins.
|
|
9389
|
+
* All Rights Reserved.
|
|
9390
|
+
***********************************************************************/
|
|
9391
|
+
/************************************************************
|
|
9392
|
+
* One icon button that fires `event_name`.
|
|
9393
|
+
************************************************************/
|
|
9394
|
+
function camera_button(gobj, icon, event_name, label_key, wide, extra_style) {
|
|
9395
|
+
return [
|
|
9396
|
+
"button",
|
|
9397
|
+
{
|
|
9398
|
+
class: `button ${event_name}`,
|
|
9399
|
+
type: "button",
|
|
9400
|
+
style: {
|
|
9401
|
+
height: wide,
|
|
9402
|
+
width: "2.5em"
|
|
9403
|
+
},
|
|
9404
|
+
title: (0, i18next.t)(label_key),
|
|
9405
|
+
"data-i18n-title": label_key,
|
|
9406
|
+
"aria-label": (0, i18next.t)(label_key),
|
|
9407
|
+
"data-i18n-aria-label": label_key
|
|
9408
|
+
},
|
|
9409
|
+
["i", {
|
|
9410
|
+
style: "font-size:1.5em; color:inherit;" + (extra_style || ""),
|
|
9411
|
+
class: icon
|
|
9412
|
+
}],
|
|
9413
|
+
{ click: (evt) => {
|
|
9414
|
+
evt.stopPropagation();
|
|
9415
|
+
(0, _yuneta_gobj_js.gobj_send_event)(gobj, event_name, { evt }, gobj);
|
|
9416
|
+
} }
|
|
9417
|
+
];
|
|
9418
|
+
}
|
|
9419
|
+
/************************************************************
|
|
9420
|
+
* The current zoom as a percentage.
|
|
9421
|
+
************************************************************/
|
|
9422
|
+
function yui_graph_zoom_text(graph) {
|
|
9423
|
+
if (!graph) return "100%";
|
|
9424
|
+
try {
|
|
9425
|
+
return Math.round(graph.getZoom() * 100) + "%";
|
|
9426
|
+
} catch (e) {
|
|
9427
|
+
return "100%";
|
|
9428
|
+
}
|
|
9429
|
+
}
|
|
9430
|
+
/************************************************************
|
|
9431
|
+
* Repaint the readout of a container that carries one.
|
|
9432
|
+
*
|
|
9433
|
+
* Call it from G6's `aftertransform`, which is the ONE hook
|
|
9434
|
+
* that also covers the WHEEL — a camera change that passes
|
|
9435
|
+
* through no action, so repainting from each zoom action
|
|
9436
|
+
* leaves the number lying after every notch.
|
|
9437
|
+
************************************************************/
|
|
9438
|
+
function yui_graph_update_zoom($container, graph) {
|
|
9439
|
+
if (!$container) return;
|
|
9440
|
+
let $readout = $container.querySelector(".GRAPH_ZOOM_LEVEL");
|
|
9441
|
+
if (!$readout) return;
|
|
9442
|
+
$readout.textContent = yui_graph_zoom_text(graph);
|
|
9443
|
+
}
|
|
9444
|
+
/************************************************************
|
|
9445
|
+
* The camera cluster: zoom in, zoom out, readout, fit,
|
|
9446
|
+
* actual size. Returns createElement2 specs, in order.
|
|
9447
|
+
*
|
|
9448
|
+
* `wide` is the host toolbar's button height.
|
|
9449
|
+
************************************************************/
|
|
9450
|
+
function yui_graph_camera_items(gobj, graph, wide) {
|
|
9451
|
+
return [
|
|
9452
|
+
camera_button(gobj, "yi-magnifying-glass-plus", "EV_ZOOM_IN", "zoom in", wide),
|
|
9453
|
+
camera_button(gobj, "yi-magnifying-glass-minus", "EV_ZOOM_OUT", "zoom out", wide),
|
|
9454
|
+
[
|
|
9455
|
+
"span",
|
|
9456
|
+
{
|
|
9457
|
+
class: "GRAPH_ZOOM_LEVEL is-flex is-align-items-center px-2 has-text-grey",
|
|
9458
|
+
style: "font-size:.85rem; min-width:3.5em; justify-content:center;",
|
|
9459
|
+
title: (0, i18next.t)("zoom level"),
|
|
9460
|
+
"data-i18n-title": "zoom level"
|
|
9461
|
+
},
|
|
9462
|
+
yui_graph_zoom_text(graph)
|
|
9463
|
+
],
|
|
9464
|
+
camera_button(gobj, "yi-fit", "EV_CENTER", "auto fit", wide),
|
|
9465
|
+
[
|
|
9466
|
+
"button",
|
|
9467
|
+
{
|
|
9468
|
+
class: "button EV_ZOOM_RESET",
|
|
9469
|
+
type: "button",
|
|
9470
|
+
style: {
|
|
9471
|
+
height: wide,
|
|
9472
|
+
width: "2.5em"
|
|
9473
|
+
},
|
|
9474
|
+
title: (0, i18next.t)("actual size"),
|
|
9475
|
+
"data-i18n-title": "actual size",
|
|
9476
|
+
"aria-label": (0, i18next.t)("actual size"),
|
|
9477
|
+
"data-i18n-aria-label": "actual size"
|
|
9478
|
+
},
|
|
9479
|
+
[
|
|
9480
|
+
"span",
|
|
9481
|
+
{ style: "font-weight:700;" },
|
|
9482
|
+
"1:1"
|
|
9483
|
+
],
|
|
9484
|
+
{ click: (evt) => {
|
|
9485
|
+
evt.stopPropagation();
|
|
9486
|
+
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_ZOOM_RESET", { evt }, gobj);
|
|
9487
|
+
} }
|
|
9488
|
+
]
|
|
9489
|
+
];
|
|
9490
|
+
}
|
|
9491
|
+
/************************************************************
|
|
9492
|
+
* The fold pair: expand all, collapse all. Chevrons, the
|
|
9493
|
+
* open one rotated down — the same pair the lazy tree
|
|
9494
|
+
* viewer's toolbar uses, and the same direction the
|
|
9495
|
+
* per-node handles speak.
|
|
9496
|
+
************************************************************/
|
|
9497
|
+
function yui_graph_fold_items(gobj, wide) {
|
|
9498
|
+
return [camera_button(gobj, "yi-chevron-right", "EV_EXPAND_ALL", "expand all", wide, " transform: rotate(90deg);"), camera_button(gobj, "yi-chevron-right", "EV_COLLAPSE_ALL", "collapse all", wide)];
|
|
9499
|
+
}
|
|
9500
|
+
/************************************************************
|
|
9501
|
+
* A refresh button, for the graphs that offer one.
|
|
9502
|
+
************************************************************/
|
|
9503
|
+
function yui_graph_refresh_item(gobj, wide) {
|
|
9504
|
+
return camera_button(gobj, "yi-arrows-rotate", "EV_REFRESH", "refresh", wide);
|
|
9505
|
+
}
|
|
9506
|
+
//#endregion
|
|
9353
9507
|
//#region src/g6_drag_canvas_touch.js
|
|
9354
9508
|
/***********************************************************************
|
|
9355
9509
|
* g6_drag_canvas_touch.js
|
|
@@ -9556,7 +9710,6 @@ var PRIVATE_DATA$11 = {
|
|
|
9556
9710
|
find_timer: null,
|
|
9557
9711
|
fold_listener: null,
|
|
9558
9712
|
$layout_select: null,
|
|
9559
|
-
$zoom_readout: null,
|
|
9560
9713
|
$find_input: null,
|
|
9561
9714
|
$find_result: null,
|
|
9562
9715
|
$find_count: null
|
|
@@ -9754,84 +9907,6 @@ function destroy_ui$6(gobj) {
|
|
|
9754
9907
|
}
|
|
9755
9908
|
}
|
|
9756
9909
|
/************************************************************
|
|
9757
|
-
* One camera button.
|
|
9758
|
-
************************************************************/
|
|
9759
|
-
function camera_button(gobj, icon, event_name, label_key, wide) {
|
|
9760
|
-
return [
|
|
9761
|
-
"button",
|
|
9762
|
-
{
|
|
9763
|
-
class: `button ${event_name}`,
|
|
9764
|
-
type: "button",
|
|
9765
|
-
style: {
|
|
9766
|
-
height: wide,
|
|
9767
|
-
width: "2.5em"
|
|
9768
|
-
},
|
|
9769
|
-
title: (0, i18next.t)(label_key),
|
|
9770
|
-
"data-i18n-title": label_key,
|
|
9771
|
-
"aria-label": (0, i18next.t)(label_key),
|
|
9772
|
-
"data-i18n-aria-label": label_key
|
|
9773
|
-
},
|
|
9774
|
-
["i", {
|
|
9775
|
-
style: "font-size:1.5em; color:inherit;",
|
|
9776
|
-
class: icon
|
|
9777
|
-
}],
|
|
9778
|
-
{ click: (evt) => {
|
|
9779
|
-
evt.stopPropagation();
|
|
9780
|
-
(0, _yuneta_gobj_js.gobj_send_event)(gobj, event_name, { evt }, gobj);
|
|
9781
|
-
} }
|
|
9782
|
-
];
|
|
9783
|
-
}
|
|
9784
|
-
/************************************************************
|
|
9785
|
-
* The zoom, as a percentage. What the two magnifiers
|
|
9786
|
-
* change: an editor that offers a zoom shows the number.
|
|
9787
|
-
************************************************************/
|
|
9788
|
-
function zoom_percent_text$1(gobj) {
|
|
9789
|
-
let graph = gobj.priv.graph;
|
|
9790
|
-
if (!graph) return "100%";
|
|
9791
|
-
try {
|
|
9792
|
-
return Math.round(graph.getZoom() * 100) + "%";
|
|
9793
|
-
} catch (e) {
|
|
9794
|
-
return "100%";
|
|
9795
|
-
}
|
|
9796
|
-
}
|
|
9797
|
-
/************************************************************
|
|
9798
|
-
* Repaint the readout after anything that moves the camera.
|
|
9799
|
-
************************************************************/
|
|
9800
|
-
function update_zoom_readout$1(gobj) {
|
|
9801
|
-
let priv = gobj.priv;
|
|
9802
|
-
if (priv.$zoom_readout) priv.$zoom_readout.textContent = zoom_percent_text$1(gobj);
|
|
9803
|
-
}
|
|
9804
|
-
/************************************************************
|
|
9805
|
-
* One fold button. `open` rotates the chevron to the open
|
|
9806
|
-
* state, mirroring the per-node toggle of the lazy tree.
|
|
9807
|
-
************************************************************/
|
|
9808
|
-
function graph_fold_button(gobj, event_name, label_key, open) {
|
|
9809
|
-
let icon_style = "font-size:1.5em; color:inherit;" + (open ? " transform: rotate(90deg);" : "");
|
|
9810
|
-
return [
|
|
9811
|
-
"button",
|
|
9812
|
-
{
|
|
9813
|
-
class: `button ${event_name}`,
|
|
9814
|
-
type: "button",
|
|
9815
|
-
style: {
|
|
9816
|
-
height: (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "wide"),
|
|
9817
|
-
width: "2.5em"
|
|
9818
|
-
},
|
|
9819
|
-
title: (0, i18next.t)(label_key),
|
|
9820
|
-
"data-i18n-title": label_key,
|
|
9821
|
-
"aria-label": (0, i18next.t)(label_key),
|
|
9822
|
-
"data-i18n-aria-label": label_key
|
|
9823
|
-
},
|
|
9824
|
-
["i", {
|
|
9825
|
-
style: icon_style,
|
|
9826
|
-
class: "yi-chevron-right"
|
|
9827
|
-
}],
|
|
9828
|
-
{ click: (evt) => {
|
|
9829
|
-
evt.stopPropagation();
|
|
9830
|
-
(0, _yuneta_gobj_js.gobj_send_event)(gobj, event_name, {}, gobj);
|
|
9831
|
-
} }
|
|
9832
|
-
];
|
|
9833
|
-
}
|
|
9834
|
-
/************************************************************
|
|
9835
9910
|
* Toolbar
|
|
9836
9911
|
************************************************************/
|
|
9837
9912
|
function make_toolbar$3(gobj) {
|
|
@@ -9881,52 +9956,8 @@ function make_toolbar$3(gobj) {
|
|
|
9881
9956
|
]]
|
|
9882
9957
|
]];
|
|
9883
9958
|
let center_items = [];
|
|
9884
|
-
|
|
9885
|
-
|
|
9886
|
-
"EV_ZOOM_IN",
|
|
9887
|
-
"zoom in"
|
|
9888
|
-
], [
|
|
9889
|
-
"yi-magnifying-glass-minus",
|
|
9890
|
-
"EV_ZOOM_OUT",
|
|
9891
|
-
"zoom out"
|
|
9892
|
-
]]) center_items.push(camera_button(gobj, item[0], item[1], item[2], toolbar_wide));
|
|
9893
|
-
priv.$zoom_readout = (0, _yuneta_gobj_js.createElement2)([
|
|
9894
|
-
"span",
|
|
9895
|
-
{
|
|
9896
|
-
class: "JSON_GRAPH_ZOOM_LEVEL is-flex is-align-items-center px-2 has-text-grey",
|
|
9897
|
-
style: "font-size:.85rem; min-width:3.5em; justify-content:center;",
|
|
9898
|
-
title: (0, i18next.t)("zoom level"),
|
|
9899
|
-
"data-i18n-title": "zoom level"
|
|
9900
|
-
},
|
|
9901
|
-
zoom_percent_text$1(gobj)
|
|
9902
|
-
]);
|
|
9903
|
-
center_items.push(priv.$zoom_readout);
|
|
9904
|
-
center_items.push(camera_button(gobj, "yi-fit", "EV_CENTER", "auto fit", toolbar_wide));
|
|
9905
|
-
center_items.push([
|
|
9906
|
-
"button",
|
|
9907
|
-
{
|
|
9908
|
-
class: "button EV_ZOOM_RESET",
|
|
9909
|
-
type: "button",
|
|
9910
|
-
style: {
|
|
9911
|
-
height: toolbar_wide,
|
|
9912
|
-
width: "2.5em"
|
|
9913
|
-
},
|
|
9914
|
-
title: (0, i18next.t)("actual size"),
|
|
9915
|
-
"data-i18n-title": "actual size",
|
|
9916
|
-
"aria-label": (0, i18next.t)("actual size"),
|
|
9917
|
-
"data-i18n-aria-label": "actual size"
|
|
9918
|
-
},
|
|
9919
|
-
[
|
|
9920
|
-
"span",
|
|
9921
|
-
{ style: "font-weight:700;" },
|
|
9922
|
-
"1:1"
|
|
9923
|
-
],
|
|
9924
|
-
{ click: (evt) => {
|
|
9925
|
-
evt.stopPropagation();
|
|
9926
|
-
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_ZOOM_RESET", { evt }, gobj);
|
|
9927
|
-
} }
|
|
9928
|
-
]);
|
|
9929
|
-
center_items.push(camera_button(gobj, "yi-arrows-rotate", "EV_REFRESH", "refresh", toolbar_wide));
|
|
9959
|
+
center_items = yui_graph_camera_items(gobj, priv.graph, toolbar_wide);
|
|
9960
|
+
center_items.push(yui_graph_refresh_item(gobj, toolbar_wide));
|
|
9930
9961
|
let current_layout = (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "layout") || DEFAULT_LAYOUT;
|
|
9931
9962
|
let options = Object.keys(LAYOUTS$1).map(function(key) {
|
|
9932
9963
|
let attrs = {
|
|
@@ -9940,29 +9971,25 @@ function make_toolbar$3(gobj) {
|
|
|
9940
9971
|
layout_label(key)
|
|
9941
9972
|
];
|
|
9942
9973
|
});
|
|
9943
|
-
let right_items = [
|
|
9944
|
-
|
|
9945
|
-
|
|
9946
|
-
|
|
9947
|
-
|
|
9948
|
-
|
|
9949
|
-
|
|
9950
|
-
"margin-left": "0.5em"
|
|
9951
|
-
},
|
|
9952
|
-
title: (0, i18next.t)("layout"),
|
|
9953
|
-
"data-i18n-title": "layout",
|
|
9954
|
-
"aria-label": (0, i18next.t)("layout"),
|
|
9955
|
-
"data-i18n-aria-label": "layout"
|
|
9974
|
+
let right_items = [(0, _yuneta_gobj_js.createElement2)([
|
|
9975
|
+
"select",
|
|
9976
|
+
{
|
|
9977
|
+
class: "JSON_GRAPH_LAYOUT select",
|
|
9978
|
+
style: {
|
|
9979
|
+
height: toolbar_wide,
|
|
9980
|
+
"margin-left": "0.5em"
|
|
9956
9981
|
},
|
|
9957
|
-
|
|
9958
|
-
|
|
9959
|
-
|
|
9960
|
-
|
|
9961
|
-
|
|
9962
|
-
|
|
9963
|
-
|
|
9964
|
-
|
|
9965
|
-
|
|
9982
|
+
title: (0, i18next.t)("layout"),
|
|
9983
|
+
"data-i18n-title": "layout",
|
|
9984
|
+
"aria-label": (0, i18next.t)("layout"),
|
|
9985
|
+
"data-i18n-aria-label": "layout"
|
|
9986
|
+
},
|
|
9987
|
+
options,
|
|
9988
|
+
{ change: (evt) => {
|
|
9989
|
+
evt.stopPropagation();
|
|
9990
|
+
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_CHANGE_LAYOUT", { layout: evt.target.value }, gobj);
|
|
9991
|
+
} }
|
|
9992
|
+
])].concat(yui_graph_fold_items(gobj, toolbar_wide));
|
|
9966
9993
|
const $toolbar = yui_toolbar({}, [
|
|
9967
9994
|
[
|
|
9968
9995
|
"div",
|
|
@@ -10011,7 +10038,7 @@ function build_graph$3(gobj) {
|
|
|
10011
10038
|
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_NODE_CLICK", { evt }, gobj);
|
|
10012
10039
|
});
|
|
10013
10040
|
graph.on("aftertransform", () => {
|
|
10014
|
-
|
|
10041
|
+
yui_graph_update_zoom((0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container"), priv.graph);
|
|
10015
10042
|
});
|
|
10016
10043
|
graph.on(_antv_g6.CanvasEvent.CLICK, (evt) => {});
|
|
10017
10044
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -10272,7 +10299,7 @@ function load_json(gobj) {
|
|
|
10272
10299
|
});
|
|
10273
10300
|
graph.render().then(() => {
|
|
10274
10301
|
if (!preserve_view) graph.fitView();
|
|
10275
|
-
|
|
10302
|
+
yui_graph_update_zoom((0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container"), priv.graph);
|
|
10276
10303
|
});
|
|
10277
10304
|
}
|
|
10278
10305
|
}
|
|
@@ -12582,74 +12609,8 @@ function make_toolbar$1(gobj) {
|
|
|
12582
12609
|
let left_items = [];
|
|
12583
12610
|
let center_items = [];
|
|
12584
12611
|
let right_items = [];
|
|
12585
|
-
|
|
12586
|
-
|
|
12587
|
-
"yi-magnifying-glass-plus",
|
|
12588
|
-
"EV_ZOOM_IN",
|
|
12589
|
-
false,
|
|
12590
|
-
"i"
|
|
12591
|
-
],
|
|
12592
|
-
[
|
|
12593
|
-
"yi-magnifying-glass",
|
|
12594
|
-
"EV_ZOOM_RESET",
|
|
12595
|
-
false,
|
|
12596
|
-
"i"
|
|
12597
|
-
],
|
|
12598
|
-
[
|
|
12599
|
-
"yi-magnifying-glass-minus",
|
|
12600
|
-
"EV_ZOOM_OUT",
|
|
12601
|
-
false,
|
|
12602
|
-
"i"
|
|
12603
|
-
],
|
|
12604
|
-
[
|
|
12605
|
-
"yi-arrows-to-eye",
|
|
12606
|
-
"EV_CENTER",
|
|
12607
|
-
false,
|
|
12608
|
-
"i"
|
|
12609
|
-
],
|
|
12610
|
-
[
|
|
12611
|
-
"yi-eye",
|
|
12612
|
-
"EV_EXPAND_ALL",
|
|
12613
|
-
false,
|
|
12614
|
-
"i"
|
|
12615
|
-
],
|
|
12616
|
-
[
|
|
12617
|
-
"yi-eye-slash",
|
|
12618
|
-
"EV_COLLAPSE_ALL",
|
|
12619
|
-
false,
|
|
12620
|
-
"i"
|
|
12621
|
-
],
|
|
12622
|
-
[
|
|
12623
|
-
"yi-arrows-rotate",
|
|
12624
|
-
"EV_REFRESH",
|
|
12625
|
-
false,
|
|
12626
|
-
"i"
|
|
12627
|
-
]
|
|
12628
|
-
]) {
|
|
12629
|
-
let icon_name = item[0];
|
|
12630
|
-
let event_name = item[1];
|
|
12631
|
-
let disabled = item[2];
|
|
12632
|
-
let button = {
|
|
12633
|
-
class: `button ${event_name}`,
|
|
12634
|
-
style: {
|
|
12635
|
-
height: toolbar_wide,
|
|
12636
|
-
width: "2.5em"
|
|
12637
|
-
}
|
|
12638
|
-
};
|
|
12639
|
-
if (disabled) button.disabled = true;
|
|
12640
|
-
center_items.push([
|
|
12641
|
-
"button",
|
|
12642
|
-
button,
|
|
12643
|
-
["i", {
|
|
12644
|
-
style: "font-size:1.5em; color:inherit;",
|
|
12645
|
-
class: icon_name
|
|
12646
|
-
}],
|
|
12647
|
-
{ click: (evt) => {
|
|
12648
|
-
evt.stopPropagation();
|
|
12649
|
-
(0, _yuneta_gobj_js.gobj_send_event)(gobj, event_name, { evt }, gobj);
|
|
12650
|
-
} }
|
|
12651
|
-
]);
|
|
12652
|
-
}
|
|
12612
|
+
center_items = yui_graph_camera_items(gobj, priv.graph, toolbar_wide).concat(yui_graph_fold_items(gobj, toolbar_wide));
|
|
12613
|
+
center_items.push(yui_graph_refresh_item(gobj, toolbar_wide));
|
|
12653
12614
|
let options = [];
|
|
12654
12615
|
for (let key of Object.keys(LAYOUTS)) {
|
|
12655
12616
|
let opt_attrs = { value: key };
|
|
@@ -12722,6 +12683,9 @@ function build_graph$2(gobj) {
|
|
|
12722
12683
|
behaviors: ["drag-canvas", "zoom-canvas"]
|
|
12723
12684
|
});
|
|
12724
12685
|
if (priv.theme) graph.setTheme(priv.theme);
|
|
12686
|
+
graph.on("aftertransform", () => {
|
|
12687
|
+
yui_graph_update_zoom((0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container"), priv.graph);
|
|
12688
|
+
});
|
|
12725
12689
|
graph.on(_antv_g6.NodeEvent.CLICK, (evt) => {
|
|
12726
12690
|
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_NODE_CLICK", { evt }, gobj);
|
|
12727
12691
|
});
|
package/dist/gobj-ui.es.js
CHANGED
|
@@ -9345,6 +9345,160 @@ function yui_toolbar(attrs = {}, items = []) {
|
|
|
9345
9345
|
return $toolbar;
|
|
9346
9346
|
}
|
|
9347
9347
|
//#endregion
|
|
9348
|
+
//#region src/yui_graph_camera.js
|
|
9349
|
+
/***********************************************************************
|
|
9350
|
+
* yui_graph_camera.js
|
|
9351
|
+
*
|
|
9352
|
+
* The camera and fold controls a G6 graph puts in a DOM toolbar,
|
|
9353
|
+
* built in ONE place.
|
|
9354
|
+
*
|
|
9355
|
+
* This module exists because the same action was drawn three
|
|
9356
|
+
* different ways across sibling views — actual size as a bare
|
|
9357
|
+
* magnifier here and as `1:1` there, fit as `arrows-to-eye` here and
|
|
9358
|
+
* as corner brackets there, fold as chevrons here and as an eye
|
|
9359
|
+
* there. A user sees two of these graphs side by side in the same
|
|
9360
|
+
* console, so a copied-and-drifted toolbar is not a detail.
|
|
9361
|
+
*
|
|
9362
|
+
* The VOCABULARY is not invented here. It is the one
|
|
9363
|
+
* `c_g6_nodes_tree.js` settled on for the treedb graph, which draws
|
|
9364
|
+
* its toolbar as a G6 plugin over an SVG sprite and therefore cannot
|
|
9365
|
+
* share this code — only its decisions:
|
|
9366
|
+
*
|
|
9367
|
+
* zoom in / zoom out magnifiers
|
|
9368
|
+
* zoom level a READOUT, because without it "1:1" is
|
|
9369
|
+
* a jump to a value nobody was told
|
|
9370
|
+
* fit corner brackets (`yi-fit`, the same
|
|
9371
|
+
* path as the sprite's `g6-icon-fit`)
|
|
9372
|
+
* actual size the WRITTEN `1:1` — the action is
|
|
9373
|
+
* `zoomTo(1)`, and actual size is written
|
|
9374
|
+
* in every editor that offers it, never
|
|
9375
|
+
* drawn, because there is no glyph for it
|
|
9376
|
+
*
|
|
9377
|
+
* Fold is the one the treedb graph does not have, so its vocabulary
|
|
9378
|
+
* comes from the other side of the family: the lazy tree viewer's own
|
|
9379
|
+
* toolbar (`c_yui_json.js`) uses chevrons — open pointing down, closed
|
|
9380
|
+
* pointing right — which is also the direction the per-node handles
|
|
9381
|
+
* speak. An eye means show/hide, which is a different idea.
|
|
9382
|
+
*
|
|
9383
|
+
* Copyright (c) 2026, ArtGins.
|
|
9384
|
+
* All Rights Reserved.
|
|
9385
|
+
***********************************************************************/
|
|
9386
|
+
/************************************************************
|
|
9387
|
+
* One icon button that fires `event_name`.
|
|
9388
|
+
************************************************************/
|
|
9389
|
+
function camera_button(gobj, icon, event_name, label_key, wide, extra_style) {
|
|
9390
|
+
return [
|
|
9391
|
+
"button",
|
|
9392
|
+
{
|
|
9393
|
+
class: `button ${event_name}`,
|
|
9394
|
+
type: "button",
|
|
9395
|
+
style: {
|
|
9396
|
+
height: wide,
|
|
9397
|
+
width: "2.5em"
|
|
9398
|
+
},
|
|
9399
|
+
title: t(label_key),
|
|
9400
|
+
"data-i18n-title": label_key,
|
|
9401
|
+
"aria-label": t(label_key),
|
|
9402
|
+
"data-i18n-aria-label": label_key
|
|
9403
|
+
},
|
|
9404
|
+
["i", {
|
|
9405
|
+
style: "font-size:1.5em; color:inherit;" + (extra_style || ""),
|
|
9406
|
+
class: icon
|
|
9407
|
+
}],
|
|
9408
|
+
{ click: (evt) => {
|
|
9409
|
+
evt.stopPropagation();
|
|
9410
|
+
gobj_send_event(gobj, event_name, { evt }, gobj);
|
|
9411
|
+
} }
|
|
9412
|
+
];
|
|
9413
|
+
}
|
|
9414
|
+
/************************************************************
|
|
9415
|
+
* The current zoom as a percentage.
|
|
9416
|
+
************************************************************/
|
|
9417
|
+
function yui_graph_zoom_text(graph) {
|
|
9418
|
+
if (!graph) return "100%";
|
|
9419
|
+
try {
|
|
9420
|
+
return Math.round(graph.getZoom() * 100) + "%";
|
|
9421
|
+
} catch (e) {
|
|
9422
|
+
return "100%";
|
|
9423
|
+
}
|
|
9424
|
+
}
|
|
9425
|
+
/************************************************************
|
|
9426
|
+
* Repaint the readout of a container that carries one.
|
|
9427
|
+
*
|
|
9428
|
+
* Call it from G6's `aftertransform`, which is the ONE hook
|
|
9429
|
+
* that also covers the WHEEL — a camera change that passes
|
|
9430
|
+
* through no action, so repainting from each zoom action
|
|
9431
|
+
* leaves the number lying after every notch.
|
|
9432
|
+
************************************************************/
|
|
9433
|
+
function yui_graph_update_zoom($container, graph) {
|
|
9434
|
+
if (!$container) return;
|
|
9435
|
+
let $readout = $container.querySelector(".GRAPH_ZOOM_LEVEL");
|
|
9436
|
+
if (!$readout) return;
|
|
9437
|
+
$readout.textContent = yui_graph_zoom_text(graph);
|
|
9438
|
+
}
|
|
9439
|
+
/************************************************************
|
|
9440
|
+
* The camera cluster: zoom in, zoom out, readout, fit,
|
|
9441
|
+
* actual size. Returns createElement2 specs, in order.
|
|
9442
|
+
*
|
|
9443
|
+
* `wide` is the host toolbar's button height.
|
|
9444
|
+
************************************************************/
|
|
9445
|
+
function yui_graph_camera_items(gobj, graph, wide) {
|
|
9446
|
+
return [
|
|
9447
|
+
camera_button(gobj, "yi-magnifying-glass-plus", "EV_ZOOM_IN", "zoom in", wide),
|
|
9448
|
+
camera_button(gobj, "yi-magnifying-glass-minus", "EV_ZOOM_OUT", "zoom out", wide),
|
|
9449
|
+
[
|
|
9450
|
+
"span",
|
|
9451
|
+
{
|
|
9452
|
+
class: "GRAPH_ZOOM_LEVEL is-flex is-align-items-center px-2 has-text-grey",
|
|
9453
|
+
style: "font-size:.85rem; min-width:3.5em; justify-content:center;",
|
|
9454
|
+
title: t("zoom level"),
|
|
9455
|
+
"data-i18n-title": "zoom level"
|
|
9456
|
+
},
|
|
9457
|
+
yui_graph_zoom_text(graph)
|
|
9458
|
+
],
|
|
9459
|
+
camera_button(gobj, "yi-fit", "EV_CENTER", "auto fit", wide),
|
|
9460
|
+
[
|
|
9461
|
+
"button",
|
|
9462
|
+
{
|
|
9463
|
+
class: "button EV_ZOOM_RESET",
|
|
9464
|
+
type: "button",
|
|
9465
|
+
style: {
|
|
9466
|
+
height: wide,
|
|
9467
|
+
width: "2.5em"
|
|
9468
|
+
},
|
|
9469
|
+
title: t("actual size"),
|
|
9470
|
+
"data-i18n-title": "actual size",
|
|
9471
|
+
"aria-label": t("actual size"),
|
|
9472
|
+
"data-i18n-aria-label": "actual size"
|
|
9473
|
+
},
|
|
9474
|
+
[
|
|
9475
|
+
"span",
|
|
9476
|
+
{ style: "font-weight:700;" },
|
|
9477
|
+
"1:1"
|
|
9478
|
+
],
|
|
9479
|
+
{ click: (evt) => {
|
|
9480
|
+
evt.stopPropagation();
|
|
9481
|
+
gobj_send_event(gobj, "EV_ZOOM_RESET", { evt }, gobj);
|
|
9482
|
+
} }
|
|
9483
|
+
]
|
|
9484
|
+
];
|
|
9485
|
+
}
|
|
9486
|
+
/************************************************************
|
|
9487
|
+
* The fold pair: expand all, collapse all. Chevrons, the
|
|
9488
|
+
* open one rotated down — the same pair the lazy tree
|
|
9489
|
+
* viewer's toolbar uses, and the same direction the
|
|
9490
|
+
* per-node handles speak.
|
|
9491
|
+
************************************************************/
|
|
9492
|
+
function yui_graph_fold_items(gobj, wide) {
|
|
9493
|
+
return [camera_button(gobj, "yi-chevron-right", "EV_EXPAND_ALL", "expand all", wide, " transform: rotate(90deg);"), camera_button(gobj, "yi-chevron-right", "EV_COLLAPSE_ALL", "collapse all", wide)];
|
|
9494
|
+
}
|
|
9495
|
+
/************************************************************
|
|
9496
|
+
* A refresh button, for the graphs that offer one.
|
|
9497
|
+
************************************************************/
|
|
9498
|
+
function yui_graph_refresh_item(gobj, wide) {
|
|
9499
|
+
return camera_button(gobj, "yi-arrows-rotate", "EV_REFRESH", "refresh", wide);
|
|
9500
|
+
}
|
|
9501
|
+
//#endregion
|
|
9348
9502
|
//#region src/g6_drag_canvas_touch.js
|
|
9349
9503
|
/***********************************************************************
|
|
9350
9504
|
* g6_drag_canvas_touch.js
|
|
@@ -9551,7 +9705,6 @@ var PRIVATE_DATA$11 = {
|
|
|
9551
9705
|
find_timer: null,
|
|
9552
9706
|
fold_listener: null,
|
|
9553
9707
|
$layout_select: null,
|
|
9554
|
-
$zoom_readout: null,
|
|
9555
9708
|
$find_input: null,
|
|
9556
9709
|
$find_result: null,
|
|
9557
9710
|
$find_count: null
|
|
@@ -9749,84 +9902,6 @@ function destroy_ui$6(gobj) {
|
|
|
9749
9902
|
}
|
|
9750
9903
|
}
|
|
9751
9904
|
/************************************************************
|
|
9752
|
-
* One camera button.
|
|
9753
|
-
************************************************************/
|
|
9754
|
-
function camera_button(gobj, icon, event_name, label_key, wide) {
|
|
9755
|
-
return [
|
|
9756
|
-
"button",
|
|
9757
|
-
{
|
|
9758
|
-
class: `button ${event_name}`,
|
|
9759
|
-
type: "button",
|
|
9760
|
-
style: {
|
|
9761
|
-
height: wide,
|
|
9762
|
-
width: "2.5em"
|
|
9763
|
-
},
|
|
9764
|
-
title: t(label_key),
|
|
9765
|
-
"data-i18n-title": label_key,
|
|
9766
|
-
"aria-label": t(label_key),
|
|
9767
|
-
"data-i18n-aria-label": label_key
|
|
9768
|
-
},
|
|
9769
|
-
["i", {
|
|
9770
|
-
style: "font-size:1.5em; color:inherit;",
|
|
9771
|
-
class: icon
|
|
9772
|
-
}],
|
|
9773
|
-
{ click: (evt) => {
|
|
9774
|
-
evt.stopPropagation();
|
|
9775
|
-
gobj_send_event(gobj, event_name, { evt }, gobj);
|
|
9776
|
-
} }
|
|
9777
|
-
];
|
|
9778
|
-
}
|
|
9779
|
-
/************************************************************
|
|
9780
|
-
* The zoom, as a percentage. What the two magnifiers
|
|
9781
|
-
* change: an editor that offers a zoom shows the number.
|
|
9782
|
-
************************************************************/
|
|
9783
|
-
function zoom_percent_text$1(gobj) {
|
|
9784
|
-
let graph = gobj.priv.graph;
|
|
9785
|
-
if (!graph) return "100%";
|
|
9786
|
-
try {
|
|
9787
|
-
return Math.round(graph.getZoom() * 100) + "%";
|
|
9788
|
-
} catch (e) {
|
|
9789
|
-
return "100%";
|
|
9790
|
-
}
|
|
9791
|
-
}
|
|
9792
|
-
/************************************************************
|
|
9793
|
-
* Repaint the readout after anything that moves the camera.
|
|
9794
|
-
************************************************************/
|
|
9795
|
-
function update_zoom_readout$1(gobj) {
|
|
9796
|
-
let priv = gobj.priv;
|
|
9797
|
-
if (priv.$zoom_readout) priv.$zoom_readout.textContent = zoom_percent_text$1(gobj);
|
|
9798
|
-
}
|
|
9799
|
-
/************************************************************
|
|
9800
|
-
* One fold button. `open` rotates the chevron to the open
|
|
9801
|
-
* state, mirroring the per-node toggle of the lazy tree.
|
|
9802
|
-
************************************************************/
|
|
9803
|
-
function graph_fold_button(gobj, event_name, label_key, open) {
|
|
9804
|
-
let icon_style = "font-size:1.5em; color:inherit;" + (open ? " transform: rotate(90deg);" : "");
|
|
9805
|
-
return [
|
|
9806
|
-
"button",
|
|
9807
|
-
{
|
|
9808
|
-
class: `button ${event_name}`,
|
|
9809
|
-
type: "button",
|
|
9810
|
-
style: {
|
|
9811
|
-
height: gobj_read_attr(gobj, "wide"),
|
|
9812
|
-
width: "2.5em"
|
|
9813
|
-
},
|
|
9814
|
-
title: t(label_key),
|
|
9815
|
-
"data-i18n-title": label_key,
|
|
9816
|
-
"aria-label": t(label_key),
|
|
9817
|
-
"data-i18n-aria-label": label_key
|
|
9818
|
-
},
|
|
9819
|
-
["i", {
|
|
9820
|
-
style: icon_style,
|
|
9821
|
-
class: "yi-chevron-right"
|
|
9822
|
-
}],
|
|
9823
|
-
{ click: (evt) => {
|
|
9824
|
-
evt.stopPropagation();
|
|
9825
|
-
gobj_send_event(gobj, event_name, {}, gobj);
|
|
9826
|
-
} }
|
|
9827
|
-
];
|
|
9828
|
-
}
|
|
9829
|
-
/************************************************************
|
|
9830
9905
|
* Toolbar
|
|
9831
9906
|
************************************************************/
|
|
9832
9907
|
function make_toolbar$3(gobj) {
|
|
@@ -9876,52 +9951,8 @@ function make_toolbar$3(gobj) {
|
|
|
9876
9951
|
]]
|
|
9877
9952
|
]];
|
|
9878
9953
|
let center_items = [];
|
|
9879
|
-
|
|
9880
|
-
|
|
9881
|
-
"EV_ZOOM_IN",
|
|
9882
|
-
"zoom in"
|
|
9883
|
-
], [
|
|
9884
|
-
"yi-magnifying-glass-minus",
|
|
9885
|
-
"EV_ZOOM_OUT",
|
|
9886
|
-
"zoom out"
|
|
9887
|
-
]]) center_items.push(camera_button(gobj, item[0], item[1], item[2], toolbar_wide));
|
|
9888
|
-
priv.$zoom_readout = createElement2([
|
|
9889
|
-
"span",
|
|
9890
|
-
{
|
|
9891
|
-
class: "JSON_GRAPH_ZOOM_LEVEL is-flex is-align-items-center px-2 has-text-grey",
|
|
9892
|
-
style: "font-size:.85rem; min-width:3.5em; justify-content:center;",
|
|
9893
|
-
title: t("zoom level"),
|
|
9894
|
-
"data-i18n-title": "zoom level"
|
|
9895
|
-
},
|
|
9896
|
-
zoom_percent_text$1(gobj)
|
|
9897
|
-
]);
|
|
9898
|
-
center_items.push(priv.$zoom_readout);
|
|
9899
|
-
center_items.push(camera_button(gobj, "yi-fit", "EV_CENTER", "auto fit", toolbar_wide));
|
|
9900
|
-
center_items.push([
|
|
9901
|
-
"button",
|
|
9902
|
-
{
|
|
9903
|
-
class: "button EV_ZOOM_RESET",
|
|
9904
|
-
type: "button",
|
|
9905
|
-
style: {
|
|
9906
|
-
height: toolbar_wide,
|
|
9907
|
-
width: "2.5em"
|
|
9908
|
-
},
|
|
9909
|
-
title: t("actual size"),
|
|
9910
|
-
"data-i18n-title": "actual size",
|
|
9911
|
-
"aria-label": t("actual size"),
|
|
9912
|
-
"data-i18n-aria-label": "actual size"
|
|
9913
|
-
},
|
|
9914
|
-
[
|
|
9915
|
-
"span",
|
|
9916
|
-
{ style: "font-weight:700;" },
|
|
9917
|
-
"1:1"
|
|
9918
|
-
],
|
|
9919
|
-
{ click: (evt) => {
|
|
9920
|
-
evt.stopPropagation();
|
|
9921
|
-
gobj_send_event(gobj, "EV_ZOOM_RESET", { evt }, gobj);
|
|
9922
|
-
} }
|
|
9923
|
-
]);
|
|
9924
|
-
center_items.push(camera_button(gobj, "yi-arrows-rotate", "EV_REFRESH", "refresh", toolbar_wide));
|
|
9954
|
+
center_items = yui_graph_camera_items(gobj, priv.graph, toolbar_wide);
|
|
9955
|
+
center_items.push(yui_graph_refresh_item(gobj, toolbar_wide));
|
|
9925
9956
|
let current_layout = gobj_read_str_attr(gobj, "layout") || DEFAULT_LAYOUT;
|
|
9926
9957
|
let options = Object.keys(LAYOUTS$1).map(function(key) {
|
|
9927
9958
|
let attrs = {
|
|
@@ -9935,29 +9966,25 @@ function make_toolbar$3(gobj) {
|
|
|
9935
9966
|
layout_label(key)
|
|
9936
9967
|
];
|
|
9937
9968
|
});
|
|
9938
|
-
let right_items = [
|
|
9939
|
-
|
|
9940
|
-
|
|
9941
|
-
|
|
9942
|
-
|
|
9943
|
-
|
|
9944
|
-
|
|
9945
|
-
"margin-left": "0.5em"
|
|
9946
|
-
},
|
|
9947
|
-
title: t("layout"),
|
|
9948
|
-
"data-i18n-title": "layout",
|
|
9949
|
-
"aria-label": t("layout"),
|
|
9950
|
-
"data-i18n-aria-label": "layout"
|
|
9969
|
+
let right_items = [createElement2([
|
|
9970
|
+
"select",
|
|
9971
|
+
{
|
|
9972
|
+
class: "JSON_GRAPH_LAYOUT select",
|
|
9973
|
+
style: {
|
|
9974
|
+
height: toolbar_wide,
|
|
9975
|
+
"margin-left": "0.5em"
|
|
9951
9976
|
},
|
|
9952
|
-
|
|
9953
|
-
|
|
9954
|
-
|
|
9955
|
-
|
|
9956
|
-
|
|
9957
|
-
|
|
9958
|
-
|
|
9959
|
-
|
|
9960
|
-
|
|
9977
|
+
title: t("layout"),
|
|
9978
|
+
"data-i18n-title": "layout",
|
|
9979
|
+
"aria-label": t("layout"),
|
|
9980
|
+
"data-i18n-aria-label": "layout"
|
|
9981
|
+
},
|
|
9982
|
+
options,
|
|
9983
|
+
{ change: (evt) => {
|
|
9984
|
+
evt.stopPropagation();
|
|
9985
|
+
gobj_send_event(gobj, "EV_CHANGE_LAYOUT", { layout: evt.target.value }, gobj);
|
|
9986
|
+
} }
|
|
9987
|
+
])].concat(yui_graph_fold_items(gobj, toolbar_wide));
|
|
9961
9988
|
const $toolbar = yui_toolbar({}, [
|
|
9962
9989
|
[
|
|
9963
9990
|
"div",
|
|
@@ -10006,7 +10033,7 @@ function build_graph$3(gobj) {
|
|
|
10006
10033
|
gobj_send_event(gobj, "EV_NODE_CLICK", { evt }, gobj);
|
|
10007
10034
|
});
|
|
10008
10035
|
graph.on("aftertransform", () => {
|
|
10009
|
-
|
|
10036
|
+
yui_graph_update_zoom(gobj_read_attr(gobj, "$container"), priv.graph);
|
|
10010
10037
|
});
|
|
10011
10038
|
graph.on(CanvasEvent.CLICK, (evt) => {});
|
|
10012
10039
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -10267,7 +10294,7 @@ function load_json(gobj) {
|
|
|
10267
10294
|
});
|
|
10268
10295
|
graph.render().then(() => {
|
|
10269
10296
|
if (!preserve_view) graph.fitView();
|
|
10270
|
-
|
|
10297
|
+
yui_graph_update_zoom(gobj_read_attr(gobj, "$container"), priv.graph);
|
|
10271
10298
|
});
|
|
10272
10299
|
}
|
|
10273
10300
|
}
|
|
@@ -12577,74 +12604,8 @@ function make_toolbar$1(gobj) {
|
|
|
12577
12604
|
let left_items = [];
|
|
12578
12605
|
let center_items = [];
|
|
12579
12606
|
let right_items = [];
|
|
12580
|
-
|
|
12581
|
-
|
|
12582
|
-
"yi-magnifying-glass-plus",
|
|
12583
|
-
"EV_ZOOM_IN",
|
|
12584
|
-
false,
|
|
12585
|
-
"i"
|
|
12586
|
-
],
|
|
12587
|
-
[
|
|
12588
|
-
"yi-magnifying-glass",
|
|
12589
|
-
"EV_ZOOM_RESET",
|
|
12590
|
-
false,
|
|
12591
|
-
"i"
|
|
12592
|
-
],
|
|
12593
|
-
[
|
|
12594
|
-
"yi-magnifying-glass-minus",
|
|
12595
|
-
"EV_ZOOM_OUT",
|
|
12596
|
-
false,
|
|
12597
|
-
"i"
|
|
12598
|
-
],
|
|
12599
|
-
[
|
|
12600
|
-
"yi-arrows-to-eye",
|
|
12601
|
-
"EV_CENTER",
|
|
12602
|
-
false,
|
|
12603
|
-
"i"
|
|
12604
|
-
],
|
|
12605
|
-
[
|
|
12606
|
-
"yi-eye",
|
|
12607
|
-
"EV_EXPAND_ALL",
|
|
12608
|
-
false,
|
|
12609
|
-
"i"
|
|
12610
|
-
],
|
|
12611
|
-
[
|
|
12612
|
-
"yi-eye-slash",
|
|
12613
|
-
"EV_COLLAPSE_ALL",
|
|
12614
|
-
false,
|
|
12615
|
-
"i"
|
|
12616
|
-
],
|
|
12617
|
-
[
|
|
12618
|
-
"yi-arrows-rotate",
|
|
12619
|
-
"EV_REFRESH",
|
|
12620
|
-
false,
|
|
12621
|
-
"i"
|
|
12622
|
-
]
|
|
12623
|
-
]) {
|
|
12624
|
-
let icon_name = item[0];
|
|
12625
|
-
let event_name = item[1];
|
|
12626
|
-
let disabled = item[2];
|
|
12627
|
-
let button = {
|
|
12628
|
-
class: `button ${event_name}`,
|
|
12629
|
-
style: {
|
|
12630
|
-
height: toolbar_wide,
|
|
12631
|
-
width: "2.5em"
|
|
12632
|
-
}
|
|
12633
|
-
};
|
|
12634
|
-
if (disabled) button.disabled = true;
|
|
12635
|
-
center_items.push([
|
|
12636
|
-
"button",
|
|
12637
|
-
button,
|
|
12638
|
-
["i", {
|
|
12639
|
-
style: "font-size:1.5em; color:inherit;",
|
|
12640
|
-
class: icon_name
|
|
12641
|
-
}],
|
|
12642
|
-
{ click: (evt) => {
|
|
12643
|
-
evt.stopPropagation();
|
|
12644
|
-
gobj_send_event(gobj, event_name, { evt }, gobj);
|
|
12645
|
-
} }
|
|
12646
|
-
]);
|
|
12647
|
-
}
|
|
12607
|
+
center_items = yui_graph_camera_items(gobj, priv.graph, toolbar_wide).concat(yui_graph_fold_items(gobj, toolbar_wide));
|
|
12608
|
+
center_items.push(yui_graph_refresh_item(gobj, toolbar_wide));
|
|
12648
12609
|
let options = [];
|
|
12649
12610
|
for (let key of Object.keys(LAYOUTS)) {
|
|
12650
12611
|
let opt_attrs = { value: key };
|
|
@@ -12717,6 +12678,9 @@ function build_graph$2(gobj) {
|
|
|
12717
12678
|
behaviors: ["drag-canvas", "zoom-canvas"]
|
|
12718
12679
|
});
|
|
12719
12680
|
if (priv.theme) graph.setTheme(priv.theme);
|
|
12681
|
+
graph.on("aftertransform", () => {
|
|
12682
|
+
yui_graph_update_zoom(gobj_read_attr(gobj, "$container"), priv.graph);
|
|
12683
|
+
});
|
|
12720
12684
|
graph.on(NodeEvent.CLICK, (evt) => {
|
|
12721
12685
|
gobj_send_event(gobj, "EV_NODE_CLICK", { evt }, gobj);
|
|
12722
12686
|
});
|
package/package.json
CHANGED
|
@@ -40,6 +40,12 @@ import {
|
|
|
40
40
|
} from "@yuneta/gobj-js";
|
|
41
41
|
|
|
42
42
|
import {yui_toolbar} from "./yui_toolbar.js";
|
|
43
|
+
import {
|
|
44
|
+
yui_graph_camera_items,
|
|
45
|
+
yui_graph_fold_items,
|
|
46
|
+
yui_graph_refresh_item,
|
|
47
|
+
yui_graph_update_zoom,
|
|
48
|
+
} from "./yui_graph_camera.js";
|
|
43
49
|
|
|
44
50
|
import {t} from "i18next";
|
|
45
51
|
|
|
@@ -535,40 +541,18 @@ function make_toolbar(gobj)
|
|
|
535
541
|
let center_items = [];
|
|
536
542
|
let right_items = [];
|
|
537
543
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
let event_name = item[1];
|
|
551
|
-
let disabled = item[2];
|
|
552
|
-
|
|
553
|
-
let button = {
|
|
554
|
-
class: `button ${event_name}`,
|
|
555
|
-
style: {height: toolbar_wide, width: '2.5em'}
|
|
556
|
-
};
|
|
557
|
-
if(disabled) {
|
|
558
|
-
button.disabled = true;
|
|
559
|
-
}
|
|
560
|
-
center_items.push(
|
|
561
|
-
['button', button,
|
|
562
|
-
['i', {style: 'font-size:1.5em; color:inherit;', class: icon_name}],
|
|
563
|
-
{
|
|
564
|
-
click: (evt) => {
|
|
565
|
-
evt.stopPropagation();
|
|
566
|
-
gobj_send_event(gobj, event_name, {evt: evt}, gobj);
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
]
|
|
570
|
-
);
|
|
571
|
-
}
|
|
544
|
+
/*
|
|
545
|
+
* The camera and the fold pair come from yui_graph_camera.js.
|
|
546
|
+
*
|
|
547
|
+
* This toolbar used to draw two of these its own way — a bare
|
|
548
|
+
* magnifier for actual size, `arrows-to-eye` for fit — and fold as
|
|
549
|
+
* an eye, which means show/hide and not open/closed. The same
|
|
550
|
+
* console shows this graph and the JSON one side by side, so the
|
|
551
|
+
* drawings have to be the same drawings.
|
|
552
|
+
*/
|
|
553
|
+
center_items = yui_graph_camera_items(gobj, priv.graph, toolbar_wide)
|
|
554
|
+
.concat(yui_graph_fold_items(gobj, toolbar_wide));
|
|
555
|
+
center_items.push(yui_graph_refresh_item(gobj, toolbar_wide));
|
|
572
556
|
|
|
573
557
|
/*
|
|
574
558
|
* Layout selector
|
|
@@ -651,6 +635,12 @@ function build_graph(gobj)
|
|
|
651
635
|
graph.setTheme(priv.theme);
|
|
652
636
|
}
|
|
653
637
|
|
|
638
|
+
/* The readout follows ANY camera change, the wheel included — a
|
|
639
|
+
* wheel notch passes through no action of ours. */
|
|
640
|
+
graph.on('aftertransform', () => {
|
|
641
|
+
yui_graph_update_zoom(gobj_read_attr(gobj, "$container"), priv.graph);
|
|
642
|
+
});
|
|
643
|
+
|
|
654
644
|
graph.on(NodeEvent.CLICK, (evt) => {
|
|
655
645
|
gobj_send_event(gobj, "EV_NODE_CLICK", {evt: evt}, gobj);
|
|
656
646
|
});
|
package/src/c_yui_json_graph.js
CHANGED
|
@@ -47,6 +47,12 @@ import {
|
|
|
47
47
|
} from "@yuneta/gobj-js";
|
|
48
48
|
|
|
49
49
|
import {yui_toolbar} from "./yui_toolbar.js";
|
|
50
|
+
import {
|
|
51
|
+
yui_graph_camera_items,
|
|
52
|
+
yui_graph_fold_items,
|
|
53
|
+
yui_graph_refresh_item,
|
|
54
|
+
yui_graph_update_zoom,
|
|
55
|
+
} from "./yui_graph_camera.js";
|
|
50
56
|
|
|
51
57
|
import {t} from "i18next";
|
|
52
58
|
|
|
@@ -179,7 +185,6 @@ let PRIVATE_DATA = {
|
|
|
179
185
|
find_timer: null, // rate-limits the find box
|
|
180
186
|
fold_listener: null, // delegated click on the card fold handles
|
|
181
187
|
$layout_select: null, // the layout picker
|
|
182
|
-
$zoom_readout: null, // the zoom percentage
|
|
183
188
|
$find_input: null,
|
|
184
189
|
$find_result: null,
|
|
185
190
|
$find_count: null,
|
|
@@ -455,77 +460,6 @@ function destroy_ui(gobj)
|
|
|
455
460
|
}
|
|
456
461
|
}
|
|
457
462
|
|
|
458
|
-
/************************************************************
|
|
459
|
-
* One camera button.
|
|
460
|
-
************************************************************/
|
|
461
|
-
function camera_button(gobj, icon, event_name, label_key, wide)
|
|
462
|
-
{
|
|
463
|
-
return ['button', {class: `button ${event_name}`, type: 'button',
|
|
464
|
-
style: {height: wide, width: '2.5em'},
|
|
465
|
-
title: t(label_key), 'data-i18n-title': label_key,
|
|
466
|
-
'aria-label': t(label_key), 'data-i18n-aria-label': label_key},
|
|
467
|
-
['i', {style: 'font-size:1.5em; color:inherit;', class: icon}],
|
|
468
|
-
{
|
|
469
|
-
click: (evt) => {
|
|
470
|
-
evt.stopPropagation();
|
|
471
|
-
gobj_send_event(gobj, event_name, {evt: evt}, gobj);
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
];
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
/************************************************************
|
|
478
|
-
* The zoom, as a percentage. What the two magnifiers
|
|
479
|
-
* change: an editor that offers a zoom shows the number.
|
|
480
|
-
************************************************************/
|
|
481
|
-
function zoom_percent_text(gobj)
|
|
482
|
-
{
|
|
483
|
-
let graph = gobj.priv.graph;
|
|
484
|
-
if(!graph) {
|
|
485
|
-
return "100%";
|
|
486
|
-
}
|
|
487
|
-
try {
|
|
488
|
-
return Math.round(graph.getZoom() * 100) + "%";
|
|
489
|
-
} catch(e) {
|
|
490
|
-
return "100%";
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
/************************************************************
|
|
495
|
-
* Repaint the readout after anything that moves the camera.
|
|
496
|
-
************************************************************/
|
|
497
|
-
function update_zoom_readout(gobj)
|
|
498
|
-
{
|
|
499
|
-
let priv = gobj.priv;
|
|
500
|
-
if(priv.$zoom_readout) {
|
|
501
|
-
priv.$zoom_readout.textContent = zoom_percent_text(gobj);
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
/************************************************************
|
|
506
|
-
* One fold button. `open` rotates the chevron to the open
|
|
507
|
-
* state, mirroring the per-node toggle of the lazy tree.
|
|
508
|
-
************************************************************/
|
|
509
|
-
function graph_fold_button(gobj, event_name, label_key, open)
|
|
510
|
-
{
|
|
511
|
-
let icon_style = 'font-size:1.5em; color:inherit;' +
|
|
512
|
-
(open? ' transform: rotate(90deg);': '');
|
|
513
|
-
|
|
514
|
-
return ['button', {class: `button ${event_name}`,
|
|
515
|
-
type: 'button',
|
|
516
|
-
style: {height: gobj_read_attr(gobj, "wide"), width: '2.5em'},
|
|
517
|
-
title: t(label_key), 'data-i18n-title': label_key,
|
|
518
|
-
'aria-label': t(label_key), 'data-i18n-aria-label': label_key},
|
|
519
|
-
['i', {style: icon_style, class: 'yi-chevron-right'}],
|
|
520
|
-
{
|
|
521
|
-
click: (evt) => {
|
|
522
|
-
evt.stopPropagation();
|
|
523
|
-
gobj_send_event(gobj, event_name, {}, gobj);
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
];
|
|
527
|
-
}
|
|
528
|
-
|
|
529
463
|
/************************************************************
|
|
530
464
|
* Toolbar
|
|
531
465
|
************************************************************/
|
|
@@ -593,54 +527,12 @@ function make_toolbar(gobj)
|
|
|
593
527
|
let center_items = [];
|
|
594
528
|
|
|
595
529
|
/*
|
|
596
|
-
* The camera
|
|
597
|
-
*
|
|
598
|
-
*
|
|
599
|
-
* a value nobody was told — then fit, then actual size.
|
|
600
|
-
*
|
|
601
|
-
* Two of these used to be a different picture for the same action
|
|
602
|
-
* in a sibling view, which is the worst thing an icon can be:
|
|
603
|
-
* `EV_ZOOM_RESET` was a bare magnifier and `EV_CENTER` was
|
|
604
|
-
* `yi-arrows-to-eye`. Now fit is the same bracket glyph as the
|
|
605
|
-
* sprite's `g6-icon-fit`, and actual size is WRITTEN — `1:1` is
|
|
606
|
-
* written in every editor that offers it, never drawn, because
|
|
607
|
-
* there is no glyph for it.
|
|
530
|
+
* The camera and the fold pair come from yui_graph_camera.js: the
|
|
531
|
+
* same drawings the gobj tree uses, because the two graphs sit in
|
|
532
|
+
* the same console and a copied toolbar drifts.
|
|
608
533
|
*/
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
["yi-magnifying-glass-minus", "EV_ZOOM_OUT", "zoom out"],
|
|
612
|
-
];
|
|
613
|
-
|
|
614
|
-
for(let item of c_icons) {
|
|
615
|
-
center_items.push(camera_button(gobj, item[0], item[1], item[2], toolbar_wide));
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
priv.$zoom_readout = createElement2(
|
|
619
|
-
['span', {class: 'JSON_GRAPH_ZOOM_LEVEL is-flex is-align-items-center px-2 has-text-grey',
|
|
620
|
-
style: 'font-size:.85rem; min-width:3.5em; justify-content:center;',
|
|
621
|
-
title: t('zoom level'), 'data-i18n-title': 'zoom level'},
|
|
622
|
-
zoom_percent_text(gobj)]
|
|
623
|
-
);
|
|
624
|
-
center_items.push(priv.$zoom_readout);
|
|
625
|
-
|
|
626
|
-
center_items.push(camera_button(gobj, "yi-fit", "EV_CENTER", "auto fit", toolbar_wide));
|
|
627
|
-
|
|
628
|
-
/* Written, not drawn — see above. */
|
|
629
|
-
center_items.push(
|
|
630
|
-
['button', {class: 'button EV_ZOOM_RESET', type: 'button',
|
|
631
|
-
style: {height: toolbar_wide, width: '2.5em'},
|
|
632
|
-
title: t('actual size'), 'data-i18n-title': 'actual size',
|
|
633
|
-
'aria-label': t('actual size'), 'data-i18n-aria-label': 'actual size'},
|
|
634
|
-
['span', {style: 'font-weight:700;'}, '1:1'],
|
|
635
|
-
{
|
|
636
|
-
click: (evt) => {
|
|
637
|
-
evt.stopPropagation();
|
|
638
|
-
gobj_send_event(gobj, "EV_ZOOM_RESET", {evt: evt}, gobj);
|
|
639
|
-
}
|
|
640
|
-
}]
|
|
641
|
-
);
|
|
642
|
-
|
|
643
|
-
center_items.push(camera_button(gobj, "yi-arrows-rotate", "EV_REFRESH", "refresh", toolbar_wide));
|
|
534
|
+
center_items = yui_graph_camera_items(gobj, priv.graph, toolbar_wide);
|
|
535
|
+
center_items.push(yui_graph_refresh_item(gobj, toolbar_wide));
|
|
644
536
|
|
|
645
537
|
/*
|
|
646
538
|
* Right: fold the tree.
|
|
@@ -681,11 +573,8 @@ function make_toolbar(gobj)
|
|
|
681
573
|
}]
|
|
682
574
|
);
|
|
683
575
|
|
|
684
|
-
let right_items = [
|
|
685
|
-
|
|
686
|
-
graph_fold_button(gobj, "EV_EXPAND_ALL", "expand all", true),
|
|
687
|
-
graph_fold_button(gobj, "EV_COLLAPSE_ALL", "collapse all", false),
|
|
688
|
-
];
|
|
576
|
+
let right_items = [$layout_select].concat(
|
|
577
|
+
yui_graph_fold_items(gobj, toolbar_wide));
|
|
689
578
|
|
|
690
579
|
const $toolbar = yui_toolbar({}, [
|
|
691
580
|
['div', {class: 'yui-horizontal-toolbar-section left'}, left_items],
|
|
@@ -748,7 +637,7 @@ function build_graph(gobj)
|
|
|
748
637
|
* node from each zoom action would have left the readout lying
|
|
749
638
|
* after every notch. */
|
|
750
639
|
graph.on('aftertransform', () => {
|
|
751
|
-
|
|
640
|
+
yui_graph_update_zoom(gobj_read_attr(gobj, "$container"), priv.graph);
|
|
752
641
|
});
|
|
753
642
|
|
|
754
643
|
graph.on(CanvasEvent.CLICK, (evt) => {
|
|
@@ -1145,7 +1034,7 @@ function load_json(gobj)
|
|
|
1145
1034
|
if(!preserve_view) {
|
|
1146
1035
|
graph.fitView();
|
|
1147
1036
|
}
|
|
1148
|
-
|
|
1037
|
+
yui_graph_update_zoom(gobj_read_attr(gobj, "$container"), priv.graph);
|
|
1149
1038
|
});
|
|
1150
1039
|
}
|
|
1151
1040
|
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/***********************************************************************
|
|
2
|
+
* yui_graph_camera.js
|
|
3
|
+
*
|
|
4
|
+
* The camera and fold controls a G6 graph puts in a DOM toolbar,
|
|
5
|
+
* built in ONE place.
|
|
6
|
+
*
|
|
7
|
+
* This module exists because the same action was drawn three
|
|
8
|
+
* different ways across sibling views — actual size as a bare
|
|
9
|
+
* magnifier here and as `1:1` there, fit as `arrows-to-eye` here and
|
|
10
|
+
* as corner brackets there, fold as chevrons here and as an eye
|
|
11
|
+
* there. A user sees two of these graphs side by side in the same
|
|
12
|
+
* console, so a copied-and-drifted toolbar is not a detail.
|
|
13
|
+
*
|
|
14
|
+
* The VOCABULARY is not invented here. It is the one
|
|
15
|
+
* `c_g6_nodes_tree.js` settled on for the treedb graph, which draws
|
|
16
|
+
* its toolbar as a G6 plugin over an SVG sprite and therefore cannot
|
|
17
|
+
* share this code — only its decisions:
|
|
18
|
+
*
|
|
19
|
+
* zoom in / zoom out magnifiers
|
|
20
|
+
* zoom level a READOUT, because without it "1:1" is
|
|
21
|
+
* a jump to a value nobody was told
|
|
22
|
+
* fit corner brackets (`yi-fit`, the same
|
|
23
|
+
* path as the sprite's `g6-icon-fit`)
|
|
24
|
+
* actual size the WRITTEN `1:1` — the action is
|
|
25
|
+
* `zoomTo(1)`, and actual size is written
|
|
26
|
+
* in every editor that offers it, never
|
|
27
|
+
* drawn, because there is no glyph for it
|
|
28
|
+
*
|
|
29
|
+
* Fold is the one the treedb graph does not have, so its vocabulary
|
|
30
|
+
* comes from the other side of the family: the lazy tree viewer's own
|
|
31
|
+
* toolbar (`c_yui_json.js`) uses chevrons — open pointing down, closed
|
|
32
|
+
* pointing right — which is also the direction the per-node handles
|
|
33
|
+
* speak. An eye means show/hide, which is a different idea.
|
|
34
|
+
*
|
|
35
|
+
* Copyright (c) 2026, ArtGins.
|
|
36
|
+
* All Rights Reserved.
|
|
37
|
+
***********************************************************************/
|
|
38
|
+
import {createElement2, gobj_send_event} from "@yuneta/gobj-js";
|
|
39
|
+
|
|
40
|
+
import {t} from "i18next";
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
/************************************************************
|
|
44
|
+
* One icon button that fires `event_name`.
|
|
45
|
+
************************************************************/
|
|
46
|
+
function camera_button(gobj, icon, event_name, label_key, wide, extra_style)
|
|
47
|
+
{
|
|
48
|
+
return ['button', {class: `button ${event_name}`, type: 'button',
|
|
49
|
+
style: {height: wide, width: '2.5em'},
|
|
50
|
+
title: t(label_key), 'data-i18n-title': label_key,
|
|
51
|
+
'aria-label': t(label_key), 'data-i18n-aria-label': label_key},
|
|
52
|
+
['i', {style: 'font-size:1.5em; color:inherit;' + (extra_style || ''),
|
|
53
|
+
class: icon}],
|
|
54
|
+
{
|
|
55
|
+
click: (evt) => {
|
|
56
|
+
evt.stopPropagation();
|
|
57
|
+
gobj_send_event(gobj, event_name, {evt: evt}, gobj);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/************************************************************
|
|
64
|
+
* The current zoom as a percentage.
|
|
65
|
+
************************************************************/
|
|
66
|
+
export function yui_graph_zoom_text(graph)
|
|
67
|
+
{
|
|
68
|
+
if(!graph) {
|
|
69
|
+
return "100%";
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
return Math.round(graph.getZoom() * 100) + "%";
|
|
73
|
+
} catch(e) {
|
|
74
|
+
return "100%";
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/************************************************************
|
|
79
|
+
* Repaint the readout of a container that carries one.
|
|
80
|
+
*
|
|
81
|
+
* Call it from G6's `aftertransform`, which is the ONE hook
|
|
82
|
+
* that also covers the WHEEL — a camera change that passes
|
|
83
|
+
* through no action, so repainting from each zoom action
|
|
84
|
+
* leaves the number lying after every notch.
|
|
85
|
+
************************************************************/
|
|
86
|
+
export function yui_graph_update_zoom($container, graph)
|
|
87
|
+
{
|
|
88
|
+
if(!$container) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
let $readout = $container.querySelector('.GRAPH_ZOOM_LEVEL');
|
|
92
|
+
if(!$readout) {
|
|
93
|
+
return; /* a toolbar without a readout: nobody to report to */
|
|
94
|
+
}
|
|
95
|
+
$readout.textContent = yui_graph_zoom_text(graph);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/************************************************************
|
|
99
|
+
* The camera cluster: zoom in, zoom out, readout, fit,
|
|
100
|
+
* actual size. Returns createElement2 specs, in order.
|
|
101
|
+
*
|
|
102
|
+
* `wide` is the host toolbar's button height.
|
|
103
|
+
************************************************************/
|
|
104
|
+
export function yui_graph_camera_items(gobj, graph, wide)
|
|
105
|
+
{
|
|
106
|
+
return [
|
|
107
|
+
camera_button(gobj, "yi-magnifying-glass-plus", "EV_ZOOM_IN", "zoom in", wide),
|
|
108
|
+
camera_button(gobj, "yi-magnifying-glass-minus", "EV_ZOOM_OUT", "zoom out", wide),
|
|
109
|
+
['span', {class: 'GRAPH_ZOOM_LEVEL is-flex is-align-items-center px-2 has-text-grey',
|
|
110
|
+
style: 'font-size:.85rem; min-width:3.5em; justify-content:center;',
|
|
111
|
+
title: t('zoom level'), 'data-i18n-title': 'zoom level'},
|
|
112
|
+
yui_graph_zoom_text(graph)],
|
|
113
|
+
camera_button(gobj, "yi-fit", "EV_CENTER", "auto fit", wide),
|
|
114
|
+
/* Written, not drawn — see the header. */
|
|
115
|
+
['button', {class: 'button EV_ZOOM_RESET', type: 'button',
|
|
116
|
+
style: {height: wide, width: '2.5em'},
|
|
117
|
+
title: t('actual size'), 'data-i18n-title': 'actual size',
|
|
118
|
+
'aria-label': t('actual size'), 'data-i18n-aria-label': 'actual size'},
|
|
119
|
+
['span', {style: 'font-weight:700;'}, '1:1'],
|
|
120
|
+
{
|
|
121
|
+
click: (evt) => {
|
|
122
|
+
evt.stopPropagation();
|
|
123
|
+
gobj_send_event(gobj, "EV_ZOOM_RESET", {evt: evt}, gobj);
|
|
124
|
+
}
|
|
125
|
+
}]
|
|
126
|
+
];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/************************************************************
|
|
130
|
+
* The fold pair: expand all, collapse all. Chevrons, the
|
|
131
|
+
* open one rotated down — the same pair the lazy tree
|
|
132
|
+
* viewer's toolbar uses, and the same direction the
|
|
133
|
+
* per-node handles speak.
|
|
134
|
+
************************************************************/
|
|
135
|
+
export function yui_graph_fold_items(gobj, wide)
|
|
136
|
+
{
|
|
137
|
+
return [
|
|
138
|
+
camera_button(gobj, "yi-chevron-right", "EV_EXPAND_ALL", "expand all", wide,
|
|
139
|
+
' transform: rotate(90deg);'),
|
|
140
|
+
camera_button(gobj, "yi-chevron-right", "EV_COLLAPSE_ALL", "collapse all", wide),
|
|
141
|
+
];
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/************************************************************
|
|
145
|
+
* A refresh button, for the graphs that offer one.
|
|
146
|
+
************************************************************/
|
|
147
|
+
export function yui_graph_refresh_item(gobj, wide)
|
|
148
|
+
{
|
|
149
|
+
return camera_button(gobj, "yi-arrows-rotate", "EV_REFRESH", "refresh", wide);
|
|
150
|
+
}
|