Skip to content

Commit

Permalink
#36 composition implementation, metanode instantiation and pluggin re…
Browse files Browse the repository at this point in the history
…quired parts of the library
  • Loading branch information
ddelpiano committed Sep 5, 2022
1 parent c2f503d commit 2d2d5de
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 75 deletions.
18 changes: 10 additions & 8 deletions src/components/Main.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import React from 'react';
// import MechanismNode from '../model/nodes/mechanism/MechanismNode';
import { withStyles } from '@mui/styles';
import { PNLClasses } from '../constants';
import { buildModel } from '../model/utils';
import BG from "../assets/svg/bg-dotted.svg";
import ModelInterpreter from '../model/Interpreter';
import Composition from './views/compositions/Composition';
import GenericMechanism from './views/mechanisms/GenericMechanism';
import MetaDiagram, { ComponentsMap } from "@metacell/meta-diagram";
import CustomLinkWidget from './views/projections/CustomLinkWidget';
import GenericMechanism from './views/mechanisms/GenericMechanism';
import { buildModel } from '../model/utils';
import { PNLClasses } from '../constants';

const mockModel = require('../resources/model').mockModel;

Expand All @@ -33,14 +34,15 @@ class Main extends React.Component {
const model = interpreter.getModel();
const metaModel = buildModel(model);

const componentsMap = new ComponentsMap(
new Map(Object.entries({'mechanism': GenericMechanism})),
new Map(Object.entries({'projection': CustomLinkWidget}))
)
const componentsMap = new ComponentsMap(new Map(), new Map());

componentsMap.nodes.set(PNLClasses.COMPOSITION, Composition);
componentsMap.nodes.set(PNLClasses.MECHANISM, GenericMechanism);
componentsMap.links.set(PNLClasses.PROJECTION, CustomLinkWidget);

return (
<div className={classes.root}>
<MetaDiagram metaNodes={metaModel[PNLClasses.MECHANISM]} metaLinks={metaModel[PNLClasses.PROJECTION]} componentsMap={componentsMap}
<MetaDiagram metaNodes={[...metaModel[PNLClasses.COMPOSITION], ...metaModel[PNLClasses.MECHANISM],]} metaLinks={metaModel[PNLClasses.PROJECTION]} componentsMap={componentsMap}
metaTheme={{
customThemeVariables: {},
canvasClassName: classes.canvasBG,
Expand Down
123 changes: 123 additions & 0 deletions src/components/views/compositions/Composition.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import * as React from "react";
import { Rnd } from "react-rnd";
import { withStyles } from "@mui/styles";
import { Box, Chip } from "@mui/material";
import vars from "../../../assets/styles/variables";
import MORE_OPTION from "../../../assets/svg/option.svg"

const { draggableBg, listItemActiveBg, textWhite, chipTextColor, chipBorderColor } = vars;

const commonStyles = {
background: `${textWhite} !important`,
border: `0.0975rem solid ${listItemActiveBg} !important`,
borderRadius: '0.125rem !important'
};

const styles = () => ({
root: {
'& .react-draggable': {
background: draggableBg,
border: `0.125rem solid ${chipBorderColor}`,
borderRadius: '0.75rem',
display: "flex !important",
alignItems: "center",
justifyContent: "center",

'&:hover': {
borderColor: listItemActiveBg
},
},

'& .MuiChip-root': {
background: chipBorderColor,
borderRadius: '0.75rem',
padding: '0 0.5rem',
display: "flex",
left: 0,
position: 'absolute',
color: chipTextColor,
top: '-1.75rem',
alignItems: "center",
height: '1.5rem',
letterSpacing: '-0.005rem',
fontWeight: 510,
fontSize: '0.8125rem',
lineHeight: '1.25rem',
flexDirection: 'row-reverse',

'& .MuiChip-label': {
padding: 0,
},

'& .MuiChip-icon': {
margin: '0 0 0 0.25rem',
},
},
},

selected: {
'&:before': {
left: 0,
...commonStyles
},

'&:after': {
right: 0,
...commonStyles
},

'& .MuiChip-root': {
background: listItemActiveBg
},

'& .react-draggable': {
borderColor: listItemActiveBg,
}
},
});

class Composition extends React.Component {
constructor(props) {
super(props);
this.state = {
expanded: false,
width: 442,
height: 192,
x: 0,
y: 0
}
this.changeVisibility = this.changeVisibility.bind(this);
}

changeVisibility() {
this.setState({expanded: !this.state.expanded});
}

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

return (
<Box className={`${classes.root} ${expanded ? classes.selected : ''}`}>
<Rnd
size={{ width: this.state.width, height: this.state.height }}
position={{ x: this.state.x, y: this.state.y }}
onDragStop={(e, d) => {
this.setState({ x: d.x, y: d.y });
}}
onResizeStop={(e, direction, ref, delta, position) => {
this.setState({
width: ref.style.width,
height: ref.style.height,
...position
});
}}
>
<Chip icon={<img src={MORE_OPTION} alt="" />} label="New Comp" color="secondary" />
</Rnd>
</Box>
);
}
}

export default withStyles(styles)(Composition);
32 changes: 3 additions & 29 deletions src/components/views/mechanisms/GenericMechanism.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import * as React from "react";
import MechSimple from "./MechSimple";
import MechMetadata from "./MechMetadata";
import { Rnd } from "react-rnd";
import { withStyles } from "@mui/styles";
import { Box, Chip } from "@mui/material";
import MORE_OPTION from "../../../assets/svg/option.svg"
import vars from "../../../assets/styles/variables";

const { draggableBg, listItemActiveBg, textWhite, chipTextColor, chipBorderColor } = vars;
Expand Down Expand Up @@ -97,37 +94,14 @@ class GenericMechanism extends React.Component {

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

return (
// <>
// { expanded
// ? ( <MechMetadata changeVisibility={this.changeVisibility} {...this.props} /> )
// : ( <MechSimple changeVisibility={this.changeVisibility} {...this.props} /> )
// }
// </>
<Box className={`${classes.root} ${expanded ? classes.selected : ''}`}>
<Rnd
size={{ width: this.state.width, height: this.state.height }}
position={{ x: this.state.x, y: this.state.y }}
onDragStop={(e, d) => {
this.setState({ x: d.x, y: d.y });
}}
onResizeStop={(e, direction, ref, delta, position) => {
this.setState({
width: ref.style.width,
height: ref.style.height,
...position
});
}}
>
<Chip icon={<img src={MORE_OPTION} alt="" />} label="New Comp" color="secondary" />
{ expanded
<>
{ expanded
? ( <MechMetadata changeVisibility={this.changeVisibility} {...this.props} /> )
: ( <MechSimple changeVisibility={this.changeVisibility} {...this.props} /> )
}
</Rnd>
</Box>
</>
);
}
}
Expand Down
34 changes: 25 additions & 9 deletions src/model/Interpreter.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { GVTypes, PNLClasses } from '../constants';
import { 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 { PortTypes } from '@metacell/meta-diagram';

const html2json = require('html2json').html2json
const typesArray = Object.values(GVTypes);
Expand All @@ -13,10 +13,15 @@ const parse = require('dotparser');
export default class ModelInterpreter {
nativeModel: any;
jsonModel: Object;
modelMap: { [key: string]: Map<String, CompositionNode|MechanismNode|ProjectionLink|any> };

constructor(model: any) {
this.nativeModel = model;
this.jsonModel = this._convertModel(model);
this.modelMap = {
'nodes': new Map(),
'links': new Map()
};
}

_convertModel(model: any) : Object {
Expand All @@ -26,13 +31,13 @@ export default class ModelInterpreter {
};

parsedModel[PNLClasses.COMPOSITION] = model[PNLClasses.COMPOSITION].map((singleModel: any) => {
const newModel = parse(singleModel).map((elem: any) => ModelInterpreter.castObject(elem));
const newModel = parse(singleModel).map((elem: any) => ModelInterpreter.castObject(elem, undefined, this.modelMap));
return newModel;
});

parsedModel[PNLClasses.MECHANISM] = model[PNLClasses.MECHANISM].map((singleNode: any) => {
let tempNode = parse(singleNode)[0].children.filter((elem: { node_id: { id: string; }; }) => elem.node_id.id !== 'graph');
let newNode = tempNode.map((elem: any) => ModelInterpreter.castObject(elem));
let newNode = tempNode.map((elem: any) => ModelInterpreter.castObject(elem, undefined, this.modelMap));
return newNode;
});

Expand All @@ -51,6 +56,10 @@ export default class ModelInterpreter {
return this.nativeModel;
}

getModelElementsMap() {
return this.modelMap;
}

static parseNodePorts(name: string, type: string): { [key: string]: any } {
let ports: { [key: string]: any[] } = {
[PortTypes.INPUT_PORT]: [],
Expand Down Expand Up @@ -80,7 +89,11 @@ export default class ModelInterpreter {
return ports;
}

static castObject(item: MechanismNode|CompositionNode|ProjectionLink|any) : MechanismNode|CompositionNode|ProjectionLink {
static castObject(
item: MechanismNode|CompositionNode|ProjectionLink|any,
parent: any|undefined,
modelMap: { [key: string]: Map<String, CompositionNode|MechanismNode|ProjectionLink|any> })
: MechanismNode|CompositionNode|ProjectionLink {
let newNode = item;
if (item?.type === undefined) {
throw new TypeError('type is missing, object cannot be casted to the right class type.');
Expand All @@ -94,6 +107,8 @@ export default class ModelInterpreter {
[PNLClasses.PROJECTION]: [],
[PNLClasses.COMPOSITION]: [],
}
newNode = new CompositionNode(item.id, parent, '', false, ports, extra, children);
modelMap['nodes'].set(newNode.getName(), newNode);
item.children.forEach((element: any) => {
if (element.type === 'attr_stmt') {
extra[element.target] = {}
Expand All @@ -107,15 +122,15 @@ export default class ModelInterpreter {
if (typesArray.includes(element.type)) {
switch (element.type) {
case GVTypes.COMPOSITION: {
children[PNLClasses.COMPOSITION].push(ModelInterpreter.castObject(element));
children[PNLClasses.COMPOSITION].push(ModelInterpreter.castObject(element, newNode, modelMap));
break;
}
case GVTypes.MECHANISM: {
children[PNLClasses.MECHANISM].push(ModelInterpreter.castObject(element));
children[PNLClasses.MECHANISM].push(ModelInterpreter.castObject(element, newNode, modelMap));
break;
}
case GVTypes.PROJECTION: {
children[PNLClasses.PROJECTION].push(ModelInterpreter.castObject(element));
children[PNLClasses.PROJECTION].push(ModelInterpreter.castObject(element, newNode, modelMap));
break;
}
default:
Expand All @@ -125,7 +140,6 @@ export default class ModelInterpreter {
}
}
});
newNode = new CompositionNode(item.id, '', false, ports, extra, children);
break;
}
case GVTypes.MECHANISM: {
Expand All @@ -142,7 +156,8 @@ export default class ModelInterpreter {
extra[singleAttr?.id] = singleAttr?.eq;
}
});
newNode = new MechanismNode(item?.node_id?.id, '', false, ports, extra);
newNode = new MechanismNode(item?.node_id?.id, parent, '', false, ports, extra);
modelMap['nodes'].set(newNode.getName(), newNode);
break;
}
case GVTypes.PROJECTION: {
Expand All @@ -165,6 +180,7 @@ export default class ModelInterpreter {
receiverPort = item.edge_list[1]['port']['id'];
}
newNode = new ProjectionLink(name, sender, senderPort, receiver, receiverPort, false, extra);
modelMap['links'].set(newNode.getName(), newNode);
break;
}
default:
Expand Down
Loading

0 comments on commit 2d2d5de

Please sign in to comment.