Skip to content

Commit

Permalink
#36 moving logic from graph to children for metanodes
Browse files Browse the repository at this point in the history
  • Loading branch information
ddelpiano committed Oct 15, 2022
1 parent feb3dd0 commit 13e18e4
Show file tree
Hide file tree
Showing 6 changed files with 207 additions and 98 deletions.
17 changes: 16 additions & 1 deletion src/components/Main.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,29 @@ class Main extends React.Component {
this.componentsMap.nodes.set(PNLClasses.COMPOSITION, Composition);
this.componentsMap.nodes.set(PNLClasses.MECHANISM, GenericMechanism);
this.componentsMap.links.set(PNLClasses.PROJECTION, CustomLinkWidget);

this.metaCallback = this.metaCallback.bind(this);
}

shouldComponentUpdate() {
return false;
}

metaCallback(event) {
console.log('metacallback');
console.log(event);
}

render() {
const { classes } = this.props;

return (
<div className={classes.root}>
<MetaDiagram metaNodes={[...this.metaModel[PNLClasses.COMPOSITION], ...this.metaModel[PNLClasses.MECHANISM]]} metaLinks={this.metaModel[PNLClasses.PROJECTION]} componentsMap={this.componentsMap}
<MetaDiagram
metaCallback={this.metaCallback}
componentsMap={this.componentsMap}
metaLinks={this.metaModel[PNLClasses.PROJECTION]}
metaNodes={[...this.metaModel[PNLClasses.COMPOSITION], ...this.metaModel[PNLClasses.MECHANISM]]}
metaTheme={{
customThemeVariables: {},
canvasClassName: classes.canvasBG,
Expand Down
8 changes: 4 additions & 4 deletions src/components/views/compositions/Composition.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,10 @@ class Composition extends React.Component {
super(props);
this.state = {
expanded: false,
width: 442,
height: 192,
x: 0,
y: 0
width: props.model.options.width,
height: props.model.options.height,
x: props.model.options.x,
y: props.model.options.y
}
this.changeVisibility = this.changeVisibility.bind(this);
}
Expand Down
20 changes: 19 additions & 1 deletion src/components/views/mechanisms/MechMetadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,24 @@ class MechMetadata extends React.Component {
{/* <Typography>{value}</Typography> */}
</Box>
)

const updateOptionField = (label, value) => (
<Box className={classes.cardSecondary}>
<Typography component="label">{label}</Typography>
<TextField
id="outlined-multiline-flexible"
maxRows={4}
value={value}
onChange={ (e) => {
model.setOption(label, e.target.value)
}}
variant="outlined"
style={{ zIndex: 11 }}
/>
{/* <Typography>{value}</Typography> */}
</Box>
)

return (
<>
{options.selected && (
Expand Down Expand Up @@ -154,7 +172,7 @@ class MechMetadata extends React.Component {
functionValues('Size', '8.90')
}
{
functionValues('Prefs', '44')
updateOptionField('variant', options.variant)
}
<Box className={classes.cardSecondary}>
<Typography component="label">Function</Typography>
Expand Down
80 changes: 40 additions & 40 deletions src/model/Interpreter.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { PNLClasses } from '../constants';
import { MetaLink, MetaNode, PortTypes } from '@metacell/meta-diagram';
import ProjectionLink from './links/ProjectionLink';
import QueryService from '../services/queryService';
import MechanismNode from './nodes/mechanism/MechanismNode';
import CompositionNode from './nodes/composition/CompositionNode';
import { MetaLink, MetaNode, PortTypes } from '@metacell/meta-diagram';

export default class ModelInterpreter {
nativeModel: any;
Expand Down Expand Up @@ -36,14 +36,14 @@ export default class ModelInterpreter {
}

_convertModel(model: any) : Object {
model[PNLClasses.MECHANISM].forEach((singleNode: any) => {
this.castMechanism(singleNode, undefined, this.modelMap);
});
model[PNLClasses.COMPOSITION].forEach((singleModel: any) => {
this.nodeIdsMap = new Map();
this.linkIdsMap = new Map();
this.castComposition(singleModel, undefined, this.modelMap);
});
model[PNLClasses.MECHANISM].forEach((singleNode: any) => {
this.castMechanism(singleNode, undefined, this.modelMap);
});
this.setMetaModel()
return this.pnlModel;
}
Expand Down Expand Up @@ -88,7 +88,6 @@ export default class ModelInterpreter {
};

const result = QueryService.getPorts(name, type);

if (result !== '') {
const parsedPorts = result.replace('[', '').replace(']', '').split(', ');
parsedPorts.forEach(element => {
Expand All @@ -113,7 +112,7 @@ export default class ModelInterpreter {
item: MechanismNode|CompositionNode|ProjectionLink|any,
parent: any|undefined,
modelMap: { [key: string]: Map<String, CompositionNode|MechanismNode|ProjectionLink|any> })
: MechanismNode|CompositionNode|ProjectionLink {
: CompositionNode {
let newNode = item;
let extra: { [key: string]: any } = {};
let ports : any = [];
Expand All @@ -125,12 +124,18 @@ export default class ModelInterpreter {
};
if (item?.bb) {
let _vertices = item.bb.split(',');
boundingBox.llx = _vertices[0];
boundingBox.lly = _vertices[1];
boundingBox.urx = _vertices[2];
boundingBox.ury = _vertices[3];
boundingBox.llx = parseFloat(_vertices[0]);
boundingBox.lly = parseFloat(_vertices[1]);
boundingBox.urx = parseFloat(_vertices[2]);
boundingBox.ury = parseFloat(_vertices[3]);
}
extra['boundingBox'] = boundingBox;
extra['position'] = {
x: boundingBox.llx,
y: boundingBox.lly
}
newNode = new CompositionNode(item?.name, parent, '', false, ports, extra, undefined, boundingBox);
extra['isExpanded'] = false;
newNode = new CompositionNode(item?.name, parent, ports, extra);
modelMap['nodes'].set(newNode.getName(), newNode);
// temp array to host all the nested compositions
let childrenCompositions: Array<any> = [];
Expand All @@ -143,6 +148,7 @@ export default class ModelInterpreter {
childrenCompositions.push(child)
} else {
newChild = this.castMechanism(child, newNode, this.modelMap);
newChild.setParent(newNode);
newNode.addChild(newChild);
}
if (newChild && !this.nodeIdsMap.has(child?._gvid)) {
Expand All @@ -164,12 +170,11 @@ export default class ModelInterpreter {
item.edges.forEach((edge: any) => {
let tail = this.nodeIdsMap.get(edge.tail);
let head = this.nodeIdsMap.get(edge.head);
// TODO: adjust the cast method below with tail and head
let newChild = this.castEdge(edge, tail, head, newNode, this.modelMap);
if (newChild && !this.linkIdsMap.has(edge?._gvid)) {
this.linkIdsMap.set(edge?._gvid, newChild);
}
newNode.addChild(newChild);
// newNode.addChild(newChild);
});

this.pnlModel[PNLClasses.COMPOSITION].push(newNode);
Expand All @@ -180,7 +185,7 @@ export default class ModelInterpreter {
item: MechanismNode|CompositionNode|ProjectionLink|any,
parent: CompositionNode,
modelMap: { [key: string]: Map<String, CompositionNode|MechanismNode|ProjectionLink|any> })
: MechanismNode|CompositionNode|ProjectionLink {
: CompositionNode {
let newNode = item;
let extra: { [key: string]: any } = {};
let ports : any = [];
Expand All @@ -192,12 +197,18 @@ export default class ModelInterpreter {
};
if (item?.bb) {
let _vertices = item.bb.split(',');
boundingBox.llx = _vertices[0];
boundingBox.lly = _vertices[1];
boundingBox.urx = _vertices[2];
boundingBox.ury = _vertices[3];
boundingBox.llx = parseFloat(_vertices[0]);
boundingBox.lly = parseFloat(_vertices[1]);
boundingBox.urx = parseFloat(_vertices[2]);
boundingBox.ury = parseFloat(_vertices[3]);
}
extra['boundingBox'] = boundingBox;
extra['position'] = {
x: boundingBox.llx,
y: boundingBox.lly
}
newNode = new CompositionNode(item?.name, parent, '', false, ports, extra, undefined, boundingBox);
extra['isExpanded'] = false;
newNode = new CompositionNode(item?.name, parent, ports, extra);
modelMap['nodes'].set(newNode.getName(), newNode);

// Iterates nodes of the nested composition to fill the children map/array
Expand All @@ -218,21 +229,17 @@ export default class ModelInterpreter {
item: MechanismNode|CompositionNode|ProjectionLink|any,
parent: CompositionNode|undefined,
modelMap: { [key: string]: Map<String, CompositionNode|MechanismNode|ProjectionLink|any> })
: MechanismNode|CompositionNode|ProjectionLink {
: MechanismNode {
let newNode = item;
let ports: { [key: string]: any } = this.parseNodePorts(item?.name, PNLClasses.MECHANISM);
let extra: { [key: string]: any } = {};
let coordinates = item.pos.split(',');
newNode = new MechanismNode(
item?.name,
parent,
'',
false,
ports,
extra,
coordinates[0],
coordinates[1],
);
let ports: { [key: string]: any } = this.parseNodePorts(item?.name, PNLClasses.MECHANISM);
let extra: { [key: string]: any } = {
position: {
x: parseFloat(coordinates[0]),
y: parseFloat(coordinates[1])
}
};
newNode = new MechanismNode(item?.name, parent, ports, extra,);
modelMap['nodes'].set(newNode.getName(), newNode);
this.pnlModel[PNLClasses.MECHANISM].push(newNode);
return newNode;
Expand All @@ -244,13 +251,11 @@ export default class ModelInterpreter {
receiver: MechanismNode|CompositionNode,
parent: CompositionNode|undefined,
modelMap: { [key: string]: Map<String, CompositionNode|MechanismNode|ProjectionLink|any> })
: MechanismNode|CompositionNode|ProjectionLink {
: ProjectionLink {
let newNode = item;
let name = '';
let extra: { [key: string]: any } = {};
let senderPortName, receiverPortName;
// senderPortName = this.getPortName(item.tailport);
// receiverPortName = this.getPortName(item.headport);
senderPortName = item.tailport;
receiverPortName = item.headport;
newNode = new ProjectionLink(
Expand All @@ -266,9 +271,4 @@ export default class ModelInterpreter {
this.pnlModel[PNLClasses.PROJECTION].push(newNode);
return newNode;
}

getPortName(portString: string): string {
const [portType, ...portName] = portString.split('-');
return portName.join('-');
}
}
83 changes: 64 additions & 19 deletions src/model/nodes/composition/CompositionNode.ts
Original file line number Diff line number Diff line change
@@ -1,47 +1,70 @@
import { PNLClasses } from '../../../constants';
import ModelInterpreter from '../../Interpreter';
import MechanismNode from '../mechanism/MechanismNode';
import ProjectionLink from '../../links/ProjectionLink';
import { MetaNode, MetaPort, Position, PortTypes } from '@metacell/meta-diagram';
import { MetaNode, MetaPort, Position } from '@metacell/meta-diagram';
import { ExtraObject } from '../utils';

export default class CompositionNode extends MechanismNode {
children: {[key: string]: any};
metaChildren: Array<MetaNode>;
childrenMap: Map<string, MechanismNode|CompositionNode|ProjectionLink>;
innerClass: string;
boundingBox: {[key: string]: Number}|undefined;

constructor(
name: string,
parent: CompositionNode|undefined,
icon?: string,
isExpaded?: boolean,
ports?: { [key: string]: Array<any> },
extra?: Object,
children?: {[key: string]: any},
boundingBox?: {[key: string]: Number}|undefined)
extra?: ExtraObject,
children?: {[key: string]: any})
{
super(name, parent, icon, isExpaded, ports, extra);
super(name, parent, ports, extra);

this.childrenMap = new Map();
this.children = children !== undefined ? children : {
[PNLClasses.MECHANISM]: [],
[PNLClasses.PROJECTION]: [],
[PNLClasses.COMPOSITION]: [],
};

this.metaChildren = [];
if (children) {
children[PNLClasses.COMPOSITION].forEach((child: any) => {
if (this.childrenMap.has(child.getName())) {
throw Error('ChildrenMap already has an object with that name.');
}
this.childrenMap.set(child.getName(), child);
this.metaChildren.push(child.getMetaNode());
});
children[PNLClasses.MECHANISM].forEach((child: any) => {
if (this.childrenMap.has(child.getName())) {
throw Error('ChildrenMap already has an object with that name.');
}
this.childrenMap.set(child.getName(), child);
this.metaChildren.push(child.getMetaNode());
});
}

if (this.extra?.boundingBox) {
this.extra.position = {
x: this.extra.boundingBox.llx + 75,
y: this.extra.boundingBox.lly + 75
}
}

this.innerClass = PNLClasses.COMPOSITION;
this.boundingBox = boundingBox;
}

addChild(child: MechanismNode|CompositionNode|ProjectionLink) {
addChild(child: MechanismNode|CompositionNode) {
if (!this.childrenMap.has(child.getName())) {
this.childrenMap.set(child.getName(), child);
this.metaChildren.push(child.getMetaNode());
}
this.children[child.getType()].push(child);
}

removeChild(child: MechanismNode|CompositionNode|ProjectionLink) {
removeChild(child: MechanismNode|CompositionNode) {
if (this.childrenMap.has(child.getName())) {
this.childrenMap.delete(child.getName());
this.metaChildren = this.metaChildren.filter((item: MetaNode) => item.getId() !== child.getName());
}
switch (child.getType()) {
case PNLClasses.MECHANISM: {
Expand Down Expand Up @@ -73,26 +96,48 @@ export default class CompositionNode extends MechanismNode {
return this.innerClass;
}

getPosition(): Position {
if (this.extra?.position === undefined) {
this.setPosition(Math.random() * 900, Math.random() * 900);
}

return new Position(
// @ts-ignore
this.extra.position.x + 75, this.extra.position.y + 75
);
}

getMetaNode() : any {
// TODO: get position from the graphviz data
let x = 200 + Math.random() * 600;
let y = 200 + Math.random() * 600;
let parent = this.parent ? this.parent.getMetaNode() : undefined;
// @ts-ignore
const width = Math.abs(parseFloat(this.extra.boundingBox['llx']) - parseFloat(this.extra.boundingBox['urx']));
// @ts-ignore
const height = Math.abs(parseFloat(this.extra.boundingBox['ury']) - parseFloat(this.extra.boundingBox['lly']));
const compositions = this.children[PNLClasses.COMPOSITION].map((child: CompositionNode) => {
return child.getMetaNode()
});
const mechanisms = this.children[PNLClasses.MECHANISM].map((child: MechanismNode) => {
return child.getMetaNode()
});
const family = [...compositions, ...mechanisms];
let ports: Array<MetaPort> = []
return new MetaNode(
this.name,
this.name,
PNLClasses.COMPOSITION,
new Position(x, y),
this.getPosition(),
'node-gray',
parent,
this.metaParent,
ports,
family,
new Map(Object.entries({
name: 'Mechanism Name',
variant: 'node-gray',
pnlClass: 'ProcessingMechanism',
shape: 'circle',
selected: false
selected: false,
width: width,
height: height,
})
)
);
Expand Down
Loading

0 comments on commit 13e18e4

Please sign in to comment.