Skip to content

Commit

Permalink
support hidden node attributes and text formatters (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
ellthompson authored Nov 9, 2021
1 parent 861cebc commit 0dfd157
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 28 deletions.
132 changes: 132 additions & 0 deletions .storybook/stories/basic/node-attributes.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import React from 'react';
import { GRAPH_ACTIONS } from '../../../src/constants';
import Component from '../../base-component';

var name = 'Node Attributes Graph';
var config = {
title: `Basic/${name}`
};

export default {
title: config.title,
component: Component,
parameters: {
docs: {}
}
};

const GRAPH_ENUM = {
NODE: {
HELLO: 0,
WORLD: 1,
},
EDGE: {
HELLO_TO_WORLD: 0,
}
};

const GRAPH_SCHEMA = {
nodes: {
[GRAPH_ENUM.NODE.HELLO]: {
name: 'Hello',
headerTextFormatter: (attributes) => `Hello ${attributes.foo}`,
outPorts: [
{
name: 'output',
type: GRAPH_ENUM.EDGE.HELLO_TO_WORLD,
textFormatter: (attributes) => `output (${attributes.foo})`
}
],
attributes: [
{
name: 'foo',
type: 'TEXT_INPUT'
}
]
},
[GRAPH_ENUM.NODE.WORLD]: {
name: 'World',
inPorts: [
{
name: 'input',
type: GRAPH_ENUM.EDGE.HELLO_TO_WORLD,
textFormatter: (attributes) => `input (${attributes.foo})`
}
],
attributes: [
{
name: 'foo',
type: 'TEXT_INPUT',
hidden: true
}
]
}
},
edges: {
[GRAPH_ENUM.EDGE.HELLO_TO_WORLD]: {
from: GRAPH_ENUM.NODE.HELLO,
to: GRAPH_ENUM.NODE.WORLD,
}
}
};

var GRAPH_DATA = {
nodes: {
1234: {
id: 1234,
nodeType: GRAPH_ENUM.NODE.HELLO,
name: 'Hello',
posX: 200,
posY: 200,
attributes: {
foo: 'bar'
}
},
1235: {
id: 1235,
nodeType: GRAPH_ENUM.NODE.WORLD,
name: 'World',
posX: 500,
posY: 200,
attributes: {
foo: 'bar'
}
},
},
edges: {
'1234,0-1235,0': {
edgeType: GRAPH_ENUM.EDGE.HELLO_TO_WORLD,
from: 1234,
to: 1235,
inPort: 0,
outPort: 0,
}
}
};

export const NodeAttributesGraphExample = (args) => {
return <Component schema={GRAPH_SCHEMA} options={{
initialData: GRAPH_DATA,
passiveUIEvents: false,
includeFonts: true,
defaultStyles: {
edge: {
connectionStyle: 'smoothInOut'
},
background: {
color: '#20292B',
gridSize: 10
}
}
}} />;
};

document.querySelector('#root').setAttribute('style', 'position: fixed; width: 100%; height: 100%');
document.body.setAttribute('style', 'margin: 0px; padding: 0px;');

setTimeout(() => {
const graph = document.querySelector('.pcui-graph').ui;
graph.on(GRAPH_ACTIONS.UPDATE_NODE_ATTRIBUTE, (data) => {
graph.updateNodeAttribute(1235, data.attribute, data.node.attributes[data.attribute]);
});
}, 500);
63 changes: 37 additions & 26 deletions src/graph-view-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,16 @@ class GraphViewNode {
var outHeight = (nodeSchema.outPorts.length * 25) + 10;
if (outHeight > portHeight) portHeight = outHeight;
}
if (nodeSchema.attributes && nodeSchema.attributes.length > 0) {
attributeHeight = nodeSchema.attributes.length * 32 + 10;
const visibleAttributes = nodeSchema.attributes && nodeSchema.attributes.filter(a => !a.hidden);
if (visibleAttributes && visibleAttributes.length > 0) {
attributeHeight = visibleAttributes.length * 32 + 10;
}
var rectSize = { x: this.getSchemaValue('baseWidth'), y: rectHeight + portHeight + attributeHeight };

var labelName;
if (nodeSchema.outPorts || nodeSchema.inPorts) {
if (nodeSchema.headerTextFormatter) {
labelName = nodeSchema.headerTextFormatter(nodeData.attributes);
} else if (nodeSchema.outPorts || nodeSchema.inPorts) {
labelName = nodeData.attributes && nodeData.attributes.name ? `${nodeData.attributes.name} (${nodeSchema.name})` : nodeSchema.name;
} else {
labelName = nodeData.attributes && nodeData.attributes.name || nodeData.name;
Expand Down Expand Up @@ -196,13 +199,13 @@ class GraphViewNode {
id: `in${i}`,
group: 'in',
edgeType: port.edgeType,
markup: `<circle class="port-body" edgeType="${port.type}"></circle><circle class="port-inner-body" visibility="hidden"></circle>`,
markup: `<circle class="port-body" id="${nodeData.id}-in${i}" edgeType="${port.type}"></circle><circle class="port-inner-body" visibility="hidden"></circle>`,
attrs: {
'.port-body': {
stroke: this._graphSchema.edges[port.type].stroke || this._config.defaultStyles.edge.stroke
},
text: {
text: port.name,
text: port.textFormatter ? port.textFormatter(nodeData.attributes) : port.name,
fill: this.getSchemaValue('textColorSecondary'),
'font-size': 14
}
Expand Down Expand Up @@ -242,14 +245,14 @@ class GraphViewNode {
nodeSchema.outPorts.forEach((port, i) => rect.addPort({
id: `out${i}`,
group: 'out',
markup: `<circle class="port-body" edgeType="${port.type}"></circle><circle class="port-inner-body" visibility="hidden"></circle>`,
markup: `<circle class="port-body" id="${nodeData.id}-out${i}" edgeType="${port.type}"></circle><circle class="port-inner-body" visibility="hidden"></circle>`,
attrs: {
type: port.type,
'.port-body': {
stroke: this._graphSchema.edges[port.type].stroke || this._config.defaultStyles.edge.stroke
},
text: {
text: port.name,
text: port.textFormatter ? port.textFormatter(nodeData.attributes) : port.name,
fill: this.getSchemaValue('textColorSecondary'),
'font-size': 14
}
Expand All @@ -258,8 +261,8 @@ class GraphViewNode {
}

var containers = [];
if (nodeSchema.attributes) {
nodeSchema.attributes.forEach((attribute, i) => {
if (visibleAttributes) {
visibleAttributes.forEach((attribute, i) => {
const container = new this._graphView.pcui.Container({ class: 'graph-node-container' });
const label = new this._graphView.pcui.Label({ text: attribute.name, class: 'graph-node-label' });
let input;
Expand Down Expand Up @@ -387,16 +390,28 @@ class GraphViewNode {
return arr;
}

updateAttribute(attribute, value) {
if (attribute === 'name') {
var labelName;
if (this.nodeSchema.outPorts || this.nodeSchema.inPorts) {
labelName = `${value} (${this.nodeSchema.name})`;
} else {
labelName = value;
}
this.model.attr('label/text', labelName);
updateFormattedTextFields() {
if (this.nodeSchema.headerTextFormatter) {
this.model.attr('label/text', this.nodeSchema.headerTextFormatter(this.nodeData.attributes));
}
if (this.nodeSchema.outPorts) {
this.nodeSchema.outPorts.forEach((port, i) => {
if (port.textFormatter) {
document.getElementById(`${this.nodeData.id}-out${i}`).parentElement.parentElement.querySelector('tspan').innerHTML = port.textFormatter(this.nodeData.attributes);
}
});
}
if (this.nodeSchema.inPorts) {
this.nodeSchema.inPorts.forEach((port, i) => {
if (port.textFormatter) {
document.getElementById(`${this.nodeData.id}-in${i}`).parentElement.parentElement.querySelector('tspan').innerHTML = port.textFormatter(this.nodeData.attributes);
}
});
}
}

updateAttribute(attribute, value) {
this.nodeData.attributes[attribute] = value;
const attributeElement = document.querySelector(`#nodediv_${this.model.id}`).querySelector(`#input_${attribute}`);
if (attributeElement) {
attributeElement.ui.suspendEvents = true;
Expand All @@ -408,6 +423,7 @@ class GraphViewNode {
attributeElement.ui.error = false;
attributeElement.ui.suspendEvents = false;
}
this.updateFormattedTextFields();
}

updateNodeType(nodeType) {
Expand All @@ -431,7 +447,9 @@ class GraphViewNode {
break;
}
case 'updateAttribute': {
document.querySelector(`#nodediv_${this.model.id}`).querySelector(`#input_${attribute.name}`).ui.on('change', (value) => {
const attributeElement = document.querySelector(`#nodediv_${this.model.id}`).querySelector(`#input_${attribute.name}`);
if (!attributeElement) break;
attributeElement.ui.on('change', (value) => {
if (attribute.name === 'name') {
var nameTaken = false;
Object.keys(this._graphView._graphData.get('data.nodes')).forEach((nodeKey) => {
Expand All @@ -446,13 +464,6 @@ class GraphViewNode {
return;
}
attributeElement.ui.error = false;
var labelName;
if (this.nodeSchema.outPorts || this.nodeSchema.inPorts) {
labelName = `${this.nodeSchema.name} (${value})`;
} else {
labelName = value;
}
this.model.attr('label/text', labelName);
}
callback(this.nodeData.id, attribute, value);
});
Expand Down
4 changes: 2 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ class Graph extends Element {
node.attributes[attributeKey] = value;
}
if (JSON.stringify(node.attributes[attributeKey]) === JSON.stringify(prevAttributeValue)) return;
this.updateNodeAttribute(nodeId, attribute.name, prevAttributeValue);
this.updateNodeAttribute(nodeId, attribute.name, value);
this._dispatchEvent(
GRAPH_ACTIONS.UPDATE_NODE_ATTRIBUTE,
{
Expand Down Expand Up @@ -634,7 +634,7 @@ class Graph extends Element {
this.updateNodePosition(nodeId, { x: node.posX, y: node.posY });
});
this.on(GRAPH_ACTIONS.UPDATE_NODE_ATTRIBUTE, ({ node }) => {
this._graphData.set(`data.nodes.${nodeId}`, node);
this._graphData.set(`data.nodes.${node.id}`, node);
});
this.on(GRAPH_ACTIONS.ADD_EDGE, ({ edge, edgeId }) => {
if (Number.isFinite(edge.inPort)) {
Expand Down

0 comments on commit 0dfd157

Please sign in to comment.