UNPKG

@hms-dbmi-bgm/react-workflow-viz

Version:

React component for visualizing CWL-like workflows and provenance graphs.

604 lines (521 loc) 30.6 kB
'use strict'; function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = exports.GraphParser = void 0; var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _underscore = _interopRequireDefault(require("underscore")); var d3 = _interopRequireWildcard(require("d3")); var _memoizeOne = _interopRequireDefault(require("memoize-one")); var _StateContainer = _interopRequireDefault(require("./StateContainer")); var _ScrollContainer = _interopRequireDefault(require("./ScrollContainer")); var _NodesLayer = _interopRequireDefault(require("./NodesLayer")); var _EdgesLayer = _interopRequireDefault(require("./EdgesLayer")); var _DefaultDetailPane = require("./DefaultDetailPane"); var _Node = require("./Node"); var _ScaleController = require("./ScaleController"); var _utilities = require("../utilities"); var _parsingFunctions = require("./parsing-functions"); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function (o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function () { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function (o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } /** * Primary/entry component for the Workflow graph. * * @class Graph * @prop {Object[]} nodes Array of node objects to plot. Both nodes and edges can be generated from a CWL-like structure using static functions, including the provided 'parseAnalysisSteps'. See propTypes in class def below for object structure. * @prop {Object[]} edges Array of edge objects to plot. See propTypes in class def below for object structure. * @prop {function} renderNodeElement Function to render out own custom Node Element. Accepts two params - 'node' and 'props' (of graph). * @prop {function?} renderDetailPane Function to render out own custom Detail Pane. Accepts two params - 'selectedNode' and 'props' (of graph). Pass in null to perform your own logic in onNodeClick. * @prop {function} [onNodeClick] A function to be executed each time a node is clicked. 'this' will refer to internal statecontainer. Should accept params: {Object} 'node', {Object|null} 'selectedNode', and {MouseEvent} 'evt'. By default, it changes internal state's selectedNode. You should either disable props.checkHrefForSelectedNode -or- change href in this function. * @prop {function} [isNodeDisabled] Function which accepts a 'node' object and returns a boolean. * @prop {Object} [innerMargin={top : 20, bottom: 48, left: 15, right: 15}] Provide this object, containing numbers for 'top', 'bottom', 'left', and 'right', if want to adjust chart margins. * @prop {boolean} [pathArrows=true] Whether to display arrows at the end side of edges. * @prop {number} [columnSpacing=56] Adjust default spacing between columns, where edges are drawn. * @prop {number} [columnWidth=150] Adjust width of columns, where nodes are drawn. * @prop {number} [rowSpacing=56] Adjust vertical spacing between node centers (NOT between their bottom/top). * @prop {function} [nodeTitle] Optional function to supply to get node title, before is passed to visible Node element. Useful if want to display some meta sub-property rather than technical title. */ var Graph = /*#__PURE__*/function (_React$Component) { _inherits(Graph, _React$Component); var _super = _createSuper(Graph); function Graph(props) { var _this; _classCallCheck(this, Graph); _this = _super.call(this, props); _this.height = _this.height.bind(_assertThisInitialized(_this)); _this.nodesWithCoordinates = _this.nodesWithCoordinates.bind(_assertThisInitialized(_this)); _this.setScale = _this.setScale.bind(_assertThisInitialized(_this)); _this.state = { mounted: false, scale: props.scale, minScale: props.minScale }; _this.memoized = { getHeightFromNodes: (0, _memoizeOne["default"])(Graph.getHeightFromNodes), getScrollableWidthFromNodes: (0, _memoizeOne["default"])(Graph.getScrollableWidthFromNodes), getNodesWithCoordinates: (0, _memoizeOne["default"])(Graph.getNodesWithCoordinates) }; return _this; } _createClass(Graph, [{ key: "componentDidMount", value: function componentDidMount() { this.setState({ 'mounted': true }); var _this$props = this.props, containerWidth = _this$props.containerWidth, containerHeight = _this$props.containerHeight, propMinScale = _this$props.minScale, maxScale = _this$props.maxScale, graphWidth = _this$props.graphWidth, graphHeight = _this$props.graphHeight, _this$props$zoomToExt = _this$props.zoomToExtentsOnMount, zoomToExtentsOnMount = _this$props$zoomToExt === void 0 ? true : _this$props$zoomToExt; // if (typeof containerWidth !== "number" || typeof containerHeight !== "number") { // // Maybe will become set in componentDidUpdate later. // return false; // } // if (isNaN(containerWidth) || isNaN(containerHeight)) { // throw new Error("Width or height is NaN."); // } // const minScaleUnbounded = Math.min( // (containerWidth / graphWidth), // (containerHeight / graphHeight) // ); // // Decrease by 5% for scrollbars, etc. // const nextMinScale = Math.floor( // Math.min(1, maxScale, Math.max(propMinScale, minScaleUnbounded)) // * 95) / 100; // const retObj = { minScale: nextMinScale, mounted: true }; // // First time that we've gotten dimensions -- set scale to fit. // // Also, if nextMinScale > scale or we had scale === minScale before. // // TODO: Maybe do this onMount also // if (zoomToExtentsOnMount) { // retObj.scale = nextMinScale; // } // requestAnimationFrame(() => { // this.setState(retObj); // }); } }, { key: "setScale", value: function setScale(scaleToSet, cb) { this.setState(function (_ref, _ref2) { var stateMinScale = _ref.minScale; var propMinScale = _ref2.minScale, maxScale = _ref2.maxScale; var scale = Math.max(Math.min(maxScale, scaleToSet), stateMinScale || propMinScale); return { scale: scale }; }, cb); } }, { key: "height", value: function height() { var _this$props2 = this.props, nodes = _this$props2.nodes, nodesPreSortFxn = _this$props2.nodesPreSortFxn, propRowSpacing = _this$props2.rowSpacing; var scale = this.state.scale; var rowSpacing = (0, _utilities.roundScaled)(propRowSpacing, scale); return this.memoized.getHeightFromNodes(nodes, nodesPreSortFxn, rowSpacing); } }, { key: "scrollableWidth", value: function scrollableWidth() { var _this$props3 = this.props, nodes = _this$props3.nodes, propColumnWidth = _this$props3.columnWidth, propColumnSpacing = _this$props3.columnSpacing, innerMargin = _this$props3.innerMargin; var scale = this.state.scale; var columnWidth = (0, _utilities.roundScaled)(propColumnWidth, scale); var columnSpacing = (0, _utilities.roundScaled)(propColumnSpacing, scale); return this.memoized.getScrollableWidthFromNodes(nodes, columnWidth, columnSpacing, innerMargin); } }, { key: "nodesWithCoordinates", value: function nodesWithCoordinates(viewportWidth, contentWidth, contentHeight) { var _this$props4 = this.props, nodes = _this$props4.nodes, innerMargin = _this$props4.innerMargin, rowSpacingType = _this$props4.rowSpacingType, propRowSpacing = _this$props4.rowSpacing, propColumnWidth = _this$props4.columnWidth, propColumnSpacing = _this$props4.columnSpacing, isNodeCurrentContext = _this$props4.isNodeCurrentContext; var scale = this.state.scale; var rowSpacing = (0, _utilities.roundScaled)(propRowSpacing, scale); var columnWidth = (0, _utilities.roundScaled)(propColumnWidth, scale); var columnSpacing = (0, _utilities.roundScaled)(propColumnSpacing, scale); return this.memoized.getNodesWithCoordinates(nodes, viewportWidth, contentWidth, contentHeight, innerMargin, rowSpacingType, rowSpacing, columnWidth, columnSpacing, isNodeCurrentContext, scale || 1); } }, { key: "render", value: function render() { var _this$props5 = this.props, width = _this$props5.width, propInnerMargin = _this$props5.innerMargin, edges = _this$props5.edges, minimumHeight = _this$props5.minimumHeight, propColumnSpacing = _this$props5.columnSpacing, propRowSpacing = _this$props5.rowSpacing, propColumnWidth = _this$props5.columnWidth, _this$props5$scale = _this$props5.scale, propScale = _this$props5$scale === void 0 ? 1 : _this$props5$scale, _this$props5$maxScale = _this$props5.maxScale, propMaxScale = _this$props5$maxScale === void 0 ? 1.1 : _this$props5$maxScale, _this$props5$minScale = _this$props5.minScale, propMinScale = _this$props5$minScale === void 0 ? 0.9 : _this$props5$minScale, showZoomControls = _this$props5.showZoomControls; var _this$state = this.state, mounted = _this$state.mounted, stateScale = _this$state.scale; var scale = stateScale || propScale; var innerHeight = this.height(); var contentWidth = this.scrollableWidth(); var innerWidth = width; (0, _utilities.roundScaled)(propColumnSpacing, scale); (0, _utilities.roundScaled)(propRowSpacing, scale); (0, _utilities.roundScaled)(propColumnWidth, scale); var innerMargin = { top: (0, _utilities.roundScaled)(propInnerMargin.top, scale), right: (0, _utilities.roundScaled)(propInnerMargin.right, scale), bottom: (0, _utilities.roundScaled)(propInnerMargin.bottom, scale), left: (0, _utilities.roundScaled)(propInnerMargin.left, scale) }; if (!mounted) { return /*#__PURE__*/_react["default"].createElement("div", { key: "outer" }, /*#__PURE__*/_react["default"].createElement("div", null, "\xA0")); } if (innerMargin && (innerMargin.left || innerMargin.right)) { innerWidth -= innerMargin.left || 0; innerWidth -= innerMargin.right || 0; } var nodes = this.nodesWithCoordinates(innerWidth, contentWidth, innerHeight); var graphHeight = innerHeight + (innerMargin.top || 0) + (innerMargin.bottom || 0); /* TODO: later var spacerCount = _.reduce(nodes, function(m,n){ if (n.nodeType === 'spacer'){ return m + 1; } else { return m; }}, 0); if (spacerCount){ height += (spacerCount * this.props.columnSpacing); graphHeight += (spacerCount * this.props.columnSpacing); } */ var scaleControls = null; if (showZoomControls && typeof this.setScale === "function") { var scaleProps = { scale: scale, minScale: this.state.minScale || propMinScale, maxScale: propMaxScale, setScale: this.setScale }; scaleControls = /*#__PURE__*/_react["default"].createElement(_ScaleController.ScaleControls, scaleProps); } return /*#__PURE__*/_react["default"].createElement("div", { className: "workflow-chart-outer-container", key: "outer" }, /*#__PURE__*/_react["default"].createElement("div", { className: "workflow-chart-inner-container" }, scaleControls, /*#__PURE__*/_react["default"].createElement(_StateContainer["default"], _extends({ nodes: nodes, edges: edges, innerWidth: innerWidth, innerHeight: innerHeight, contentWidth: contentWidth, width: width }, _underscore["default"].pick(this.props, 'pathArrows', 'href', 'onNodeClick', 'renderDetailPane')), /*#__PURE__*/_react["default"].createElement(_ScrollContainer["default"], { outerHeight: graphHeight, minHeight: minimumHeight }, /*#__PURE__*/_react["default"].createElement(_EdgesLayer["default"], _extends({ scale: scale, columnWidth: propColumnWidth, columnSpacing: propColumnSpacing, rowSpacing: propRowSpacing, innerMargin: propInnerMargin }, _underscore["default"].pick(this.props, 'isNodeDisabled', 'isNodeCurrentContext', 'isNodeSelected', 'edgeStyle', 'nodeEdgeLedgeWidths'))), /*#__PURE__*/_react["default"].createElement(_NodesLayer["default"], _extends({ scale: scale, columnWidth: propColumnWidth, columnSpacing: propColumnSpacing, innerMargin: propInnerMargin }, _underscore["default"].pick(this.props, 'renderNodeElement', 'isNodeDisabled', 'isNodeCurrentContext', 'nodeClassName'))))))); } }], [{ key: "getHeightFromNodes", value: function getHeightFromNodes(nodes, nodesPreSortFxn, rowSpacing) { // Run pre-sort fxn, e.g. to manually pre-arrange nodes into different columns. if (typeof nodesPreSortFxn === 'function') { nodes = nodesPreSortFxn(nodes.slice(0)); } return Math.max((0, _underscore["default"])(nodes).chain().groupBy('column').pairs().reduce(function (maxCount, nodeSet) { return Math.max(nodeSet[1].length, maxCount); }, 0).value() * rowSpacing - rowSpacing); } }, { key: "getScrollableWidthFromNodes", value: function getScrollableWidthFromNodes(nodes, columnWidth, columnSpacing, innerMargin) { return (_underscore["default"].reduce(nodes, function (highestCol, node) { return Math.max(node.column, highestCol); }, 0) + 1) * (columnWidth + columnSpacing) + (innerMargin.left || 0) + (innerMargin.right || 0) - columnSpacing; } /** * Extends each node with X & Y coordinates. * * Converts column placement and position within columns, * along with other chart dimension settings, into X & Y coordinates. * * IMPORTANT: * Returns a new array but _modifies array items in place_. * If need fresh nodes, deep-clone before supplying `props.nodes`. * * @static * @memberof Graph */ }, { key: "getNodesWithCoordinates", value: function getNodesWithCoordinates() { var nodes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; var viewportWidth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; var contentWidth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; var contentHeight = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; var innerMargin = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : { top: 0, right: 0, bottom: 0, left: 0 }; var rowSpacingType = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 'compact'; var rowSpacing = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : 75; var columnWidth = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 150; var columnSpacing = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : 56; var isNodeCurrentContext = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : false; /** Vertically centers a single node within a column */ function centerNode(n) { n.y = contentHeight / 2 + innerMargin.top; n.nodesInColumn = 1; n.indexInColumn = 0; } var nodesByColumnPairs, leftOffset, nodesWithCoords; // Arrange into lists of columns // Ensure we're sorted, using column _numbers_ (JS objs keyed by str). nodesByColumnPairs = _underscore["default"].sortBy(_underscore["default"].map(_underscore["default"].pairs(_underscore["default"].groupBy(nodes, 'column')), function (_ref3) { var _ref4 = _slicedToArray(_ref3, 2), columnNumStr = _ref4[0], nodesInColumn = _ref4[1]; return [parseInt(columnNumStr), nodesInColumn]; }), 0); // Set correct Y coordinate on each node depending on how many nodes are in each column. _underscore["default"].forEach(nodesByColumnPairs, function (_ref5) { var _ref6 = _slicedToArray(_ref5, 2), columnNumber = _ref6[0], nodesInColumn = _ref6[1]; var countInCol = nodesInColumn.length; nodesInColumn = _underscore["default"].sortBy(nodesInColumn, 'indexInColumn'); if (rowSpacingType === 'compact') { if (countInCol === 1) centerNode(nodesInColumn[0]);else { var padding = Math.max(0, contentHeight - (countInCol - 1) * rowSpacing) / 2; _underscore["default"].forEach(nodesInColumn, function (nodeInCol, idx) { nodeInCol.y = (idx + 0) * rowSpacing + innerMargin.top + padding; nodeInCol.nodesInColumn = countInCol; }); } } else if (rowSpacingType === 'stacked') { _underscore["default"].forEach(nodesInColumn, function (nodeInCol, idx) { if (!nodeInCol) return; nodeInCol.y = rowSpacing * idx + innerMargin.top; nodeInCol.nodesInColumn = countInCol; }); } else if (rowSpacingType === 'wide') { if (countInCol === 1) centerNode(nodesInColumn[0]);else { _underscore["default"].forEach(d3.range(0, contentHeight, contentHeight / (countInCol - 1)).concat([contentHeight]), function (yCoordinate, idx) { var nodeInCol = nodesInColumn[idx]; if (!nodeInCol) return; nodeInCol.y = yCoordinate + innerMargin.top; nodeInCol.nodesInColumn = countInCol; }); } } else { console.error("Prop 'rowSpacingType' not valid. Must be ", Graph.propTypes.rowSpacingType); throw new Error("Prop 'rowSpacingType' not valid."); } }); nodesWithCoords = _underscore["default"].reduce(nodesByColumnPairs, function (m, _ref7) { var _ref8 = _slicedToArray(_ref7, 2), columnNumber = _ref8[0], nodesInColumn = _ref8[1]; return m.concat(nodesInColumn); }, []); leftOffset = innerMargin.left; // Center graph contents horizontally if needed. if (contentWidth && viewportWidth && contentWidth < viewportWidth) { leftOffset += (viewportWidth - contentWidth) / 2; } // Set correct X coordinate on each node depending on column and spacing prop. _underscore["default"].forEach(nodesWithCoords, function (node) { node.x = node.column * (columnWidth + columnSpacing) + leftOffset; }); // Finally, add boolean `isCurrentContext` flag to each node object if needed. if (typeof isNodeCurrentContext === 'function') { _underscore["default"].forEach(nodesWithCoords, function (node) { node.isCurrentContext = isNodeCurrentContext(node); }); } return nodesWithCoords; } }]); return Graph; }(_react["default"].Component); /** * Optional component to wrap Graph and pass steps in. * @todo Test for (lack of) bidirectionality in data and fix. */ exports["default"] = Graph; _defineProperty(Graph, "propTypes", { 'isNodeDisabled': _propTypes["default"].func, 'innerMargin': _propTypes["default"].shape({ 'top': _propTypes["default"].number.isRequired, 'bottom': _propTypes["default"].number.isRequired, 'left': _propTypes["default"].number.isRequired, 'right': _propTypes["default"].number.isRequired }).isRequired, 'renderNodeElement': _propTypes["default"].func.isRequired, 'renderDetailPane': _propTypes["default"].func.isRequired, 'nodes': _propTypes["default"].arrayOf(_propTypes["default"].shape({ 'column': _propTypes["default"].number.isRequired, 'name': _propTypes["default"].string.isRequired, 'nodeType': _propTypes["default"].string.isRequired, 'ioType': _propTypes["default"].string, 'id': _propTypes["default"].string, // Optional unique ID if node names might be same. 'outputOf': _propTypes["default"].object, // Unused currently 'inputOf': _propTypes["default"].arrayOf(_propTypes["default"].object), // Unused currently 'description': _propTypes["default"].string, 'meta': _propTypes["default"].oneOfType([_propTypes["default"].object, _propTypes["default"].shape({ 'target': _propTypes["default"].arrayOf(_propTypes["default"].shape({ 'name': _propTypes["default"].string.isRequired, 'type': _propTypes["default"].string.isRequired, 'step': _propTypes["default"].string })) })]) })).isRequired, 'edges': _propTypes["default"].arrayOf(_propTypes["default"].shape({ 'source': _propTypes["default"].object.isRequired, 'target': _propTypes["default"].object.isRequired, 'capacity': _propTypes["default"].string })).isRequired, 'nodeTitle': _propTypes["default"].func, 'rowSpacingType': _propTypes["default"].oneOf(['compact', 'wide', 'stacked']), //scale 'showZoomControls': _propTypes["default"].bool, 'scale': _propTypes["default"].number, 'minScale': _propTypes["default"].number, 'maxScale': _propTypes["default"].number }); _defineProperty(Graph, "defaultProps", { 'height': null, // Unused, should be set to nodes count in highest column * rowSpacing + innerMargins. 'width': null, 'columnSpacing': 100, 'columnWidth': 150, 'rowSpacing': 80, 'rowSpacingType': 'compact', 'pathArrows': true, 'renderDetailPane': function renderDetailPane(selectedNode, props) { return /*#__PURE__*/_react["default"].createElement(_DefaultDetailPane.DefaultDetailPane, _extends({}, props, { selectedNode: selectedNode })); }, 'renderNodeElement': function renderNodeElement(node, props) { return /*#__PURE__*/_react["default"].createElement(_Node.DefaultNodeElement, _extends({}, props, { node: node })); }, 'onNodeClick': null, // Use StateContainer.defaultOnNodeClick 'innerMargin': { 'top': 80, 'bottom': 80, 'left': 40, 'right': 40 }, 'minimumHeight': 75, 'edgeStyle': 'bezier', 'isNodeCurrentContext': function isNodeCurrentContext() { return false; }, 'nodeClassName': function nodeClassName() { return ''; }, 'nodeEdgeLedgeWidths': [3, 5], //scale 'showZoomControls': true, 'scale': 1, 'minScale': 0.50, 'maxScale': 1.50 }); var GraphParser = /*#__PURE__*/function (_React$Component2) { _inherits(GraphParser, _React$Component2); var _super2 = _createSuper(GraphParser); function GraphParser(props) { var _this2; _classCallCheck(this, GraphParser); _this2 = _super2.call(this, props); _this2.memoized = { parseAnalysisSteps: (0, _memoizeOne["default"])(_parsingFunctions.parseAnalysisSteps), parseBasicIOAnalysisSteps: (0, _memoizeOne["default"])(_parsingFunctions.parseBasicIOAnalysisSteps) }; return _this2; } _createClass(GraphParser, [{ key: "render", value: function render() { var _this$props6 = this.props, steps = _this$props6.steps, parentItem = _this$props6.parentItem, children = _this$props6.children, parsingOptions = _this$props6.parsingOptions; var parseBasicIO = parsingOptions.parseBasicIO; var graphData; if (parseBasicIO) { graphData = this.memoized.parseBasicIOAnalysisSteps(steps, parentItem, parsingOptions); } else { graphData = this.memoized.parseAnalysisSteps(steps, parsingOptions); } return _react["default"].Children.map(children, function (child) { return /*#__PURE__*/_react["default"].cloneElement(child, graphData); }); } }]); return GraphParser; }(_react["default"].Component); exports.GraphParser = GraphParser; _defineProperty(GraphParser, "defaultProps", { 'parsingOptions': { showReferenceFiles: true, showParameters: true, showIndirectFiles: true, parseBasicIO: false }, 'parentItem': { name: "Workflow" } });