Skip to content

Commit

Permalink
feat: add nesting for transitions in nested model diagram renderer (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Manfred Cheung authored Jul 18, 2023
1 parent e193a8e commit 9079b6c
Showing 1 changed file with 109 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { select } from 'd3';
import { D3SelectionINode, Options } from '@graph-scaffolder/types';
import { useNodeTypeColorPalette } from '@/utils/petrinet-color-palette';

import { NodeType, PetrinetRenderer } from '@/model-representation/petrinet/petrinet-renderer';
import { NodeData } from '@/model-representation/petrinet/petrinet-service';
Expand All @@ -14,6 +15,7 @@ export interface NestedPetrinetOptions extends Options {
}

const CIRCLE_MARGIN_CONST = 1;
const { getNodeTypeColor } = useNodeTypeColorPalette();

export const extractNestedMap = (amr: Model) => {
const nestedMap = amr.semantics?.span?.[0].map.reduce((childMap: any, [stratNode, baseNode]) => {
Expand All @@ -36,10 +38,46 @@ export class NestedPetrinetRenderer extends PetrinetRenderer {
}

renderNodes(selection: D3SelectionINode<NodeData>) {
super.renderNodes(selection);
const species = selection.filter((d) => d.data.type === NodeType.State);
const transitions = selection.filter((d) => d.data.type === NodeType.Transition);

const states = selection.filter((d) => d.data.type === NodeType.State);
states.each((d, idx, g) => {
const strataTypes: string[] = [];
selection.each((d) => {
const strataType = d.data.strataType;
if (strataType && !strataTypes.includes(strataType)) {
strataTypes.push(strataType as string);
}
});
// transitions
transitions
.append('rect')
.classed('shape selectableNode', true)
.attr('width', (d) => d.width)
.attr('height', (d) => d.height)
.attr('y', (d) => -d.height * 0.5)
.attr('x', (d) => -d.width * 0.5)
.attr('rx', '6')
.attr('ry', '6')
.style('fill', (d) =>
d.data.strataType ? getNodeTypeColor(d.data.strataType) : 'var(--petri-nodeFill'
)
.style('cursor', 'pointer')
.attr('stroke', 'var(--petri-nodeBorder)')
.attr('stroke-width', 1);

// species
species
.append('circle')
.classed('shape selectableNode', true)
.attr('r', (d) => 0.55 * d.width) // FIXME: need to adjust edge from sqaure mapping to circle
.attr('fill', (d) =>
d.data.strataType ? getNodeTypeColor(d.data.strataType) : 'var(--petri-nodeFill)'
)
.attr('stroke', 'var(--petri-nodeBorder)')
.attr('stroke-width', 1)
.style('cursor', 'pointer');

species.each((d, idx, g) => {
const nestedNodes = this.nestedMap[d.id] ?? [];
const nestedNodesLen = nestedNodes.length;
for (let i = 0; i < nestedNodesLen; i++) {
Expand All @@ -63,9 +101,7 @@ export class NestedPetrinetRenderer extends PetrinetRenderer {
.attr('r', () => childRadius) // FIXME: need to adjust edge from sqaure mapping to circle
.attr('cx', xPos)
.attr('cy', yPos)
.attr('fill', () => 'transparent')
.attr('stroke', '#999999')
.attr('stroke-width', 1)
.attr('fill', () => '#ffffffaa')
.style('cursor', 'pointer');

select(g[idx])
Expand All @@ -74,10 +110,76 @@ export class NestedPetrinetRenderer extends PetrinetRenderer {
.attr('y', 5 + yPos)
.style('text-anchor', 'middle')
.style('paint-order', 'stroke')
.style('fill', 'var(--text-color-primary')
.style('fill', 'var(--text-color-subdued')
.style('pointer-events', 'none')
.html(() => nodeId ?? '');
}
});

transitions.each((d, idx, g) => {
const nestedNodes = this.nestedMap[d.id] ?? [];
const nestedNodesLen = nestedNodes.length;
const transitionNode = select(g[idx]);

for (let i = 1; i < nestedNodesLen; i++) {
const position = (d.width / nestedNodesLen) * i;

transitionNode
.append('line')
.attr('class', 'gridline')
.attr('x1', -d.width * 0.5)
.attr('y1', -d.width * 0.5 + position)
.attr('x2', d.width * 0.5)
.attr('y2', -d.width * 0.5 + position)
.attr('stroke', '#ffffffcf');
transitionNode
.append('line')
.attr('class', 'gridline')
.attr('y1', -d.width * 0.5)
.attr('x1', -d.width * 0.5 + position)
.attr('y2', d.width * 0.5)
.attr('x2', -d.width * 0.5 + position)
.attr('stroke', '#ffffffcf');
}
});

// transitions label text
transitions
.append('text')
.attr('y', () => 5)
.style('text-anchor', 'middle')
.style('paint-order', 'stroke')
.style('fill', 'var(--text-color-primary')
.style('pointer-events', 'none')
.html((d) => d.id);

// transitions expression text
transitions
.append('text')
.attr('y', (d) => -d.height / 2 - 5)
.style('text-anchor', 'middle')
.style('paint-order', 'stroke')
.style('stroke', '#FFF')
.style('stroke-width', '3px')
.style('stroke-linecap', 'butt')
.style('fill', 'var(--text-color-primary')
.style('pointer-events', 'none')
.html((d) => {
const rate = this.graph.amr.semantics.ode?.rates?.find((r) => r.target === d.id);
if (rate) {
return rate.expression;
}
return '';
});

// species text
species
.append('text')
.attr('y', () => 5)
.style('text-anchor', 'middle')
.style('paint-order', 'stroke')
.style('fill', 'var(--text-color-primary)')
.style('pointer-events', 'none')
.text((d) => d.id);
}
}

0 comments on commit 9079b6c

Please sign in to comment.