@yuneta/gobj-ui 7.23.80 → 7.23.81
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 +23 -0
- package/dist/gobj-ui.cjs.js +309 -5
- package/dist/gobj-ui.es.js +310 -6
- package/package.json +1 -1
- package/src/c_g6_nodes_tree.js +379 -3
- package/src/lib_graph.css +2 -0
package/src/c_g6_nodes_tree.js
CHANGED
|
@@ -137,6 +137,7 @@ import {
|
|
|
137
137
|
HistoryEvent,
|
|
138
138
|
EdgeEvent,
|
|
139
139
|
Circle,
|
|
140
|
+
HTML,
|
|
140
141
|
Toolbar,
|
|
141
142
|
register,
|
|
142
143
|
} from '@antv/g6';
|
|
@@ -446,6 +447,8 @@ let PRIVATE_DATA = {
|
|
|
446
447
|
_edge_icon_el: null, // floating properties icon element
|
|
447
448
|
_edge_delete_el: null, // floating delete icon element for edge
|
|
448
449
|
_edge_popover_el: null, // edge properties popover element
|
|
450
|
+
_port_icon_el: null, // floating port properties icon element
|
|
451
|
+
_port_popover_el: null, // port properties popover element
|
|
449
452
|
_node_icon_el: null, // floating node properties icon element
|
|
450
453
|
_node_delete_el: null, // floating delete icon element for node
|
|
451
454
|
_node_popover_el: null, // node properties popover element
|
|
@@ -839,6 +842,7 @@ function register_layouts(gobj)
|
|
|
839
842
|
register(ExtensionCategory.LAYOUT, 'treedb-tree', TreedbTreeLayout);
|
|
840
843
|
register(ExtensionCategory.LAYOUT, 'treedb-radial', TreedbRadialLayout);
|
|
841
844
|
register(ExtensionCategory.NODE, 'light', LightNode);
|
|
845
|
+
register(ExtensionCategory.NODE, 'treedb-card', TreedbCard);
|
|
842
846
|
}
|
|
843
847
|
}
|
|
844
848
|
|
|
@@ -940,6 +944,7 @@ function configure_events(gobj)
|
|
|
940
944
|
update_edge_icon_position(gobj);
|
|
941
945
|
update_node_icon_position(gobj);
|
|
942
946
|
update_link_icon_position(gobj);
|
|
947
|
+
update_port_icon_position(gobj);
|
|
943
948
|
});
|
|
944
949
|
|
|
945
950
|
graph.on(NodeEvent.DRAG_END, (evt) => {
|
|
@@ -974,6 +979,7 @@ function configure_events(gobj)
|
|
|
974
979
|
update_edge_icon_position(gobj);
|
|
975
980
|
update_node_icon_position(gobj);
|
|
976
981
|
update_link_icon_position(gobj);
|
|
982
|
+
update_port_icon_position(gobj);
|
|
977
983
|
update_zoom_readout(gobj);
|
|
978
984
|
|
|
979
985
|
/*
|
|
@@ -2132,12 +2138,32 @@ function card_shape_of(gobj, desc, record, geometry, pills_html)
|
|
|
2132
2138
|
}
|
|
2133
2139
|
}
|
|
2134
2140
|
}
|
|
2141
|
+
|
|
2142
|
+
/* And the SHAPE of each port, the same way: the node's own,
|
|
2143
|
+
* then the topic's per-port default, then the topic's one
|
|
2144
|
+
* shape for every port (`all ports` in the port popover). */
|
|
2145
|
+
let port_shapes = geometry.port_shapes;
|
|
2146
|
+
let default_port_shapes = topic_defaults ? topic_defaults.port_shapes : null;
|
|
2147
|
+
let default_shape = topic_defaults ? topic_defaults.port_shape : null;
|
|
2148
|
+
for(let i = 0; i < style.ports.length; i++) {
|
|
2149
|
+
let key = style.ports[i].key;
|
|
2150
|
+
let shape = is_object(port_shapes) ? port_shapes[key] : null;
|
|
2151
|
+
if(!shape && is_object(default_port_shapes)) {
|
|
2152
|
+
shape = default_port_shapes[key];
|
|
2153
|
+
}
|
|
2154
|
+
if(!shape) {
|
|
2155
|
+
shape = default_shape;
|
|
2156
|
+
}
|
|
2157
|
+
if(shape && str_in_list(PORT_SHAPES, shape)) {
|
|
2158
|
+
style.ports[i].shape = shape;
|
|
2159
|
+
}
|
|
2160
|
+
}
|
|
2135
2161
|
} else {
|
|
2136
2162
|
style.port = false;
|
|
2137
2163
|
style.ports = [];
|
|
2138
2164
|
}
|
|
2139
2165
|
|
|
2140
|
-
return {type: '
|
|
2166
|
+
return {type: 'treedb-card', style: style};
|
|
2141
2167
|
}
|
|
2142
2168
|
|
|
2143
2169
|
/************************************************************
|
|
@@ -2776,6 +2802,18 @@ function update_geometry(gobj, node_id)
|
|
|
2776
2802
|
} else {
|
|
2777
2803
|
delete node_props.port_sizes;
|
|
2778
2804
|
}
|
|
2805
|
+
// And the shape of each port that is not a circle
|
|
2806
|
+
let port_shapes = {};
|
|
2807
|
+
for(let i = 0; i < ports.length; i++) {
|
|
2808
|
+
if(ports[i].shape && ports[i].shape !== 'circle') {
|
|
2809
|
+
port_shapes[ports[i].key] = ports[i].shape;
|
|
2810
|
+
}
|
|
2811
|
+
}
|
|
2812
|
+
if(Object.keys(port_shapes).length > 0) {
|
|
2813
|
+
node_props.port_shapes = port_shapes;
|
|
2814
|
+
} else {
|
|
2815
|
+
delete node_props.port_shapes;
|
|
2816
|
+
}
|
|
2779
2817
|
}
|
|
2780
2818
|
|
|
2781
2819
|
topic_props.nodes[record.id] = node_props;
|
|
@@ -3485,6 +3523,7 @@ function graph_resize(gobj, width, height)
|
|
|
3485
3523
|
update_port_resize_handles_position(gobj);
|
|
3486
3524
|
update_node_icon_position(gobj);
|
|
3487
3525
|
update_link_icon_position(gobj);
|
|
3526
|
+
update_port_icon_position(gobj);
|
|
3488
3527
|
}
|
|
3489
3528
|
|
|
3490
3529
|
function graph_write_behaviors(gobj, behaviors)
|
|
@@ -3520,6 +3559,64 @@ function graph_set_behavior(gobj, behavior, set)
|
|
|
3520
3559
|
});
|
|
3521
3560
|
}
|
|
3522
3561
|
|
|
3562
|
+
/************************************************************
|
|
3563
|
+
* Custom G6 node: TreedbCard -- G6's html node with ports that
|
|
3564
|
+
* have a SHAPE.
|
|
3565
|
+
*
|
|
3566
|
+
* G6 draws every port as a circle (`drawPortShapes` upserts a
|
|
3567
|
+
* `Circle`, nothing in the port style says otherwise). A port's
|
|
3568
|
+
* `shape` -- `circle`, `square`, `diamond`, `triangle` -- picks
|
|
3569
|
+
* the G shape here, by the names G6 registers itself, and `r`
|
|
3570
|
+
* stays the one size: the half-side of the square, the half-
|
|
3571
|
+
* diagonal of the diamond, the half-height of the triangle. The
|
|
3572
|
+
* hit test, the resize handles and the edge's landing point all
|
|
3573
|
+
* read `r` and none of them care about the outline.
|
|
3574
|
+
************************************************************/
|
|
3575
|
+
const PORT_SHAPES = ['circle', 'square', 'diamond', 'triangle'];
|
|
3576
|
+
|
|
3577
|
+
class TreedbCard extends HTML
|
|
3578
|
+
{
|
|
3579
|
+
drawPortShapes(attributes, container) {
|
|
3580
|
+
const portsStyle = this.getPortsStyle(attributes);
|
|
3581
|
+
Object.keys(portsStyle).forEach((key) => {
|
|
3582
|
+
const style = portsStyle[key];
|
|
3583
|
+
const shapeKey = `port-${key}`;
|
|
3584
|
+
if(style === false) {
|
|
3585
|
+
this.upsert(shapeKey, 'circle', false, container);
|
|
3586
|
+
return;
|
|
3587
|
+
}
|
|
3588
|
+
let r = Number(style.r) || 0;
|
|
3589
|
+
switch(style.shape) {
|
|
3590
|
+
case 'square':
|
|
3591
|
+
this.upsert(shapeKey, 'rect', Object.assign({}, style, {
|
|
3592
|
+
x: -r, y: -r, width: 2 * r, height: 2 * r,
|
|
3593
|
+
}), container);
|
|
3594
|
+
break;
|
|
3595
|
+
case 'diamond':
|
|
3596
|
+
this.upsert(shapeKey, 'polygon', Object.assign({}, style, {
|
|
3597
|
+
points: [[0, -r], [r, 0], [0, r], [-r, 0]],
|
|
3598
|
+
}), container);
|
|
3599
|
+
break;
|
|
3600
|
+
case 'triangle':
|
|
3601
|
+
this.upsert(shapeKey, 'polygon', Object.assign({}, style, {
|
|
3602
|
+
points: [[0, -r], [r, r], [-r, r]],
|
|
3603
|
+
}), container);
|
|
3604
|
+
break;
|
|
3605
|
+
default:
|
|
3606
|
+
this.upsert(shapeKey, 'circle', style, container);
|
|
3607
|
+
break;
|
|
3608
|
+
}
|
|
3609
|
+
});
|
|
3610
|
+
}
|
|
3611
|
+
}
|
|
3612
|
+
|
|
3613
|
+
/* A record's card is `treedb-card`; `html` is what it was until
|
|
3614
|
+
* 7.23.81 and what a `+N` chip still is. */
|
|
3615
|
+
function is_card_type(type)
|
|
3616
|
+
{
|
|
3617
|
+
return type === 'treedb-card' || type === 'html';
|
|
3618
|
+
}
|
|
3619
|
+
|
|
3523
3620
|
/************************************************************
|
|
3524
3621
|
* Custom G6 node: LightNode (circle with status indicator)
|
|
3525
3622
|
************************************************************/
|
|
@@ -4661,7 +4758,7 @@ function start_node_resize(gobj, e, mx, my)
|
|
|
4661
4758
|
}
|
|
4662
4759
|
|
|
4663
4760
|
// HTML nodes: update dx, dy to keep content centered
|
|
4664
|
-
if(nodeType
|
|
4761
|
+
if(is_card_type(nodeType)) {
|
|
4665
4762
|
updateStyle.dx = -newW / 2;
|
|
4666
4763
|
updateStyle.dy = -newH / 2;
|
|
4667
4764
|
}
|
|
@@ -4842,6 +4939,7 @@ function select_port(gobj, node_id, port_key)
|
|
|
4842
4939
|
|
|
4843
4940
|
show_port_resize_handles(gobj);
|
|
4844
4941
|
show_link_icon_if_fkey(gobj);
|
|
4942
|
+
show_port_icon(gobj);
|
|
4845
4943
|
}
|
|
4846
4944
|
|
|
4847
4945
|
/************************************************************
|
|
@@ -4853,6 +4951,8 @@ function deselect_port(gobj)
|
|
|
4853
4951
|
|
|
4854
4952
|
exit_linking_mode(gobj);
|
|
4855
4953
|
hide_link_icon(gobj);
|
|
4954
|
+
hide_port_icon(gobj);
|
|
4955
|
+
hide_port_popover(gobj);
|
|
4856
4956
|
hide_port_resize_handles(gobj);
|
|
4857
4957
|
priv._selected_port_key = null;
|
|
4858
4958
|
}
|
|
@@ -4940,6 +5040,272 @@ function update_link_icon_position(gobj)
|
|
|
4940
5040
|
}
|
|
4941
5041
|
}
|
|
4942
5042
|
|
|
5043
|
+
/************************************************************
|
|
5044
|
+
* Port properties icon and popover: the gear beside a selected
|
|
5045
|
+
* port, as the node has its own. The popover has the two things
|
|
5046
|
+
* a port IS on screen -- its shape and its radius -- and the
|
|
5047
|
+
* scope: this port, the same port of every card of the topic
|
|
5048
|
+
* (the hook or fkey column), or every port there is.
|
|
5049
|
+
************************************************************/
|
|
5050
|
+
function port_icon_xy(gobj)
|
|
5051
|
+
{
|
|
5052
|
+
let priv = gobj.priv;
|
|
5053
|
+
let graph = priv.graph;
|
|
5054
|
+
let canvasPos = get_port_canvas_position(
|
|
5055
|
+
gobj, priv._selected_node_id, priv._selected_port_key
|
|
5056
|
+
);
|
|
5057
|
+
if(!canvasPos) {
|
|
5058
|
+
return null;
|
|
5059
|
+
}
|
|
5060
|
+
let vp = graph.getViewportByCanvas([canvasPos.x, canvasPos.y]);
|
|
5061
|
+
/* Under the link icon when there is one (an fkey), in its
|
|
5062
|
+
* place otherwise. */
|
|
5063
|
+
let below = priv._link_icon_el? floating_icon_step() : 0;
|
|
5064
|
+
return {
|
|
5065
|
+
x: vp[0] + floating_icon_size() / 2 + 4,
|
|
5066
|
+
y: vp[1] + floating_icon_dy() + below,
|
|
5067
|
+
};
|
|
5068
|
+
}
|
|
5069
|
+
|
|
5070
|
+
function show_port_icon(gobj)
|
|
5071
|
+
{
|
|
5072
|
+
hide_port_icon(gobj);
|
|
5073
|
+
|
|
5074
|
+
let priv = gobj.priv;
|
|
5075
|
+
if(!priv._selected_node_id || !priv._selected_port_key) {
|
|
5076
|
+
return;
|
|
5077
|
+
}
|
|
5078
|
+
let xy = port_icon_xy(gobj);
|
|
5079
|
+
if(!xy) {
|
|
5080
|
+
return;
|
|
5081
|
+
}
|
|
5082
|
+
let icon = create_floating_icon(
|
|
5083
|
+
'gear', '#1890ff', xy.x, xy.y,
|
|
5084
|
+
t('port properties'), () => toggle_port_popover(gobj)
|
|
5085
|
+
);
|
|
5086
|
+
priv.$container.appendChild(icon);
|
|
5087
|
+
priv._port_icon_el = icon;
|
|
5088
|
+
}
|
|
5089
|
+
|
|
5090
|
+
function hide_port_icon(gobj)
|
|
5091
|
+
{
|
|
5092
|
+
hide_overlay(gobj, '_port_icon_el');
|
|
5093
|
+
}
|
|
5094
|
+
|
|
5095
|
+
function update_port_icon_position(gobj)
|
|
5096
|
+
{
|
|
5097
|
+
let priv = gobj.priv;
|
|
5098
|
+
if(!priv._port_icon_el || !priv._selected_node_id || !priv._selected_port_key) {
|
|
5099
|
+
return;
|
|
5100
|
+
}
|
|
5101
|
+
try {
|
|
5102
|
+
let xy = port_icon_xy(gobj);
|
|
5103
|
+
if(!xy) {
|
|
5104
|
+
hide_port_icon(gobj);
|
|
5105
|
+
hide_port_popover(gobj);
|
|
5106
|
+
return;
|
|
5107
|
+
}
|
|
5108
|
+
priv._port_icon_el.style.left = xy.x + 'px';
|
|
5109
|
+
priv._port_icon_el.style.top = xy.y + 'px';
|
|
5110
|
+
if(priv._port_popover_el) {
|
|
5111
|
+
priv._port_popover_el.style.left = (xy.x + floating_popover_dx()) + 'px';
|
|
5112
|
+
priv._port_popover_el.style.top = xy.y + 'px';
|
|
5113
|
+
clamp_popover_position(gobj, priv._port_popover_el);
|
|
5114
|
+
}
|
|
5115
|
+
} catch(e) {
|
|
5116
|
+
hide_port_icon(gobj);
|
|
5117
|
+
hide_port_popover(gobj);
|
|
5118
|
+
}
|
|
5119
|
+
}
|
|
5120
|
+
|
|
5121
|
+
function toggle_port_popover(gobj)
|
|
5122
|
+
{
|
|
5123
|
+
let priv = gobj.priv;
|
|
5124
|
+
if(priv._port_popover_el) {
|
|
5125
|
+
hide_port_popover(gobj);
|
|
5126
|
+
} else {
|
|
5127
|
+
show_port_popover(gobj);
|
|
5128
|
+
}
|
|
5129
|
+
}
|
|
5130
|
+
|
|
5131
|
+
function hide_port_popover(gobj)
|
|
5132
|
+
{
|
|
5133
|
+
hide_overlay(gobj, '_port_popover_el');
|
|
5134
|
+
}
|
|
5135
|
+
|
|
5136
|
+
/* The ports of a node with ONE of them rewritten. */
|
|
5137
|
+
function ports_with(ports, port_key, changes)
|
|
5138
|
+
{
|
|
5139
|
+
return (ports || []).map((p) => (p.key === port_key)? Object.assign({}, p, changes) : p);
|
|
5140
|
+
}
|
|
5141
|
+
|
|
5142
|
+
function show_port_popover(gobj)
|
|
5143
|
+
{
|
|
5144
|
+
hide_port_popover(gobj);
|
|
5145
|
+
|
|
5146
|
+
let priv = gobj.priv;
|
|
5147
|
+
let graph = priv.graph;
|
|
5148
|
+
let node_id = priv._selected_node_id;
|
|
5149
|
+
let port_key = priv._selected_port_key;
|
|
5150
|
+
if(!node_id || !port_key) {
|
|
5151
|
+
return;
|
|
5152
|
+
}
|
|
5153
|
+
let nodeData = graph.getNodeData(node_id);
|
|
5154
|
+
if(!nodeData || !nodeData.style) {
|
|
5155
|
+
return;
|
|
5156
|
+
}
|
|
5157
|
+
let ports = nodeData.style.ports || [];
|
|
5158
|
+
let port = ports.find((p) => p.key === port_key);
|
|
5159
|
+
if(!port) {
|
|
5160
|
+
return;
|
|
5161
|
+
}
|
|
5162
|
+
let orig_shape = port.shape || 'circle';
|
|
5163
|
+
let orig_r = get_port_radius(gobj, node_id, port_key);
|
|
5164
|
+
|
|
5165
|
+
let xy = port_icon_xy(gobj);
|
|
5166
|
+
if(!xy) {
|
|
5167
|
+
return;
|
|
5168
|
+
}
|
|
5169
|
+
const popover = create_popover_base(
|
|
5170
|
+
xy.x + floating_popover_dx(), xy.y, 'g6-port-popover', '#d9d9d9', 180
|
|
5171
|
+
);
|
|
5172
|
+
|
|
5173
|
+
/* Live preview on THIS port; the others wait for apply. */
|
|
5174
|
+
function preview_port() {
|
|
5175
|
+
let r = parseInt(rInput.value) || orig_r;
|
|
5176
|
+
graph.updateNodeData([{id: node_id, style: {
|
|
5177
|
+
ports: ports_with(nodeData.style.ports, port_key, {shape: shapeSelect.value, r: r}),
|
|
5178
|
+
}}]);
|
|
5179
|
+
graph.draw().then(() => {
|
|
5180
|
+
update_port_resize_handles_position(gobj);
|
|
5181
|
+
});
|
|
5182
|
+
}
|
|
5183
|
+
|
|
5184
|
+
create_form_label(popover, 'shape');
|
|
5185
|
+
let shapeSelect = create_form_select(popover, PORT_SHAPES.map((shape) => {
|
|
5186
|
+
return {value: shape, label: t(shape)};
|
|
5187
|
+
}));
|
|
5188
|
+
shapeSelect.value = orig_shape;
|
|
5189
|
+
shapeSelect.addEventListener('change', preview_port);
|
|
5190
|
+
|
|
5191
|
+
create_form_label(popover, 'radius');
|
|
5192
|
+
let rInput = create_form_number_input(popover, orig_r, 2, 40, preview_port);
|
|
5193
|
+
|
|
5194
|
+
create_form_label(popover, 'apply to');
|
|
5195
|
+
let scopeSelect = create_form_select(popover, [
|
|
5196
|
+
{value: 'this', label: t('this port')},
|
|
5197
|
+
{value: 'same_topic', label: t('same port in topic')},
|
|
5198
|
+
{value: 'all', label: t('all ports')},
|
|
5199
|
+
]);
|
|
5200
|
+
|
|
5201
|
+
create_form_button_row(popover, [
|
|
5202
|
+
{
|
|
5203
|
+
text: 'cancel',
|
|
5204
|
+
style: BTN_STYLE_CANCEL,
|
|
5205
|
+
onClick: () => {
|
|
5206
|
+
graph.updateNodeData([{id: node_id, style: {
|
|
5207
|
+
ports: ports_with(nodeData.style.ports, port_key, {shape: orig_shape, r: orig_r}),
|
|
5208
|
+
}}]);
|
|
5209
|
+
graph.draw().then(() => {
|
|
5210
|
+
update_port_resize_handles_position(gobj);
|
|
5211
|
+
});
|
|
5212
|
+
hide_port_popover(gobj);
|
|
5213
|
+
},
|
|
5214
|
+
},
|
|
5215
|
+
{
|
|
5216
|
+
text: 'apply',
|
|
5217
|
+
style: 'flex:1;padding:6px;background:#1890ff;color:#fff;border:none;' +
|
|
5218
|
+
'border-radius:4px;cursor:pointer;font-size:13px;font-weight:500;',
|
|
5219
|
+
onClick: () => {
|
|
5220
|
+
apply_port_properties(gobj, node_id, port_key,
|
|
5221
|
+
shapeSelect.value, parseInt(rInput.value) || orig_r, scopeSelect.value
|
|
5222
|
+
);
|
|
5223
|
+
},
|
|
5224
|
+
},
|
|
5225
|
+
]);
|
|
5226
|
+
|
|
5227
|
+
priv.$container.appendChild(popover);
|
|
5228
|
+
priv._port_popover_el = popover;
|
|
5229
|
+
clamp_popover_position(gobj, popover);
|
|
5230
|
+
}
|
|
5231
|
+
|
|
5232
|
+
/************************************************************
|
|
5233
|
+
* Apply a port's shape and radius to one port, to the same port
|
|
5234
|
+
* of every card of the topic, or to every port -- and remember
|
|
5235
|
+
* the choice as the topic's default, the way `resize all ports`
|
|
5236
|
+
* does, so a card that arrives later is born with it.
|
|
5237
|
+
* scope: 'this', 'same_topic', 'all'
|
|
5238
|
+
************************************************************/
|
|
5239
|
+
function apply_port_properties(gobj, node_id, port_key, shape, r, scope)
|
|
5240
|
+
{
|
|
5241
|
+
let priv = gobj.priv;
|
|
5242
|
+
let graph = priv.graph;
|
|
5243
|
+
|
|
5244
|
+
let nodeData = graph.getNodeData(node_id);
|
|
5245
|
+
if(!nodeData || !nodeData.data) {
|
|
5246
|
+
return;
|
|
5247
|
+
}
|
|
5248
|
+
let source_topic = nodeData.data.topic_name;
|
|
5249
|
+
|
|
5250
|
+
if(scope === 'same_topic') {
|
|
5251
|
+
if(!is_object(priv._graph_properties[source_topic])) {
|
|
5252
|
+
priv._graph_properties[source_topic] = {};
|
|
5253
|
+
}
|
|
5254
|
+
let defaults = priv._graph_properties[source_topic].defaults || {};
|
|
5255
|
+
defaults.port_sizes = Object.assign({}, defaults.port_sizes, {[port_key]: r});
|
|
5256
|
+
defaults.port_shapes = Object.assign({}, defaults.port_shapes, {[port_key]: shape});
|
|
5257
|
+
priv._graph_properties[source_topic].defaults = defaults;
|
|
5258
|
+
} else if(scope === 'all') {
|
|
5259
|
+
for(const topic_name of Object.keys(priv.descs || {})) {
|
|
5260
|
+
if(!is_object(priv._graph_properties[topic_name])) {
|
|
5261
|
+
priv._graph_properties[topic_name] = {};
|
|
5262
|
+
}
|
|
5263
|
+
let defaults = priv._graph_properties[topic_name].defaults || {};
|
|
5264
|
+
defaults.portR = r;
|
|
5265
|
+
defaults.port_shape = shape;
|
|
5266
|
+
delete defaults.port_sizes;
|
|
5267
|
+
delete defaults.port_shapes;
|
|
5268
|
+
priv._graph_properties[topic_name].defaults = defaults;
|
|
5269
|
+
}
|
|
5270
|
+
}
|
|
5271
|
+
|
|
5272
|
+
let updates = [];
|
|
5273
|
+
for(let nd of (graph.getNodeData() || [])) {
|
|
5274
|
+
if(!nd || !nd.data || !nd.data.desc || !nd.style || !is_array(nd.style.ports)) {
|
|
5275
|
+
continue;
|
|
5276
|
+
}
|
|
5277
|
+
let new_ports;
|
|
5278
|
+
if(scope === 'this') {
|
|
5279
|
+
if(nd.id !== node_id) {
|
|
5280
|
+
continue;
|
|
5281
|
+
}
|
|
5282
|
+
new_ports = ports_with(nd.style.ports, port_key, {shape: shape, r: r});
|
|
5283
|
+
} else if(scope === 'same_topic') {
|
|
5284
|
+
if(nd.data.topic_name !== source_topic) {
|
|
5285
|
+
continue;
|
|
5286
|
+
}
|
|
5287
|
+
new_ports = ports_with(nd.style.ports, port_key, {shape: shape, r: r});
|
|
5288
|
+
} else {
|
|
5289
|
+
new_ports = nd.style.ports.map((p) => Object.assign({}, p, {shape: shape, r: r}));
|
|
5290
|
+
}
|
|
5291
|
+
let upd = {ports: new_ports};
|
|
5292
|
+
if(scope === 'all') {
|
|
5293
|
+
upd.portR = r;
|
|
5294
|
+
}
|
|
5295
|
+
updates.push({id: nd.id, style: upd});
|
|
5296
|
+
}
|
|
5297
|
+
|
|
5298
|
+
if(updates.length > 0) {
|
|
5299
|
+
graph.updateNodeData(updates);
|
|
5300
|
+
graph.draw().then(() => {
|
|
5301
|
+
update_port_resize_handles_position(gobj);
|
|
5302
|
+
update_port_icon_position(gobj);
|
|
5303
|
+
mark_graph_dirty(gobj);
|
|
5304
|
+
});
|
|
5305
|
+
}
|
|
5306
|
+
hide_port_popover(gobj);
|
|
5307
|
+
}
|
|
5308
|
+
|
|
4943
5309
|
/************************************************************
|
|
4944
5310
|
* Get a column descriptor by field id from a topic desc.
|
|
4945
5311
|
************************************************************/
|
|
@@ -7453,6 +7819,9 @@ function build_port_context_menu(gobj, node_id, port_key)
|
|
|
7453
7819
|
|
|
7454
7820
|
if(gobj.priv.edit_mode) {
|
|
7455
7821
|
inject_svg_icons();
|
|
7822
|
+
/* The popover, for a finger: the gear beside the port needs
|
|
7823
|
+
* the port selected first, and a long press is the menu. */
|
|
7824
|
+
items.push(ctx_item('g6-icon-edit', t('port properties'), 'port_properties'));
|
|
7456
7825
|
items.push(ctx_item('g6-icon-resize', t('resize all ports'), 'resize_all_ports'));
|
|
7457
7826
|
items.push(ctx_item('g6-icon-resize', t('resize topic ports'), 'resize_topic_ports'));
|
|
7458
7827
|
}
|
|
@@ -7495,6 +7864,12 @@ function handle_context_menu_click(gobj, value)
|
|
|
7495
7864
|
case 'reset_topic_sizes':
|
|
7496
7865
|
reset_sizes(gobj, true);
|
|
7497
7866
|
break;
|
|
7867
|
+
case 'port_properties':
|
|
7868
|
+
if(priv._context_node_id && priv._context_port_key) {
|
|
7869
|
+
select_port(gobj, priv._context_node_id, priv._context_port_key);
|
|
7870
|
+
show_port_popover(gobj);
|
|
7871
|
+
}
|
|
7872
|
+
break;
|
|
7498
7873
|
case 'resize_all_ports':
|
|
7499
7874
|
copy_size_to_ports(gobj, false);
|
|
7500
7875
|
break;
|
|
@@ -7581,7 +7956,7 @@ function copy_size_to_nodes(gobj, same_topic_only)
|
|
|
7581
7956
|
}
|
|
7582
7957
|
|
|
7583
7958
|
// Recalculate dx/dy for HTML nodes
|
|
7584
|
-
if(nd.type
|
|
7959
|
+
if(is_card_type(nd.type)) {
|
|
7585
7960
|
updateStyle.dx = -source_size[0] / 2;
|
|
7586
7961
|
let h = source_size.length > 1 ? source_size[1] : source_size[0];
|
|
7587
7962
|
updateStyle.dy = -h / 2;
|
|
@@ -8418,6 +8793,7 @@ async function reconcile_fold_apply(gobj, opts, visible)
|
|
|
8418
8793
|
update_edge_icon_position(gobj);
|
|
8419
8794
|
update_node_icon_position(gobj);
|
|
8420
8795
|
update_link_icon_position(gobj);
|
|
8796
|
+
update_port_icon_position(gobj);
|
|
8421
8797
|
|
|
8422
8798
|
return changed;
|
|
8423
8799
|
}
|
package/src/lib_graph.css
CHANGED
|
@@ -86,6 +86,7 @@
|
|
|
86
86
|
.graph-container .g6-create-popover,
|
|
87
87
|
.graph-container .g6-node-popover,
|
|
88
88
|
.graph-container .g6-edge-popover,
|
|
89
|
+
.graph-container .g6-port-popover,
|
|
89
90
|
.graph-container .g6-node-detail {
|
|
90
91
|
-webkit-user-select: text;
|
|
91
92
|
user-select: text;
|
|
@@ -99,6 +100,7 @@
|
|
|
99
100
|
.graph-container .g6-create-popover,
|
|
100
101
|
.graph-container .g6-node-popover,
|
|
101
102
|
.graph-container .g6-edge-popover,
|
|
103
|
+
.graph-container .g6-port-popover,
|
|
102
104
|
.graph-container .g6-node-detail,
|
|
103
105
|
.graph-container .g6-contextmenu {
|
|
104
106
|
touch-action: auto;
|