UNPKG

react-d3-dag

Version:

React component to create interactive D3 directed acyclic graphs (DAGs)

117 lines (116 loc) 4.91 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const react_1 = __importDefault(require("react")); const d3_selection_1 = require("d3-selection"); const DefaultNodeElement_js_1 = __importDefault(require("./DefaultNodeElement.js")); class Node extends react_1.default.Component { constructor() { super(...arguments); this.nodeRef = null; this.state = { transform: this.setTransform(this.props.position, this.props.orientation, true), initialStyle: { opacity: 0, }, wasClicked: false, }; this.shouldNodeTransform = (ownProps, nextProps, ownState, nextState) => nextProps.subscriptions !== ownProps.subscriptions || nextProps.position.x !== ownProps.position.x || nextProps.position.y !== ownProps.position.y || nextProps.orientation !== ownProps.orientation || nextState.wasClicked !== ownState.wasClicked; // TODO: needs tests this.renderNodeElement = () => { const { data, dagNode, renderCustomNodeElement } = this.props; const renderNode = typeof renderCustomNodeElement === 'function' ? renderCustomNodeElement : DefaultNodeElement_js_1.default; const nodeProps = { dagNode, nodeDatum: data, toggleNode: this.handleNodeToggle, onNodeClick: this.handleOnClick, onNodeMouseOver: this.handleOnMouseOver, onNodeMouseOut: this.handleOnMouseOut, addChildren: this.handleAddChildren, }; return renderNode(nodeProps); }; this.handleNodeToggle = () => { this.setState({ wasClicked: true }); this.props.onNodeToggle(this.props.data.__rd3dag.id); }; this.handleOnClick = evt => { this.setState({ wasClicked: true }); this.props.onNodeClick(this.props.dagNode, evt); }; this.handleOnMouseOver = evt => { this.props.onNodeMouseOver(this.props.dagNode, evt); }; this.handleOnMouseOut = evt => { this.props.onNodeMouseOut(this.props.dagNode, evt); }; this.handleAddChildren = childrenData => { this.props.handleAddChildrenToNode(this.props.data.__rd3dag.id, childrenData); }; } componentDidMount() { this.commitTransform(); } componentDidUpdate() { if (this.state.wasClicked) { this.props.centerNode(this.props.dagNode); this.setState({ wasClicked: false }); } this.commitTransform(); } shouldComponentUpdate(nextProps, nextState) { return this.shouldNodeTransform(this.props, nextProps, this.state, nextState); } setTransform(position, orientation, shouldTranslateToOrigin = false) { if (shouldTranslateToOrigin) { return `translate(0,0)`; } return orientation === 'horizontal' ? `translate(${position.y},${position.x})` : `translate(${position.x},${position.y})`; } applyTransform(transform, transitionDuration, opacity = 1, done = () => { }) { if (this.props.enableLegacyTransitions) { (0, d3_selection_1.select)(this.nodeRef) // @ts-ignore .transition() .duration(transitionDuration) .attr('transform', transform) .style('opacity', opacity) .on('end', done); } else { (0, d3_selection_1.select)(this.nodeRef).attr('transform', transform).style('opacity', opacity); done(); } } commitTransform() { const { orientation, transitionDuration, position } = this.props; const transform = this.setTransform(position, orientation); this.applyTransform(transform, transitionDuration); } componentWillLeave(done) { const { orientation, transitionDuration, position } = this.props; const transform = this.setTransform(position, orientation, true); this.applyTransform(transform, transitionDuration, 0, done); } render() { const { data, nodeClassName } = this.props; return (react_1.default.createElement("g", { id: data.__rd3dag.id, ref: n => { this.nodeRef = n; }, style: this.state.initialStyle, className: [ data.children && data.children.length > 0 ? 'rd3dag-node' : 'rd3dag-leaf-node', nodeClassName, ] .join(' ') .trim(), transform: this.state.transform }, this.renderNodeElement())); } } exports.default = Node;