From 0893555fd9f9742034af4c312ab9a61c66166c62 Mon Sep 17 00:00:00 2001 From: afonso Date: Fri, 19 May 2023 14:14:33 +0100 Subject: [PATCH 01/15] PSYNEU-49 feat: WIP - Update mechanisms ports location --- .../editView/mechanisms/InputOutputNode.js | 23 +-- .../views/editView/mechanisms/MechMetadata.js | 161 +++++++++--------- .../editView/projections/CustomLinkWidget.js | 44 +++-- src/client/services/clippingService.ts | 4 +- src/index.css | 4 +- 5 files changed, 133 insertions(+), 103 deletions(-) diff --git a/src/client/components/views/editView/mechanisms/InputOutputNode.js b/src/client/components/views/editView/mechanisms/InputOutputNode.js index 4dea3395..b63b688c 100644 --- a/src/client/components/views/editView/mechanisms/InputOutputNode.js +++ b/src/client/components/views/editView/mechanisms/InputOutputNode.js @@ -1,18 +1,21 @@ import * as React from "react"; import { Box, Typography } from "@mui/material"; +import {PortWidget} from "@projectstorm/react-diagrams"; class InputOutputNode extends React.Component { - render() { - const { text, direction } = this.props; - const nodeClass = direction === 'right' ? 'block reverse' : 'block'; + render() { + const { text, direction, engine, port } = this.props; + const nodeClass = direction === 'right' ? 'block reverse' : 'block'; - return ( - - - {text} - - ); - } + return ( + + + + + {text} + + ); + } } export default InputOutputNode; diff --git a/src/client/components/views/editView/mechanisms/MechMetadata.js b/src/client/components/views/editView/mechanisms/MechMetadata.js index 75e2aaa9..92111811 100644 --- a/src/client/components/views/editView/mechanisms/MechMetadata.js +++ b/src/client/components/views/editView/mechanisms/MechMetadata.js @@ -1,30 +1,30 @@ import * as React from "react"; import Box from "@mui/material/Box"; -import { withStyles } from "@mui/styles"; +import {withStyles} from "@mui/styles"; import NodeSelection from "./NodeSelection"; import InputOutputNode from "./InputOutputNode"; // import TextField from '@mui/material/TextField'; import Typography from "@mui/material/Typography"; -import { PortTypes, PortWidget } from "@metacell/meta-diagram"; +import {PortTypes} from "@metacell/meta-diagram"; import vars from "../../../../assets/styles/variables"; const styles = { - textColor: { - color: vars.functionTextColor - }, - codeColor: { - color: vars.functionCodeColor + textColor: { + color: vars.functionTextColor + }, + codeColor: { + color: vars.functionCodeColor } }; class MechMetadata extends React.Component { - render() { - const { classes, model, model: { options }, engine, changeVisibility } = this.props; - console.log(classes) - const functionValues = (label, value) => ( - - {label} - {/* ( + + {label} + {/* */} - {value} - - ) + {value} + + ) - return ( - - {options.selected && ( - - )} - - - - {options.name} - - + return ( + + {options.selected && ( + + )} + + + + {options.name} + + - - { options.ports.map(port => { - switch (port.getType()) { - case PortTypes.INPUT_PORT: - return ( - - - - ); - default: - return <> - } - })} - + + {options.ports.map(port => { + switch (port.getType()) { + case PortTypes.INPUT_PORT: + return ( + + ); + default: + return <> + } + })} + - + - - { - functionValues('Context', '12') - } - { - functionValues('Size', '8.90') - } - { - functionValues('Prefs', '44') - } - - Function - - - function - =pnl.Logistic(gain=1.0, bias=-4) - - + + { + functionValues('Context', '12') + } + { + functionValues('Size', '8.90') + } + { + functionValues('Prefs', '44') + } + + Function + + + function + =pnl.Logistic(gain=1.0, + bias=-4) + + - + - - { options.ports.map(port => { - switch (port.getType()) { - case PortTypes.OUTPUT_PORT: - return ( - - - - ); - default: - return <> - } - })} - - - ); - } + + {options.ports.map(port => { + switch (port.getType()) { + case PortTypes.OUTPUT_PORT: + return ( + + ) + ; + default: + return <> + } + })} + + + ); + } } export default withStyles(styles)(MechMetadata); diff --git a/src/client/components/views/editView/projections/CustomLinkWidget.js b/src/client/components/views/editView/projections/CustomLinkWidget.js index ef607366..37192fa8 100644 --- a/src/client/components/views/editView/projections/CustomLinkWidget.js +++ b/src/client/components/views/editView/projections/CustomLinkWidget.js @@ -6,6 +6,8 @@ import { updateLinkPoints } from "../../../../services/clippingService"; import {CallbackTypes} from "@metacell/meta-diagram"; +import {PointModel} from "@projectstorm/react-diagrams-core"; +import {Point} from "@projectstorm/geometry"; const pointlength = 6; @@ -24,7 +26,7 @@ const CustomLinkArrowWidget = (props) => { 90 + (Math.atan2( point.getY() - previousPoint.getY(), - (point.getX() - 10) - (previousPoint.getX() + 10) + (point.getX()) - (previousPoint.getX()) ) * 180) / Math.PI; @@ -132,6 +134,26 @@ export class CustomLinkWidget extends DefaultLinkWidget { }) } + getEdgePoint(center, source, radius, link) { + // Calculate the direction of the link + let dx = source.x - center.x; + let dy = source.y - center.y; + + // Normalize the direction to have a length of 1 + let length = Math.sqrt(dx * dx + dy * dy); + dx /= length; + dy /= length; + + // Scale the direction by the radius of the node to get the edge point + let edgeX = center.x + dx * radius; + let edgeY = center.y + dy * radius; + + return new PointModel({ + link: link, + position: new Point(edgeX, edgeY) + }); + } + /** * Generates a custom arrow for the link. * @@ -167,7 +189,7 @@ export class CustomLinkWidget extends DefaultLinkWidget { const angle = (Math.atan2(lastPoint.y - firstPoint.y, (lastPoint.x) - (firstPoint.x)) * 180) / Math.PI; let newX = Math.round(Math.cos(angle * Math.PI / 180) * newDistance + firstPoint.x); let newY = Math.round(Math.sin(angle * Math.PI / 180) * newDistance + firstPoint.y); - return `M${firstPoint.x - 10},${firstPoint.y} L ${newX},${newY}`; + return `M${firstPoint.x},${firstPoint.y} L ${newX},${newY}`; } /** @@ -284,7 +306,6 @@ export class CustomLinkWidget extends DefaultLinkWidget { } - /** Renders the CustomLinkWidget component. @@ -305,6 +326,9 @@ export class CustomLinkWidget extends DefaultLinkWidget { const paths = []; this.refPaths = []; + const edgePoint = this.getEdgePoint(targetPort.getCenter(), sourcePort.getCenter(), + targetPort.getParent().getBoundingBox().getWidth() / 2, link) + //draw the multiple anchors and complex line instead for (let j = 0; j < points.length - 1; j++) { paths.push( @@ -312,19 +336,19 @@ export class CustomLinkWidget extends DefaultLinkWidget { key={`link-from-${points[j].getID()}-to-${points[j + 1].getID()}`} path={this.generateLinePath( {x: points[j].getX(), y: points[j].getY()}, - {x: points[j + 1].getX(), y: points[j + 1].getY()} + {x: edgePoint.getX(), y: edgePoint.getY()} )} {...this.props} /> ); } - if (link.getTargetPort() !== null) { - if (!(this.portsHaveSameParent() && this.isTargetPortHidden())) { - paths.push(this.generateArrow(points[points.length - 1], points[points.length - 2])); - } - } else { - paths.push(this.generatePoint(points[points.length - 1])); + // we draw an arrow in all situations except when both source and target ports have the same parent and the + // target port is fully hidden + if (!(this.portsHaveSameParent() && this.isTargetPortHidden())) { + + paths.push( + this.generateArrow(edgePoint, points[points.length - 2])) } return Date: Fri, 19 May 2023 15:00:42 +0100 Subject: [PATCH 02/15] PSYNEU-49 fix: Fix crash on link between single nodes --- .../views/editView/projections/CustomLinkWidget.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/client/components/views/editView/projections/CustomLinkWidget.js b/src/client/components/views/editView/projections/CustomLinkWidget.js index 37192fa8..de122d20 100644 --- a/src/client/components/views/editView/projections/CustomLinkWidget.js +++ b/src/client/components/views/editView/projections/CustomLinkWidget.js @@ -294,6 +294,9 @@ export class CustomLinkWidget extends DefaultLinkWidget { const targetPort = this.props.link.getTargetPort() const node = targetPort.getParent() const parentNode = ModelSingleton.getInstance().getMetaGraph().getParent(node); + if(!parentNode) { + return false + } const parentNodeBoundingBox = parentNode.getBoundingBox(); const targetPortPosition = targetPort.getPosition(); @@ -343,10 +346,10 @@ export class CustomLinkWidget extends DefaultLinkWidget { ); } - // we draw an arrow in all situations except when both source and target ports have the same parent and the - // target port is fully hidden - if (!(this.portsHaveSameParent() && this.isTargetPortHidden())) { + // we draw an arrow in all situations except when both source and target ports have the same parent + // (excluding undefined as parent) and the target port is fully hidden + if (!(this.portsHaveSameParent() && this.isTargetPortHidden())) { paths.push( this.generateArrow(edgePoint, points[points.length - 2])) } From a843eebd581022076575c9b6aba9952a853dafe1 Mon Sep 17 00:00:00 2001 From: afonso Date: Fri, 19 May 2023 15:27:45 +0100 Subject: [PATCH 03/15] PSYNEU-49 feat: WIP - Update clipping link logic --- .../editView/projections/CustomLinkWidget.js | 38 ++++++------------- src/client/services/clippingService.ts | 20 ++++++++++ 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/client/components/views/editView/projections/CustomLinkWidget.js b/src/client/components/views/editView/projections/CustomLinkWidget.js index de122d20..270241f8 100644 --- a/src/client/components/views/editView/projections/CustomLinkWidget.js +++ b/src/client/components/views/editView/projections/CustomLinkWidget.js @@ -3,6 +3,7 @@ import {DefaultLinkWidget} from '@projectstorm/react-diagrams'; import {projectionLink, projectionLinkArrow} from "../../../../assets/styles/variables"; import ModelSingleton from "../../../../model/ModelSingleton"; import { + getEdgePoint, updateLinkPoints } from "../../../../services/clippingService"; import {CallbackTypes} from "@metacell/meta-diagram"; @@ -134,25 +135,6 @@ export class CustomLinkWidget extends DefaultLinkWidget { }) } - getEdgePoint(center, source, radius, link) { - // Calculate the direction of the link - let dx = source.x - center.x; - let dy = source.y - center.y; - - // Normalize the direction to have a length of 1 - let length = Math.sqrt(dx * dx + dy * dy); - dx /= length; - dy /= length; - - // Scale the direction by the radius of the node to get the edge point - let edgeX = center.x + dx * radius; - let edgeY = center.y + dy * radius; - - return new PointModel({ - link: link, - position: new Point(edgeX, edgeY) - }); - } /** * Generates a custom arrow for the link. @@ -294,7 +276,7 @@ export class CustomLinkWidget extends DefaultLinkWidget { const targetPort = this.props.link.getTargetPort() const node = targetPort.getParent() const parentNode = ModelSingleton.getInstance().getMetaGraph().getParent(node); - if(!parentNode) { + if (!parentNode) { return false } const parentNodeBoundingBox = parentNode.getBoundingBox(); @@ -318,10 +300,17 @@ export class CustomLinkWidget extends DefaultLinkWidget { render() { const {link} = this.props - let points = [...link.getPoints()] + const sourcePort = link.getSourcePort(); const targetPort = link.getTargetPort(); + let points = [ + getEdgePoint(sourcePort.getCenter(), targetPort.getCenter(), + sourcePort.getParent().getBoundingBox().getWidth() / 2, link), + getEdgePoint(targetPort.getCenter(), sourcePort.getCenter(), + targetPort.getParent().getBoundingBox().getWidth() / 2, link) + ] + updateLinkPoints(sourcePort, link, points, 0); updateLinkPoints(targetPort, link, points, 1); @@ -329,9 +318,6 @@ export class CustomLinkWidget extends DefaultLinkWidget { const paths = []; this.refPaths = []; - const edgePoint = this.getEdgePoint(targetPort.getCenter(), sourcePort.getCenter(), - targetPort.getParent().getBoundingBox().getWidth() / 2, link) - //draw the multiple anchors and complex line instead for (let j = 0; j < points.length - 1; j++) { paths.push( @@ -339,7 +325,7 @@ export class CustomLinkWidget extends DefaultLinkWidget { key={`link-from-${points[j].getID()}-to-${points[j + 1].getID()}`} path={this.generateLinePath( {x: points[j].getX(), y: points[j].getY()}, - {x: edgePoint.getX(), y: edgePoint.getY()} + {x: points[j+1].getX(), y: points[j+1].getY()} )} {...this.props} /> @@ -351,7 +337,7 @@ export class CustomLinkWidget extends DefaultLinkWidget { if (!(this.portsHaveSameParent() && this.isTargetPortHidden())) { paths.push( - this.generateArrow(edgePoint, points[points.length - 2])) + this.generateArrow(points[points.length - 1], points[points.length - 2])) } return Date: Fri, 19 May 2023 16:57:02 +0100 Subject: [PATCH 04/15] PSYNEU-49 feat: WIP - Update link and arrow generation --- .../editView/projections/CustomLinkWidget.js | 50 ++++------------ src/client/services/clippingService.ts | 59 ++++++++----------- src/constants.ts | 2 - 3 files changed, 38 insertions(+), 73 deletions(-) diff --git a/src/client/components/views/editView/projections/CustomLinkWidget.js b/src/client/components/views/editView/projections/CustomLinkWidget.js index 270241f8..a0894b88 100644 --- a/src/client/components/views/editView/projections/CustomLinkWidget.js +++ b/src/client/components/views/editView/projections/CustomLinkWidget.js @@ -3,14 +3,10 @@ import {DefaultLinkWidget} from '@projectstorm/react-diagrams'; import {projectionLink, projectionLinkArrow} from "../../../../assets/styles/variables"; import ModelSingleton from "../../../../model/ModelSingleton"; import { - getEdgePoint, - updateLinkPoints + getEdgePoint, updateLinkPoints } from "../../../../services/clippingService"; import {CallbackTypes} from "@metacell/meta-diagram"; -import {PointModel} from "@projectstorm/react-diagrams-core"; -import {Point} from "@projectstorm/geometry"; -const pointlength = 6; /** * CustomLinkArrowWidget is a functional React component that renders a custom arrow for the link. @@ -22,6 +18,7 @@ const pointlength = 6; */ const CustomLinkArrowWidget = (props) => { const {point, previousPoint} = props; + const POINTS_LENGTH = 6; const angle = 90 + @@ -35,9 +32,9 @@ const CustomLinkArrowWidget = (props) => { return ( - +