@yuneta/gobj-ui 7.23.20 → 7.23.21
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 +60 -50
- package/dist/gobj-ui.es.js +68 -50
- package/package.json +1 -1
- package/src/c_g6_nodes_tree.js +1 -53
- package/src/c_yui_json_graph.js +69 -7
- package/src/lib_graph.js +55 -0
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -9474,6 +9474,23 @@ function getStrokeColor(fillColor, theme = "light", factor = .2) {
|
|
|
9474
9474
|
const adjust = (v) => lighten ? Math.min(255, Math.floor(v + (255 - v) * factor)) : Math.max(0, Math.floor(v * (1 - factor)));
|
|
9475
9475
|
return `rgba(${adjust(r)}, ${adjust(g)}, ${adjust(b)}, ${a.toFixed(3)})`;
|
|
9476
9476
|
}
|
|
9477
|
+
/************************************************************
|
|
9478
|
+
* Returns the proportional position (between 0 and 1) of a specific point,
|
|
9479
|
+
* centered and spaced with margins.
|
|
9480
|
+
*
|
|
9481
|
+
* index - Index of the point (0 to count-1)
|
|
9482
|
+
* count - Total number of points
|
|
9483
|
+
* margin - Total margin space (default 0.2 means 10% on each end)
|
|
9484
|
+
************************************************************/
|
|
9485
|
+
function getPointPosition(count, index, margin = .2) {
|
|
9486
|
+
if (count <= 0 || index < 0 || index >= count) {
|
|
9487
|
+
(0, _yuneta_gobj_js.log_error)("Invalid count or index");
|
|
9488
|
+
return .5;
|
|
9489
|
+
}
|
|
9490
|
+
const start = margin / 2;
|
|
9491
|
+
const step = (1 - margin / 2 - start) / count;
|
|
9492
|
+
return start + index * step + step / 2;
|
|
9493
|
+
}
|
|
9477
9494
|
//#endregion
|
|
9478
9495
|
//#region src/yui_graph_camera.js
|
|
9479
9496
|
/***********************************************************************
|
|
@@ -10942,6 +10959,16 @@ function build_graph$3(gobj) {
|
|
|
10942
10959
|
}
|
|
10943
10960
|
}
|
|
10944
10961
|
/************************************************************
|
|
10962
|
+
* The port a container key opens on its card.
|
|
10963
|
+
*
|
|
10964
|
+
* Prefixed so it can never collide with anything G6 puts in
|
|
10965
|
+
* the same namespace, and stringified because an array index
|
|
10966
|
+
* is a number and a port key is a string.
|
|
10967
|
+
************************************************************/
|
|
10968
|
+
function port_key(key) {
|
|
10969
|
+
return "p_" + String(key);
|
|
10970
|
+
}
|
|
10971
|
+
/************************************************************
|
|
10945
10972
|
* Build cell value HTML (matching old mx_json_viewer colors)
|
|
10946
10973
|
************************************************************/
|
|
10947
10974
|
function build_cell_html(key, value, type, dark, matched, fold) {
|
|
@@ -11084,7 +11111,7 @@ function get_group_label(path) {
|
|
|
11084
11111
|
/************************************************************
|
|
11085
11112
|
* Recursively build nodes and edges from JSON
|
|
11086
11113
|
************************************************************/
|
|
11087
|
-
function build_json_nodes(gobj, path, kw, nodes, edges, parent_id) {
|
|
11114
|
+
function build_json_nodes(gobj, path, kw, nodes, edges, parent_id, parent_port) {
|
|
11088
11115
|
let group_id = gen_node_id$1(gobj);
|
|
11089
11116
|
let is_dict = (0, _yuneta_gobj_js.is_object)(kw);
|
|
11090
11117
|
let is_list = (0, _yuneta_gobj_js.is_array)(kw);
|
|
@@ -11108,7 +11135,8 @@ function build_json_nodes(gobj, path, kw, nodes, edges, parent_id) {
|
|
|
11108
11135
|
if (has_branch(value)) {
|
|
11109
11136
|
pending_complex.push({
|
|
11110
11137
|
key,
|
|
11111
|
-
value
|
|
11138
|
+
value,
|
|
11139
|
+
port: port_key(key)
|
|
11112
11140
|
});
|
|
11113
11141
|
if (is_pure_collection(value)) {
|
|
11114
11142
|
let child_path = add_segment(path, key);
|
|
@@ -11124,7 +11152,7 @@ function build_json_nodes(gobj, path, kw, nodes, edges, parent_id) {
|
|
|
11124
11152
|
}
|
|
11125
11153
|
if (parent_id && is_pure_collection(kw)) {
|
|
11126
11154
|
if (priv.collapsed.has(path)) return parent_id;
|
|
11127
|
-
for (let pending of pending_complex) build_json_nodes(gobj, add_segment(path, pending.key), pending.value, nodes, edges, parent_id);
|
|
11155
|
+
for (let pending of pending_complex) build_json_nodes(gobj, add_segment(path, pending.key), pending.value, nodes, edges, parent_id, parent_port);
|
|
11128
11156
|
return parent_id;
|
|
11129
11157
|
}
|
|
11130
11158
|
let label = get_group_label(path) || (is_dict ? "{}" : "[]");
|
|
@@ -11155,6 +11183,17 @@ function build_json_nodes(gobj, path, kw, nodes, edges, parent_id) {
|
|
|
11155
11183
|
">${FOLD_SPACER}<span style="flex:1 1 auto; text-align:center;">${(0, _yuneta_gobj_js.escapeHtml)(label)}</span>${fold_toggle_html(path, foldable, folded, pending_complex.length, colors)}</div>
|
|
11156
11184
|
${content_html}
|
|
11157
11185
|
</div>`;
|
|
11186
|
+
let ports = [];
|
|
11187
|
+
for (let i = 0; i < pending_complex.length; i++) {
|
|
11188
|
+
let pending = pending_complex[i];
|
|
11189
|
+
let child_colors = json_card_style((0, _yuneta_gobj_js.is_object)(pending.value) ? GROUP_COLORS.dict : GROUP_COLORS.list, dark);
|
|
11190
|
+
ports.push({
|
|
11191
|
+
key: pending.port,
|
|
11192
|
+
placement: [getPointPosition(pending_complex.length, i), 1],
|
|
11193
|
+
fill: child_colors.border,
|
|
11194
|
+
stroke: colors.border
|
|
11195
|
+
});
|
|
11196
|
+
}
|
|
11158
11197
|
let node = {
|
|
11159
11198
|
id: group_id,
|
|
11160
11199
|
type: "html",
|
|
@@ -11166,20 +11205,28 @@ function build_json_nodes(gobj, path, kw, nodes, edges, parent_id) {
|
|
|
11166
11205
|
innerHTML: node_html,
|
|
11167
11206
|
size: [min_width, 24 + lines.length * 22],
|
|
11168
11207
|
dx: -(min_width / 2),
|
|
11169
|
-
dy: -((24 + lines.length * 22) / 2)
|
|
11208
|
+
dy: -((24 + lines.length * 22) / 2),
|
|
11209
|
+
port: ports.length > 0,
|
|
11210
|
+
ports,
|
|
11211
|
+
portR: 4,
|
|
11212
|
+
portLineWidth: 1
|
|
11170
11213
|
}
|
|
11171
11214
|
};
|
|
11172
11215
|
nodes.push(node);
|
|
11173
|
-
if (parent_id)
|
|
11174
|
-
|
|
11175
|
-
|
|
11176
|
-
|
|
11177
|
-
|
|
11178
|
-
|
|
11179
|
-
|
|
11180
|
-
|
|
11216
|
+
if (parent_id) {
|
|
11217
|
+
let edge = {
|
|
11218
|
+
source: parent_id,
|
|
11219
|
+
target: group_id,
|
|
11220
|
+
style: {
|
|
11221
|
+
stroke: colors.border,
|
|
11222
|
+
lineWidth: 1
|
|
11223
|
+
}
|
|
11224
|
+
};
|
|
11225
|
+
if (parent_port) edge.style.sourcePort = parent_port;
|
|
11226
|
+
edges.push(edge);
|
|
11227
|
+
}
|
|
11181
11228
|
if (folded) return group_id;
|
|
11182
|
-
for (let pending of pending_complex) build_json_nodes(gobj, add_segment(path, pending.key), pending.value, nodes, edges, group_id);
|
|
11229
|
+
for (let pending of pending_complex) build_json_nodes(gobj, add_segment(path, pending.key), pending.value, nodes, edges, group_id, pending.port);
|
|
11183
11230
|
return group_id;
|
|
11184
11231
|
}
|
|
11185
11232
|
/************************************************************
|
|
@@ -49032,43 +49079,6 @@ function configure_behaviour(gobj) {
|
|
|
49032
49079
|
graph_write_behaviors(gobj, behaviors);
|
|
49033
49080
|
}
|
|
49034
49081
|
/************************************************************
|
|
49035
|
-
* Returns the proportional position (between 0 and 1) of a specific point,
|
|
49036
|
-
* centered and spaced with margins.
|
|
49037
|
-
*
|
|
49038
|
-
* index - Index of the point (0 to count-1)
|
|
49039
|
-
* count - Total number of points
|
|
49040
|
-
* margin - Total margin space (default 0.2 means 10% on each end)
|
|
49041
|
-
************************************************************/
|
|
49042
|
-
function getPointPosition(count, index, margin = .2) {
|
|
49043
|
-
if (count <= 0 || index < 0 || index >= count) {
|
|
49044
|
-
(0, _yuneta_gobj_js.log_error)("Invalid count or index");
|
|
49045
|
-
return .5;
|
|
49046
|
-
}
|
|
49047
|
-
const start = margin / 2;
|
|
49048
|
-
const step = (1 - margin / 2 - start) / count;
|
|
49049
|
-
return start + index * step + step / 2;
|
|
49050
|
-
}
|
|
49051
|
-
/************************************************************
|
|
49052
|
-
* Count hooks and fkeys in topic desc, classify node type
|
|
49053
|
-
************************************************************/
|
|
49054
|
-
function calculate_hooks_fkeys_counter(desc) {
|
|
49055
|
-
let cols = desc.cols;
|
|
49056
|
-
desc.hooks_counter = 0;
|
|
49057
|
-
desc.fkeys_counter = 0;
|
|
49058
|
-
for (let i = 0; i < cols.length; i++) {
|
|
49059
|
-
let col = cols[i];
|
|
49060
|
-
switch ((0, _yuneta_gobj_js.treedb_get_field_desc)(col).type) {
|
|
49061
|
-
case "hook":
|
|
49062
|
-
desc.hooks_counter++;
|
|
49063
|
-
break;
|
|
49064
|
-
case "fkey": desc.fkeys_counter++;
|
|
49065
|
-
}
|
|
49066
|
-
}
|
|
49067
|
-
if (desc.hooks_counter === 0) desc.node_treedb_type = "child";
|
|
49068
|
-
else if (desc.fkeys_counter === 0) desc.node_treedb_type = "extended";
|
|
49069
|
-
else desc.node_treedb_type = "hierarchical";
|
|
49070
|
-
}
|
|
49071
|
-
/************************************************************
|
|
49072
49082
|
* Build ports for a topic desc
|
|
49073
49083
|
************************************************************/
|
|
49074
49084
|
function build_ports(gobj, desc) {
|
package/dist/gobj-ui.es.js
CHANGED
|
@@ -9346,6 +9346,14 @@ function yui_toolbar(attrs = {}, items = []) {
|
|
|
9346
9346
|
}
|
|
9347
9347
|
//#endregion
|
|
9348
9348
|
//#region src/lib_graph.js
|
|
9349
|
+
/***********************************************************************
|
|
9350
|
+
* lib_graph.js
|
|
9351
|
+
*
|
|
9352
|
+
* Utilities for graph, using Bulma
|
|
9353
|
+
*
|
|
9354
|
+
* Copyright (c) 2025, ArtGins.
|
|
9355
|
+
* All Rights Reserved.
|
|
9356
|
+
***********************************************************************/
|
|
9349
9357
|
/************************************************************
|
|
9350
9358
|
* Add class to elements selected
|
|
9351
9359
|
************************************************************/
|
|
@@ -9461,6 +9469,23 @@ function getStrokeColor(fillColor, theme = "light", factor = .2) {
|
|
|
9461
9469
|
const adjust = (v) => lighten ? Math.min(255, Math.floor(v + (255 - v) * factor)) : Math.max(0, Math.floor(v * (1 - factor)));
|
|
9462
9470
|
return `rgba(${adjust(r)}, ${adjust(g)}, ${adjust(b)}, ${a.toFixed(3)})`;
|
|
9463
9471
|
}
|
|
9472
|
+
/************************************************************
|
|
9473
|
+
* Returns the proportional position (between 0 and 1) of a specific point,
|
|
9474
|
+
* centered and spaced with margins.
|
|
9475
|
+
*
|
|
9476
|
+
* index - Index of the point (0 to count-1)
|
|
9477
|
+
* count - Total number of points
|
|
9478
|
+
* margin - Total margin space (default 0.2 means 10% on each end)
|
|
9479
|
+
************************************************************/
|
|
9480
|
+
function getPointPosition(count, index, margin = .2) {
|
|
9481
|
+
if (count <= 0 || index < 0 || index >= count) {
|
|
9482
|
+
log_error("Invalid count or index");
|
|
9483
|
+
return .5;
|
|
9484
|
+
}
|
|
9485
|
+
const start = margin / 2;
|
|
9486
|
+
const step = (1 - margin / 2 - start) / count;
|
|
9487
|
+
return start + index * step + step / 2;
|
|
9488
|
+
}
|
|
9464
9489
|
//#endregion
|
|
9465
9490
|
//#region src/yui_graph_camera.js
|
|
9466
9491
|
/***********************************************************************
|
|
@@ -10929,6 +10954,16 @@ function build_graph$3(gobj) {
|
|
|
10929
10954
|
}
|
|
10930
10955
|
}
|
|
10931
10956
|
/************************************************************
|
|
10957
|
+
* The port a container key opens on its card.
|
|
10958
|
+
*
|
|
10959
|
+
* Prefixed so it can never collide with anything G6 puts in
|
|
10960
|
+
* the same namespace, and stringified because an array index
|
|
10961
|
+
* is a number and a port key is a string.
|
|
10962
|
+
************************************************************/
|
|
10963
|
+
function port_key(key) {
|
|
10964
|
+
return "p_" + String(key);
|
|
10965
|
+
}
|
|
10966
|
+
/************************************************************
|
|
10932
10967
|
* Build cell value HTML (matching old mx_json_viewer colors)
|
|
10933
10968
|
************************************************************/
|
|
10934
10969
|
function build_cell_html(key, value, type, dark, matched, fold) {
|
|
@@ -11071,7 +11106,7 @@ function get_group_label(path) {
|
|
|
11071
11106
|
/************************************************************
|
|
11072
11107
|
* Recursively build nodes and edges from JSON
|
|
11073
11108
|
************************************************************/
|
|
11074
|
-
function build_json_nodes(gobj, path, kw, nodes, edges, parent_id) {
|
|
11109
|
+
function build_json_nodes(gobj, path, kw, nodes, edges, parent_id, parent_port) {
|
|
11075
11110
|
let group_id = gen_node_id$1(gobj);
|
|
11076
11111
|
let is_dict = is_object(kw);
|
|
11077
11112
|
let is_list = is_array(kw);
|
|
@@ -11095,7 +11130,8 @@ function build_json_nodes(gobj, path, kw, nodes, edges, parent_id) {
|
|
|
11095
11130
|
if (has_branch(value)) {
|
|
11096
11131
|
pending_complex.push({
|
|
11097
11132
|
key,
|
|
11098
|
-
value
|
|
11133
|
+
value,
|
|
11134
|
+
port: port_key(key)
|
|
11099
11135
|
});
|
|
11100
11136
|
if (is_pure_collection(value)) {
|
|
11101
11137
|
let child_path = add_segment(path, key);
|
|
@@ -11111,7 +11147,7 @@ function build_json_nodes(gobj, path, kw, nodes, edges, parent_id) {
|
|
|
11111
11147
|
}
|
|
11112
11148
|
if (parent_id && is_pure_collection(kw)) {
|
|
11113
11149
|
if (priv.collapsed.has(path)) return parent_id;
|
|
11114
|
-
for (let pending of pending_complex) build_json_nodes(gobj, add_segment(path, pending.key), pending.value, nodes, edges, parent_id);
|
|
11150
|
+
for (let pending of pending_complex) build_json_nodes(gobj, add_segment(path, pending.key), pending.value, nodes, edges, parent_id, parent_port);
|
|
11115
11151
|
return parent_id;
|
|
11116
11152
|
}
|
|
11117
11153
|
let label = get_group_label(path) || (is_dict ? "{}" : "[]");
|
|
@@ -11142,6 +11178,17 @@ function build_json_nodes(gobj, path, kw, nodes, edges, parent_id) {
|
|
|
11142
11178
|
">${FOLD_SPACER}<span style="flex:1 1 auto; text-align:center;">${escapeHtml(label)}</span>${fold_toggle_html(path, foldable, folded, pending_complex.length, colors)}</div>
|
|
11143
11179
|
${content_html}
|
|
11144
11180
|
</div>`;
|
|
11181
|
+
let ports = [];
|
|
11182
|
+
for (let i = 0; i < pending_complex.length; i++) {
|
|
11183
|
+
let pending = pending_complex[i];
|
|
11184
|
+
let child_colors = json_card_style(is_object(pending.value) ? GROUP_COLORS.dict : GROUP_COLORS.list, dark);
|
|
11185
|
+
ports.push({
|
|
11186
|
+
key: pending.port,
|
|
11187
|
+
placement: [getPointPosition(pending_complex.length, i), 1],
|
|
11188
|
+
fill: child_colors.border,
|
|
11189
|
+
stroke: colors.border
|
|
11190
|
+
});
|
|
11191
|
+
}
|
|
11145
11192
|
let node = {
|
|
11146
11193
|
id: group_id,
|
|
11147
11194
|
type: "html",
|
|
@@ -11153,20 +11200,28 @@ function build_json_nodes(gobj, path, kw, nodes, edges, parent_id) {
|
|
|
11153
11200
|
innerHTML: node_html,
|
|
11154
11201
|
size: [min_width, 24 + lines.length * 22],
|
|
11155
11202
|
dx: -(min_width / 2),
|
|
11156
|
-
dy: -((24 + lines.length * 22) / 2)
|
|
11203
|
+
dy: -((24 + lines.length * 22) / 2),
|
|
11204
|
+
port: ports.length > 0,
|
|
11205
|
+
ports,
|
|
11206
|
+
portR: 4,
|
|
11207
|
+
portLineWidth: 1
|
|
11157
11208
|
}
|
|
11158
11209
|
};
|
|
11159
11210
|
nodes.push(node);
|
|
11160
|
-
if (parent_id)
|
|
11161
|
-
|
|
11162
|
-
|
|
11163
|
-
|
|
11164
|
-
|
|
11165
|
-
|
|
11166
|
-
|
|
11167
|
-
|
|
11211
|
+
if (parent_id) {
|
|
11212
|
+
let edge = {
|
|
11213
|
+
source: parent_id,
|
|
11214
|
+
target: group_id,
|
|
11215
|
+
style: {
|
|
11216
|
+
stroke: colors.border,
|
|
11217
|
+
lineWidth: 1
|
|
11218
|
+
}
|
|
11219
|
+
};
|
|
11220
|
+
if (parent_port) edge.style.sourcePort = parent_port;
|
|
11221
|
+
edges.push(edge);
|
|
11222
|
+
}
|
|
11168
11223
|
if (folded) return group_id;
|
|
11169
|
-
for (let pending of pending_complex) build_json_nodes(gobj, add_segment(path, pending.key), pending.value, nodes, edges, group_id);
|
|
11224
|
+
for (let pending of pending_complex) build_json_nodes(gobj, add_segment(path, pending.key), pending.value, nodes, edges, group_id, pending.port);
|
|
11170
11225
|
return group_id;
|
|
11171
11226
|
}
|
|
11172
11227
|
/************************************************************
|
|
@@ -49019,43 +49074,6 @@ function configure_behaviour(gobj) {
|
|
|
49019
49074
|
graph_write_behaviors(gobj, behaviors);
|
|
49020
49075
|
}
|
|
49021
49076
|
/************************************************************
|
|
49022
|
-
* Returns the proportional position (between 0 and 1) of a specific point,
|
|
49023
|
-
* centered and spaced with margins.
|
|
49024
|
-
*
|
|
49025
|
-
* index - Index of the point (0 to count-1)
|
|
49026
|
-
* count - Total number of points
|
|
49027
|
-
* margin - Total margin space (default 0.2 means 10% on each end)
|
|
49028
|
-
************************************************************/
|
|
49029
|
-
function getPointPosition(count, index, margin = .2) {
|
|
49030
|
-
if (count <= 0 || index < 0 || index >= count) {
|
|
49031
|
-
log_error("Invalid count or index");
|
|
49032
|
-
return .5;
|
|
49033
|
-
}
|
|
49034
|
-
const start = margin / 2;
|
|
49035
|
-
const step = (1 - margin / 2 - start) / count;
|
|
49036
|
-
return start + index * step + step / 2;
|
|
49037
|
-
}
|
|
49038
|
-
/************************************************************
|
|
49039
|
-
* Count hooks and fkeys in topic desc, classify node type
|
|
49040
|
-
************************************************************/
|
|
49041
|
-
function calculate_hooks_fkeys_counter(desc) {
|
|
49042
|
-
let cols = desc.cols;
|
|
49043
|
-
desc.hooks_counter = 0;
|
|
49044
|
-
desc.fkeys_counter = 0;
|
|
49045
|
-
for (let i = 0; i < cols.length; i++) {
|
|
49046
|
-
let col = cols[i];
|
|
49047
|
-
switch (treedb_get_field_desc(col).type) {
|
|
49048
|
-
case "hook":
|
|
49049
|
-
desc.hooks_counter++;
|
|
49050
|
-
break;
|
|
49051
|
-
case "fkey": desc.fkeys_counter++;
|
|
49052
|
-
}
|
|
49053
|
-
}
|
|
49054
|
-
if (desc.hooks_counter === 0) desc.node_treedb_type = "child";
|
|
49055
|
-
else if (desc.fkeys_counter === 0) desc.node_treedb_type = "extended";
|
|
49056
|
-
else desc.node_treedb_type = "hierarchical";
|
|
49057
|
-
}
|
|
49058
|
-
/************************************************************
|
|
49059
49077
|
* Build ports for a topic desc
|
|
49060
49078
|
************************************************************/
|
|
49061
49079
|
function build_ports(gobj, desc) {
|
package/package.json
CHANGED
package/src/c_g6_nodes_tree.js
CHANGED
|
@@ -80,6 +80,7 @@ import {
|
|
|
80
80
|
set_cancel_state,
|
|
81
81
|
set_active_state,
|
|
82
82
|
set_pressed_state,
|
|
83
|
+
getPointPosition,
|
|
83
84
|
getStrokeColor,
|
|
84
85
|
} from "./lib_graph.js";
|
|
85
86
|
|
|
@@ -1598,59 +1599,6 @@ function configure_behaviour(gobj)
|
|
|
1598
1599
|
graph_write_behaviors(gobj, behaviors);
|
|
1599
1600
|
}
|
|
1600
1601
|
|
|
1601
|
-
/************************************************************
|
|
1602
|
-
* Returns the proportional position (between 0 and 1) of a specific point,
|
|
1603
|
-
* centered and spaced with margins.
|
|
1604
|
-
*
|
|
1605
|
-
* index - Index of the point (0 to count-1)
|
|
1606
|
-
* count - Total number of points
|
|
1607
|
-
* margin - Total margin space (default 0.2 means 10% on each end)
|
|
1608
|
-
************************************************************/
|
|
1609
|
-
function getPointPosition(count, index, margin = 0.2)
|
|
1610
|
-
{
|
|
1611
|
-
if(count <= 0 || index < 0 || index >= count) {
|
|
1612
|
-
log_error("Invalid count or index");
|
|
1613
|
-
return 0.5;
|
|
1614
|
-
}
|
|
1615
|
-
|
|
1616
|
-
const start = margin / 2;
|
|
1617
|
-
const end = 1 - margin / 2;
|
|
1618
|
-
const step = (end - start) / count;
|
|
1619
|
-
|
|
1620
|
-
return start + index * step + step / 2;
|
|
1621
|
-
}
|
|
1622
|
-
|
|
1623
|
-
/************************************************************
|
|
1624
|
-
* Count hooks and fkeys in topic desc, classify node type
|
|
1625
|
-
************************************************************/
|
|
1626
|
-
function calculate_hooks_fkeys_counter(desc)
|
|
1627
|
-
{
|
|
1628
|
-
let cols = desc.cols;
|
|
1629
|
-
desc.hooks_counter = 0;
|
|
1630
|
-
desc.fkeys_counter = 0;
|
|
1631
|
-
|
|
1632
|
-
for(let i=0; i<cols.length; i++) {
|
|
1633
|
-
let col = cols[i];
|
|
1634
|
-
const field_desc = treedb_get_field_desc(col);
|
|
1635
|
-
switch(field_desc.type) {
|
|
1636
|
-
case "hook":
|
|
1637
|
-
desc.hooks_counter++;
|
|
1638
|
-
break;
|
|
1639
|
-
case "fkey":
|
|
1640
|
-
desc.fkeys_counter++;
|
|
1641
|
-
break;
|
|
1642
|
-
}
|
|
1643
|
-
}
|
|
1644
|
-
|
|
1645
|
-
if(desc.hooks_counter === 0) {
|
|
1646
|
-
desc.node_treedb_type = 'child';
|
|
1647
|
-
} else if(desc.fkeys_counter === 0) {
|
|
1648
|
-
desc.node_treedb_type = 'extended';
|
|
1649
|
-
} else {
|
|
1650
|
-
desc.node_treedb_type = 'hierarchical';
|
|
1651
|
-
}
|
|
1652
|
-
}
|
|
1653
|
-
|
|
1654
1602
|
/************************************************************
|
|
1655
1603
|
* Build ports for a topic desc
|
|
1656
1604
|
************************************************************/
|
package/src/c_yui_json_graph.js
CHANGED
|
@@ -72,6 +72,7 @@ import {
|
|
|
72
72
|
import { ensure_drag_canvas_patch } from "./g6_drag_canvas_touch.js";
|
|
73
73
|
import { ensure_pinch_zoom_patch } from "./g6_touch_gestures.js";
|
|
74
74
|
import { yui_is_dark, yui_theme_now, yui_watch_theme } from "./yui_theme.js";
|
|
75
|
+
import { getPointPosition } from "./lib_graph.js";
|
|
75
76
|
import {
|
|
76
77
|
is_pure_collection,
|
|
77
78
|
has_branch,
|
|
@@ -772,6 +773,18 @@ function build_graph(gobj)
|
|
|
772
773
|
}
|
|
773
774
|
}
|
|
774
775
|
|
|
776
|
+
/************************************************************
|
|
777
|
+
* The port a container key opens on its card.
|
|
778
|
+
*
|
|
779
|
+
* Prefixed so it can never collide with anything G6 puts in
|
|
780
|
+
* the same namespace, and stringified because an array index
|
|
781
|
+
* is a number and a port key is a string.
|
|
782
|
+
************************************************************/
|
|
783
|
+
function port_key(key)
|
|
784
|
+
{
|
|
785
|
+
return "p_" + String(key);
|
|
786
|
+
}
|
|
787
|
+
|
|
775
788
|
/************************************************************
|
|
776
789
|
* Build cell value HTML (matching old mx_json_viewer colors)
|
|
777
790
|
************************************************************/
|
|
@@ -981,7 +994,7 @@ function get_group_label(path)
|
|
|
981
994
|
/************************************************************
|
|
982
995
|
* Recursively build nodes and edges from JSON
|
|
983
996
|
************************************************************/
|
|
984
|
-
function build_json_nodes(gobj, path, kw, nodes, edges, parent_id)
|
|
997
|
+
function build_json_nodes(gobj, path, kw, nodes, edges, parent_id, parent_port)
|
|
985
998
|
{
|
|
986
999
|
let group_id = gen_node_id(gobj);
|
|
987
1000
|
let is_dict = is_object(kw);
|
|
@@ -1031,7 +1044,7 @@ function build_json_nodes(gobj, path, kw, nodes, edges, parent_id)
|
|
|
1031
1044
|
*/
|
|
1032
1045
|
let fold = null;
|
|
1033
1046
|
if(has_branch(value)) {
|
|
1034
|
-
pending_complex.push({key: key, value: value});
|
|
1047
|
+
pending_complex.push({key: key, value: value, port: port_key(key)});
|
|
1035
1048
|
|
|
1036
1049
|
/*
|
|
1037
1050
|
* A child that gets no card of its own is folded from HERE
|
|
@@ -1062,13 +1075,21 @@ function build_json_nodes(gobj, path, kw, nodes, edges, parent_id)
|
|
|
1062
1075
|
return parent_id;
|
|
1063
1076
|
}
|
|
1064
1077
|
for(let pending of pending_complex) {
|
|
1078
|
+
/*
|
|
1079
|
+
* `parent_port` and not one of ours: this collection has no
|
|
1080
|
+
* card, so the port its row opened in the PARENT is the one
|
|
1081
|
+
* every one of these lines leaves from -- fourteen columns
|
|
1082
|
+
* out of the single `cols` port, which is what the document
|
|
1083
|
+
* says and what the reader traces back.
|
|
1084
|
+
*/
|
|
1065
1085
|
build_json_nodes(
|
|
1066
1086
|
gobj,
|
|
1067
1087
|
add_segment(path, pending.key),
|
|
1068
1088
|
pending.value,
|
|
1069
1089
|
nodes,
|
|
1070
1090
|
edges,
|
|
1071
|
-
parent_id
|
|
1091
|
+
parent_id,
|
|
1092
|
+
parent_port
|
|
1072
1093
|
);
|
|
1073
1094
|
}
|
|
1074
1095
|
return parent_id;
|
|
@@ -1120,6 +1141,38 @@ function build_json_nodes(gobj, path, kw, nodes, edges, parent_id)
|
|
|
1120
1141
|
${content_html}
|
|
1121
1142
|
</div>`;
|
|
1122
1143
|
|
|
1144
|
+
/*
|
|
1145
|
+
* ONE PORT PER CONTAINER KEY, and every line leaves from its own.
|
|
1146
|
+
*
|
|
1147
|
+
* Without them each card was a single anchor: fourteen lines came
|
|
1148
|
+
* out of one point, and which row a line belonged to was a guess
|
|
1149
|
+
* the reader had to make from where it landed. A port makes the row
|
|
1150
|
+
* the ORIGIN, which is the same thing the treedb graph does with a
|
|
1151
|
+
* hook column and the reason `getPointPosition` is now shared.
|
|
1152
|
+
*
|
|
1153
|
+
* On the BOTTOM edge because the layouts put children below, and
|
|
1154
|
+
* exactly ON it (`y = 1`) rather than inside: an html node draws its
|
|
1155
|
+
* HTML in a DOM layer above the canvas, so a port fully inside the
|
|
1156
|
+
* box would be painted under the card and never seen. Half of it
|
|
1157
|
+
* sticks out.
|
|
1158
|
+
*
|
|
1159
|
+
* Coloured by what the row LEADS TO -- a dict or a list -- which is
|
|
1160
|
+
* the one thing the port can say that the row does not.
|
|
1161
|
+
*/
|
|
1162
|
+
let ports = [];
|
|
1163
|
+
for(let i = 0; i < pending_complex.length; i++) {
|
|
1164
|
+
let pending = pending_complex[i];
|
|
1165
|
+
let child_colors = json_card_style(
|
|
1166
|
+
is_object(pending.value)? GROUP_COLORS.dict: GROUP_COLORS.list, dark
|
|
1167
|
+
);
|
|
1168
|
+
ports.push({
|
|
1169
|
+
key: pending.port,
|
|
1170
|
+
placement: [getPointPosition(pending_complex.length, i), 1],
|
|
1171
|
+
fill: child_colors.border,
|
|
1172
|
+
stroke: colors.border,
|
|
1173
|
+
});
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1123
1176
|
let node = {
|
|
1124
1177
|
id: group_id,
|
|
1125
1178
|
type: 'html',
|
|
@@ -1132,22 +1185,30 @@ function build_json_nodes(gobj, path, kw, nodes, edges, parent_id)
|
|
|
1132
1185
|
size: [min_width, 24 + lines.length * 22],
|
|
1133
1186
|
dx: -(min_width / 2),
|
|
1134
1187
|
dy: -((24 + lines.length * 22) / 2),
|
|
1188
|
+
port: ports.length > 0,
|
|
1189
|
+
ports: ports,
|
|
1190
|
+
portR: 4,
|
|
1191
|
+
portLineWidth: 1,
|
|
1135
1192
|
},
|
|
1136
1193
|
};
|
|
1137
1194
|
nodes.push(node);
|
|
1138
1195
|
|
|
1139
1196
|
/*
|
|
1140
|
-
* Edge from parent to this group
|
|
1197
|
+
* Edge from parent to this group, out of the port its key opened.
|
|
1141
1198
|
*/
|
|
1142
1199
|
if(parent_id) {
|
|
1143
|
-
|
|
1200
|
+
let edge = {
|
|
1144
1201
|
source: parent_id,
|
|
1145
1202
|
target: group_id,
|
|
1146
1203
|
style: {
|
|
1147
1204
|
stroke: colors.border,
|
|
1148
1205
|
lineWidth: 1,
|
|
1149
1206
|
}
|
|
1150
|
-
}
|
|
1207
|
+
};
|
|
1208
|
+
if(parent_port) {
|
|
1209
|
+
edge.style.sourcePort = parent_port;
|
|
1210
|
+
}
|
|
1211
|
+
edges.push(edge);
|
|
1151
1212
|
}
|
|
1152
1213
|
|
|
1153
1214
|
/*
|
|
@@ -1163,7 +1224,8 @@ function build_json_nodes(gobj, path, kw, nodes, edges, parent_id)
|
|
|
1163
1224
|
pending.value,
|
|
1164
1225
|
nodes,
|
|
1165
1226
|
edges,
|
|
1166
|
-
group_id
|
|
1227
|
+
group_id,
|
|
1228
|
+
pending.port
|
|
1167
1229
|
);
|
|
1168
1230
|
}
|
|
1169
1231
|
|
package/src/lib_graph.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
***********************************************************************/
|
|
9
9
|
import {
|
|
10
10
|
gobj_read_attr,
|
|
11
|
+
log_error,
|
|
11
12
|
} from "@yuneta/gobj-js";
|
|
12
13
|
|
|
13
14
|
// import {t} from "i18next";
|
|
@@ -195,6 +196,59 @@ function getStrokeColor(fillColor, theme = 'light', factor = 0.2) {
|
|
|
195
196
|
//=======================================================================
|
|
196
197
|
// Expose the class via the global object
|
|
197
198
|
//=======================================================================
|
|
199
|
+
/************************************************************
|
|
200
|
+
* Returns the proportional position (between 0 and 1) of a specific point,
|
|
201
|
+
* centered and spaced with margins.
|
|
202
|
+
*
|
|
203
|
+
* index - Index of the point (0 to count-1)
|
|
204
|
+
* count - Total number of points
|
|
205
|
+
* margin - Total margin space (default 0.2 means 10% on each end)
|
|
206
|
+
************************************************************/
|
|
207
|
+
function getPointPosition(count, index, margin = 0.2)
|
|
208
|
+
{
|
|
209
|
+
if(count <= 0 || index < 0 || index >= count) {
|
|
210
|
+
log_error("Invalid count or index");
|
|
211
|
+
return 0.5;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const start = margin / 2;
|
|
215
|
+
const end = 1 - margin / 2;
|
|
216
|
+
const step = (end - start) / count;
|
|
217
|
+
|
|
218
|
+
return start + index * step + step / 2;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/************************************************************
|
|
222
|
+
* Count hooks and fkeys in topic desc, classify node type
|
|
223
|
+
************************************************************/
|
|
224
|
+
function calculate_hooks_fkeys_counter(desc)
|
|
225
|
+
{
|
|
226
|
+
let cols = desc.cols;
|
|
227
|
+
desc.hooks_counter = 0;
|
|
228
|
+
desc.fkeys_counter = 0;
|
|
229
|
+
|
|
230
|
+
for(let i=0; i<cols.length; i++) {
|
|
231
|
+
let col = cols[i];
|
|
232
|
+
const field_desc = treedb_get_field_desc(col);
|
|
233
|
+
switch(field_desc.type) {
|
|
234
|
+
case "hook":
|
|
235
|
+
desc.hooks_counter++;
|
|
236
|
+
break;
|
|
237
|
+
case "fkey":
|
|
238
|
+
desc.fkeys_counter++;
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if(desc.hooks_counter === 0) {
|
|
244
|
+
desc.node_treedb_type = 'child';
|
|
245
|
+
} else if(desc.fkeys_counter === 0) {
|
|
246
|
+
desc.node_treedb_type = 'extended';
|
|
247
|
+
} else {
|
|
248
|
+
desc.node_treedb_type = 'hierarchical';
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
198
252
|
export {
|
|
199
253
|
addClasses,
|
|
200
254
|
removeClasses,
|
|
@@ -207,4 +261,5 @@ export {
|
|
|
207
261
|
set_active_state,
|
|
208
262
|
set_pressed_state,
|
|
209
263
|
getStrokeColor,
|
|
264
|
+
getPointPosition,
|
|
210
265
|
};
|