1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Merge pull request #2386 from sakazuki/vertical-view

Vertical flow view
This commit is contained in:
Nick O'Leary 2019-11-21 22:06:55 +00:00 committed by GitHub
commit fc590c66c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 223 additions and 51 deletions

View File

@ -45,7 +45,8 @@
"rtl": "Right-to-left",
"auto": "Contextual",
"language": "Language",
"browserDefault": "Browser default"
"browserDefault": "Browser default",
"flowVertical": "Vertical flow"
},
"sidebar": {
"show": "Show sidebar"

View File

@ -45,7 +45,8 @@
"rtl": "右から左",
"auto": "文脈",
"language": "表示言語",
"browserDefault": "ブラウザのデフォルト"
"browserDefault": "ブラウザのデフォルト",
"flowVertical": "縦フロー"
},
"sidebar": {
"show": "サイドバーを表示"

View File

@ -36,7 +36,8 @@
"defaultDir": "默认方向",
"ltr": "从左到右",
"rtl": "从右到左",
"auto": "上下文"
"auto": "上下文",
"flowVertical": "Vertical flow"
},
"sidebar": {
"show": "显示侧边栏"

View File

@ -139,7 +139,14 @@ RED.palette = (function() {
var labelElement = el.find(".red-ui-palette-label");
labelElement.html(lines).attr('dir', RED.text.bidi.resolveBaseTextDir(lines));
el.find(".red-ui-palette-port").css({top:(multiLineNodeHeight/2-5)+"px"});
if (RED.view.vertical()) {
el.find(".red-ui-palette-port").css({top:(multiLineNodeHeight/2-5)+"px", left: "55px"});
el.find(".red-ui-palette-port-output").css({top:(multiLineNodeHeight-5)+"px", right: "55px"});
el.find(".red-ui-palette-port-input").css({top: "-5px"});
}else{
el.find(".red-ui-palette-port").css({top:(multiLineNodeHeight/2-5)+"px"});
// el.find(".palette_port_output").css({top:(multiLineNodeHeight/2-5)+"px", right: "-6px", left: "auto"});
}
var popOverContent;
try {

View File

@ -133,7 +133,8 @@ RED.userSettings = (function() {
{
title: "menu.label.other",
options: [
{setting:"view-show-tips",oldSettings:"menu-menu-item-show-tips",label:"menu.label.showTips",toggle:true,default:true,onchange:"core:toggle-show-tips"}
{setting:"view-show-tips",oldSettings:"menu-menu-item-show-tips",label:"menu.label.showTips",toggle:true,default:true,onchange:"core:toggle-show-tips"},
{setting:"view-flow-vertical",label:"menu.label.view.flowVertical",toggle:true,default:false,onchange:RED.view.vertical}
]
}
];

253
packages/node_modules/@node-red/editor-client/src/js/ui/view.js vendored Executable file → Normal file
View File

@ -44,6 +44,7 @@ RED.view = (function() {
var gridSize = 20;
var snapGrid = false;
var vertical = false;
var activeSpliceLink;
var spliceActive = false;
@ -595,6 +596,76 @@ RED.view = (function() {
}
}
function generateLinkPathV(origX,origY, destX, destY, sc) {
var dy = destY-origY;
var dx = destX-origX;
var delta = Math.sqrt(dy*dy+dx*dx);
var scale = lineCurveScale;
var scaleX = 0;
if (dy*sc > 0) {
if (delta < node_height) {
scale = 0.75-0.75*((node_height-delta)/node_height);
// scale += 2*(Math.min(5*node_height,Math.abs(dx))/(5*node_height));
// if (Math.abs(dy) < 3*node_height) {
// scaleY = ((dy>0)?0.5:-0.5)*(((3*node_height)-Math.abs(dy))/(3*node_height))*(Math.min(node_height,Math.abs(dx))/(node_height)) ;
// }
}
} else {
scale = 0.4-0.2*(Math.max(0,(node_height-Math.min(Math.abs(dx),Math.abs(dy)))/node_height));
}
if (dy*sc > 0) {
return "M "+origX+" "+origY+
" C "+(origX+(node_width*scaleX))+" "+(origY+sc*scale*node_height)+" "+
(destX-(node_width*scaleX))+" "+(destY-sc*scale*node_height)+" "+
destX+" "+destY
} else {
var midX = Math.floor(destX-dx/2);
var midY = Math.floor(destY-dy/2);
//
if (dx === 0) {
midX = destX + node_width;
}
var cp_width = node_width/2;
var x1 = (destX + midX)/2;
var topX = dx>0? Math.min(x1 - dx/2 , origX+cp_width) : Math.max(x1 - dx/2 , origX-cp_width);
var topY = origY + sc*node_height*scale;
var bottomX = dx>0?Math.max(x1, destX-cp_width):Math.min(x1, destX+cp_width);
var bottomY = destY - sc*node_height*scale;
var y1 = (origY+topY)/2;
var scx = dx>0?1:-1;
var cp = [
[origX,y1],
[dx>0 ? Math.max(origX, topX-cp_width) : Math.min(origX, topX+cp_width), topY],
[dx>0 ? Math.max(midX, topX-cp_width) : Math.min(midX, topX-cp_width), y1],
[dx>0 ? Math.max(midX, bottomX-cp_width): Math.min(midX, bottomX+cp_width), bottomY],
[destX,(destY+bottomY)/2]
];
if (cp[2][0] === topX+scx*cp_width) {
if (Math.abs(dx) < cp_width*10) {
cp[1][0] = topX-scx*cp_width/2;
cp[3][0] = bottomX-scx*cp_width/2;
}
cp[2][1] = topY;
}
return "M "+origX+" "+origY+
" C "+
cp[0][0]+" "+cp[0][1]+" "+
cp[1][0]+" "+cp[1][1]+" "+
topX+" "+topY+
" S "+
cp[2][0]+" "+cp[2][1]+" "+
midX+" "+midY+
" S "+
cp[3][0]+" "+cp[3][1]+" "+
bottomX+" "+bottomY+
" S "+
cp[4][0]+" "+cp[4][1]+" "+
destX+" "+destY
}
}
function addNode(type,x,y) {
var m = /^subflow:(.+)$/.exec(type);
@ -644,8 +715,13 @@ RED.view = (function() {
nn.changed = true;
nn.moved = true;
nn.w = node_width;
nn.h = Math.max(node_height,(nn.outputs||0) * 15);
if (vertical) {
nn.w = Math.max(node_width,(nn.outputs||0) * 15);
nn.h = node_height;
}else{
nn.w = node_width;
nn.h = Math.max(node_height,(nn.outputs||0) * 15);
}
nn.resize = true;
var historyEvent = {
@ -786,9 +862,18 @@ RED.view = (function() {
}
var numOutputs = (quickAddLink.portType === PORT_TYPE_OUTPUT)?(quickAddLink.node.outputs || 1):1;
var sourcePort = quickAddLink.port;
var portY = -((numOutputs-1)/2)*13 +13*sourcePort;
if (vertical) {
var portX = -((numOutputs-1)/2)*13 +13*sourcePort;
}else{
var portY = -((numOutputs-1)/2)*13 +13*sourcePort;
}
var sc = (quickAddLink.portType === PORT_TYPE_OUTPUT)?1:-1;
quickAddLink.el.attr("d",generateLinkPath(quickAddLink.node.x+sc*quickAddLink.node.w/2,quickAddLink.node.y+portY,point[0]-sc*node_width/2,point[1],sc));
if (vertical) {
quickAddLink.el.attr("d",generateLinkPathV(quickAddLink.node.x+portX,quickAddLink.node.y+sc*quickAddLink.node.h/2,point[0]-sc*node_width/2,point[1],sc));
}else{
quickAddLink.el.attr("d",generateLinkPath(quickAddLink.node.x+sc*quickAddLink.node.w/2,quickAddLink.node.y+portY,point[0]-sc*node_width/2,point[1],sc));
}
}
if (quickAddLink) {
rebuildQuickAddLink();
@ -1142,10 +1227,18 @@ RED.view = (function() {
var drag_line = drag_lines[i];
var numOutputs = (drag_line.portType === PORT_TYPE_OUTPUT)?(drag_line.node.outputs || 1):1;
var sourcePort = drag_line.port;
var portY = -((numOutputs-1)/2)*13 +13*sourcePort;
if (vertical) {
var portX = -((numOutputs-1)/2)*13 +13*sourcePort;
}else{
var portY = -((numOutputs-1)/2)*13 +13*sourcePort;
}
var sc = (drag_line.portType === PORT_TYPE_OUTPUT)?1:-1;
drag_line.el.attr("d",generateLinkPath(drag_line.node.x+sc*drag_line.node.w/2,drag_line.node.y+portY,mousePos[0],mousePos[1],sc));
if (vertical) {
drag_line.el.attr("d",generateLinkPathV(drag_line.node.x+portX,drag_line.node.y+sc*drag_line.node.h/2,mousePos[0],mousePos[1],sc));
}else{
drag_line.el.attr("d",generateLinkPath(drag_line.node.x+sc*drag_line.node.w/2,drag_line.node.y+portY,mousePos[0],mousePos[1],sc));
}
}
d3.event.preventDefault();
} else if (mouse_mode == RED.state.MOVING) {
@ -2563,8 +2656,8 @@ RED.view = (function() {
}
nodeMouseUp.call(this,d);
});
outGroup.append("g").attr('transform','translate(-5,15)').append("rect").attr("class","red-ui-flow-port").attr("rx",3).attr("ry",3).attr("width",10).attr("height",10)
var attr_output_translate = (vertical) ? 'translate(15,-5)' : 'translate(-5,15)';
outGroup.append("g").attr('transform',attr_output_translate).append("rect").attr("class","red-ui-flow-port").attr("rx",3).attr("ry",3).attr("width",10).attr("height",10)
.on("mousedown", function(d,i){portMouseDown(d,PORT_TYPE_INPUT,0);} )
.on("touchstart", function(d,i){portMouseDown(d,PORT_TYPE_INPUT,0);} )
.on("mouseup", function(d,i){portMouseUp(d,PORT_TYPE_INPUT,0);})
@ -2606,8 +2699,8 @@ RED.view = (function() {
}
nodeMouseUp.call(this,d);
});
inGroup.append("g").attr('transform','translate(35,15)').append("rect").attr("class","red-ui-flow-port").attr("rx",3).attr("ry",3).attr("width",10).attr("height",10)
var attr_input_translate = (vertical) ? 'translate(15,35)' : 'translate(35,15)';
inGroup.append("g").attr('transform',attr_input_translate).append("rect").attr("class","red-ui-flow-port").attr("rx",3).attr("ry",3).attr("width",10).attr("height",10)
.on("mousedown", function(d,i){portMouseDown(d,PORT_TYPE_OUTPUT,i);} )
.on("touchstart", function(d,i){portMouseDown(d,PORT_TYPE_OUTPUT,i);} )
.on("mouseup", function(d,i){portMouseUp(d,PORT_TYPE_OUTPUT,i);})
@ -2649,8 +2742,8 @@ RED.view = (function() {
}
nodeMouseUp.call(this,d);
});
statusGroup.append("g").attr('transform','translate(-5,15)').append("rect").attr("class","red-ui-flow-port").attr("rx",3).attr("ry",3).attr("width",10).attr("height",10)
var attr_status_translate = (vertical) ? 'translate(15,-5)' : 'translate(-5,15)';
statusGroup.append("g").attr('transform', attr_status_translate).append("rect").attr("class","red-ui-flow-port").attr("rx",3).attr("ry",3).attr("width",10).attr("height",10)
.on("mousedown", function(d,i){portMouseDown(d,PORT_TYPE_INPUT,0);} )
.on("touchstart", function(d,i){portMouseDown(d,PORT_TYPE_INPUT,0);} )
.on("mouseup", function(d,i){portMouseUp(d,PORT_TYPE_INPUT,0);})
@ -2710,14 +2803,23 @@ RED.view = (function() {
var hideLabel = d.hasOwnProperty('l')?!d.l : isLink;
node.attr("id",d.id);
var l = RED.utils.getNodeLabel(d);
if (d.resize || d.w === undefined) {
if (hideLabel) {
d.w = node_height;
} else {
d.w = Math.max(node_width,20*(Math.ceil((calculateTextWidth(l, "red-ui-flow-node-label", 50)+(d._def.inputs>0?7:0))/20)) );
if (vertical) {
d.w = Math.max(node_width,20*(Math.ceil((calculateTextWidth(l, "red-ui-flow-node-label", 50)+(d._def.inputs>0?7:0))/20)),(d.outputs||0) * 15 );
}else{
d.w = Math.max(node_width,20*(Math.ceil((calculateTextWidth(l, "red-ui-flow-node-label", 50)+(d._def.inputs>0?7:0))/20)) );
}
}
}
d.h = Math.max(node_height,(d.outputs||0) * 15);
if (vertical) {
d.h = node_height;
}else{
d.h = Math.max(node_height,(d.outputs||0) * 15);
}
// if (d._def.badge) {
// var badge = node.append("svg:g").attr("class","node_badge_group");
@ -2960,13 +3062,21 @@ RED.view = (function() {
if (d.resize) {
var l = RED.utils.getNodeLabel(d);
var ow = d.w;
if (hideLabel) {
d.w = node_height;
} else {
d.w = Math.max(node_width,20*(Math.ceil((calculateTextWidth(l, "red-ui-flow-node-label", 50)+(d._def.inputs>0?7:0))/20)) );
if (vertical) {
if (hideLabel) {
d.w = node_height
} else {
d.w = Math.max(node_width,20*(Math.ceil((calculateTextWidth(l, "red-ui-flow-node-label", 50)+(d._def.inputs>0?7:0))/20)),(d.outputs||0) * 15 );
}
d.h = node_height;
}else{
if (hideLabel) {
d.w = node_height;
} else {
d.w = Math.max(node_width,20*(Math.ceil((calculateTextWidth(l, "red-ui-flow-node-label", 50)+(d._def.inputs>0?7:0))/20)) );
}
d.h = Math.max(node_height,(d.outputs||0) * 15);
}
// d.w = Math.max(node_width,20*(Math.ceil((calculateTextWidth(l, "red-ui-flow-node-label", 50)+(d._def.inputs>0?7:0))/20)) );
d.h = Math.max(node_height,(d.outputs||0) * 15);
d.x += (d.w-ow)/2;
d.resize = false;
}
@ -3007,7 +3117,7 @@ RED.view = (function() {
if (d.type === "link in") {
inputGroupPorts = inputGroup.append("circle")
.attr("cx",-1).attr("cy",5)
.attr("cx",vertical ? 5 : -1).attr("cy",vertical ? -1 : 5)
.attr("r",5)
.attr("class","red-ui-flow-port red-ui-flow-link-port")
} else {
@ -3031,7 +3141,11 @@ RED.view = (function() {
numOutputs = 0;
}
}
var y = (d.h/2)-((numOutputs-1)/2)*13;
if (vertical) {
var x = (d.w/2)-((numOutputs-1)/2)*13;
}else{
var y = (d.h/2)-((numOutputs-1)/2)*13;
}
d.ports = d.ports || d3.range(numOutputs);
d._ports = thisNode.selectAll(".red-ui-flow-port-output").data(d.ports);
var output_group = d._ports.enter().append("g").attr("class","red-ui-flow-port-output");
@ -3039,7 +3153,7 @@ RED.view = (function() {
if (d.type === "link out") {
output_group_ports = output_group.append("circle")
.attr("cx",11).attr("cy",5)
.attr("cx",vertical ? 6 : 11).attr("cy", vertical ? 11 : 6)
.attr("r",5)
.attr("class","red-ui-flow-port red-ui-flow-link-port")
} else {
@ -3060,11 +3174,21 @@ RED.view = (function() {
d._ports.exit().remove();
if (d._ports) {
numOutputs = d.outputs || 1;
y = (d.h/2)-((numOutputs-1)/2)*13;
var x = d.w - 5;
if (vertical) {
x = (d.w/2)-((numOutputs-1)/2)*13;
var y = d.h - 5;
}else{
y = (d.h/2)-((numOutputs-1)/2)*13;
var x = d.w - 5;
}
d._ports.each(function(d,i) {
var port = d3.select(this);
port.attr("transform", function(d) { return "translate("+x+","+((y+13*i)-5)+")";});
//port.attr("y",(y+13*i)-5).attr("x",x);
if (vertical) {
port.attr("transform", function(d) { return "translate("+((x+13*i)-5)+","+ y +")";});
}else{
port.attr("transform", function(d) { return "translate("+x+","+((y+13*i)-5)+")";});
}
});
}
thisNode.selectAll("text.red-ui-flow-node-label").text(function(d,i){
@ -3117,17 +3241,32 @@ RED.view = (function() {
}
}
thisNode.selectAll(".red-ui-flow-node-changed")
.attr("transform",function(d){return "translate("+(d.w-10)+", -2)"})
.classed("hide",function(d) { return !(d.changed||d.moved); });
if (vertical) {
thisNode.selectAll(".red-ui-flow-node-changed")
.attr("transform",function(d){return "translate("+(d.w-2)+", -2)"})
.classed("hide",function(d) { return !(d.changed||d.moved); });
thisNode.selectAll(".red-ui-flow-node-error")
.attr("transform",function(d){ return "translate("+(d.w-2-((d.changed||d.moved)?14:0))+", -2)"})
.classed("hide",function(d) { return d.valid; });
} else {
thisNode.selectAll(".red-ui-flow-node-changed")
.attr("transform",function(d){return "translate("+(d.w-10)+", -2)"})
.classed("hide",function(d) { return !(d.changed||d.moved); });
thisNode.selectAll(".red-ui-flow-node-error")
.attr("transform",function(d){ return "translate("+(d.w-10-((d.changed||d.moved)?14:0))+", -2)"})
.classed("hide",function(d) { return d.valid; });
}
thisNode.selectAll(".red-ui-flow-node-error")
.attr("transform",function(d){ return "translate("+(d.w-10-((d.changed||d.moved)?14:0))+", -2)"})
.classed("hide",function(d) { return d.valid; });
thisNode.selectAll(".red-ui-flow-port-input").each(function(d,i) {
var port = d3.select(this);
port.attr("transform",function(d){return "translate(-5,"+((d.h/2)-5)+")";})
var port = d3.select(this);
if (vertical) {
port.attr("transform",function(d){return "translate("+((d.w/2)-5)+", -5)";})
}else{
port.attr("transform",function(d){return "translate(-5,"+((d.h/2)-5)+")";})
}
});
thisNode.selectAll(".red-ui-flow-node-icon").attr("y",function(d){return (d.h-d3.select(this).attr("height"))/2;});
@ -3192,9 +3331,17 @@ RED.view = (function() {
var fill = status_colours[d.status.fill]; // Only allow our colours for now
if (d.status.shape == null && fill == null) {
thisNode.selectAll(".red-ui-flow-node-status").style("display","none");
thisNode.selectAll(".red-ui-flow-node-status-group").attr("transform","translate(-14,"+(d.h+3)+")");
if (vertical) {
thisNode.selectAll(".red-ui-flow-node-status-group").attr("transform","translate(" + (-14+d.w/2) + ","+(d.h+3)+")");
} else {
thisNode.selectAll(".red-ui-flow-node-status-group").attr("transform","translate(-14,"+(d.h+3)+")");
}
} else {
thisNode.selectAll(".red-ui-flow-node-status-group").attr("transform","translate(3,"+(d.h+3)+")");
if (vertical) {
thisNode.selectAll(".red-ui-flow-node-status-group").attr("transform","translate(" + (3 + d.w/2) + ","+(d.h+3)+")");
} else {
thisNode.selectAll(".red-ui-flow-node-status-group").attr("transform","translate(3,"+(d.h+3)+")");
}
var statusClass = "red-ui-flow-node-status-"+(d.status.shape||"dot")+"-"+d.status.fill;
thisNode.selectAll(".red-ui-flow-node-status").style("display","inline").attr("class","red-ui-flow-node-status "+statusClass);
}
@ -3279,17 +3426,23 @@ RED.view = (function() {
link.attr("d",function(d){
var numOutputs = d.source.outputs || 1;
var sourcePort = d.sourcePort || 0;
var y = -((numOutputs-1)/2)*13 +13*sourcePort;
d.x1 = d.source.x+d.source.w/2;
d.y1 = d.source.y+y;
d.x2 = d.target.x-d.target.w/2;
d.y2 = d.target.y;
var path;
if (vertical) {
var x = -((numOutputs-1)/2)*13 +13*sourcePort;
d.x1 = d.source.x+x;
d.y1 = d.source.y+d.source.h/2;
d.x2 = d.target.x;
d.y2 = d.target.y-d.target.h/2;
path = generateLinkPathV(d.x1,d.y1,d.x2,d.y2,1);
}else{
var y = -((numOutputs-1)/2)*13 +13*sourcePort;
d.x1 = d.source.x+d.source.w/2;
d.y1 = d.source.y+y;
d.x2 = d.target.x-d.target.w/2;
d.y2 = d.target.y;
path = generateLinkPath(d.x1,d.y1,d.x2,d.y2,1);
}
// return "M "+d.x1+" "+d.y1+
// " C "+(d.x1+scale*node_width)+" "+(d.y1+scaleY*node_height)+" "+
// (d.x2-scale*node_width)+" "+(d.y2-scaleY*node_height)+" "+
// d.x2+" "+d.y2;
var path = generateLinkPath(d.x1,d.y1,d.x2,d.y2,1);
if (/NaN/.test(path)) {
return ""
}
@ -3780,6 +3933,14 @@ RED.view = (function() {
updateGrid();
}
},
vertical: function(v) {
if (v === undefined) {
return vertical;
} else {
vertical = v;
RED.view.redraw();
}
},
getActiveNodes: function() {
return activeNodes;
},