const React = require('react'); const Spring = require('react-motion').Spring; const AppActions = require('../actions/app-actions'); const NodeColorMixin = require('../mixins/node-color-mixin'); const Node = React.createClass({ mixins: [ NodeColorMixin ], render: function() { const props = this.props; const scale = this.props.scale; const textOffsetX = 0; const textOffsetY = scale(0.5) + 18; const isPseudo = !!this.props.pseudo; const color = isPseudo ? '' : this.getNodeColor(this.props.rank); const onClick = this.props.onClick; const onMouseEnter = this.handleMouseEnter; const onMouseLeave = this.handleMouseLeave; const classNames = ['node']; const ellipsis = this.ellipsis; const animConfig = [80, 20]; // stiffness, bounce if (this.props.highlighted) { classNames.push('highlighted'); } if (this.props.blurred) { classNames.push('blurred'); } if (this.props.pseudo) { classNames.push('pseudo'); } const classes = classNames.join(' '); return ( {function(interpolated) { const transform = 'translate(' + interpolated.x.val + ',' + interpolated.y.val + ')'; return ( {props.highlighted && } {ellipsis(props.label, 14)} {ellipsis(props.subLabel, 12)} ); }} ); }, ellipsis: function(text, fontSize) { const maxWidth = this.props.scale(4); const averageCharLength = fontSize / 1.5; const allowedChars = maxWidth / averageCharLength; let truncatedText = text; let trimmedText = text; while (text && trimmedText.length > 1 && trimmedText.length > allowedChars) { trimmedText = trimmedText.slice(0, -1); truncatedText = trimmedText + '...'; } return truncatedText; }, handleMouseEnter: function(ev) { AppActions.enterNode(ev.currentTarget.id); }, handleMouseLeave: function(ev) { AppActions.leaveNode(ev.currentTarget.id); } }); module.exports = Node;