UNPKG

react-sigma

Version:

Lightweight but powerful library for drawing network graphs built on top of SigmaJS

182 lines (149 loc) 7.77 kB
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 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); 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 } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { 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; } 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 { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(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; } import React from 'react'; import '../sigma/layout.forceAtlas2'; import { embedProps } from './tools'; /** ForceAtlas2 component, starts ForceAtlas2 sigma plugin once component is mounted. It supposes that sigma graph is already in place, therefore component should not be mounted while graph is unavailable. It can be used within Sigma component if graph is preloaded, or within loader component, like NeoCypher. It accepts all the parameters of ForceAtlas2 described on its github page: @param {boolean} [worker=true] Use a web worker to run calculations in separate thread @param {boolean} barnesHutOptimize Use the algorithm's Barnes-Hut to improve repulsion's scalability This is useful for large graph but harmful to small ones. @param {number} barnesHutTheta @param {boolean} adjustSizes @param {number} iterationsPerRender @param {boolean} [linLogMode=true] @param {boolean} outboundAttractionDistribution @param {number} edgeWeightInfluence @param {number} scalingRatio @param {boolean} strongGravityMode @param {number} gravity @param {number} slowDown @param {number} timeout how long algorythm should run. default=graph.nodes().length * 10 [see sigma plugin page for more details](https://github.com/jacomyal/sigma.js/tree/master/plugins/sigma.layout.forceAtlas2) **/ var ForceAtlas2 = /*#__PURE__*/function (_React$Component) { _inherits(ForceAtlas2, _React$Component); var _super = _createSuper(ForceAtlas2); function ForceAtlas2(props) { var _this; _classCallCheck(this, ForceAtlas2); _this = _super.call(this, props); _this.state = { running: false }; return _this; } _createClass(ForceAtlas2, [{ key: "componentDidMount", value: function componentDidMount() { this._refreshGraph(); } }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps, prevState) { var s = this.props.sigma; if (prevState.running && !this.state.running && s) { s.stopForceAtlas2(); s.settings({ drawEdges: prevState.drawEdges === false ? false : true }); s.refresh(); } } }, { key: "componentWillUnmount", value: function componentWillUnmount() { if (this.props.sigma) this.props.sigma.killForceAtlas2(); if (this.state.timer) clearTimeout(this.state.timer); } }, { key: "render", value: function render() { if (!this.state.running) { return /*#__PURE__*/React.createElement("div", null, embedProps(this.props.children, { sigma: this.props.sigma })); } return null; } }, { key: "_refreshGraph", value: function _refreshGraph() { var _this2 = this; var s = this.props.sigma; if (!sigma || !s) return; var drawEdges = s.settings("drawEdges"); if (s.graph.edges().length > 1000) s.settings({ drawEdges: false }); s.startForceAtlas2(this._stripOptions(this.props)); // TODO: convert running status to state var timer = setTimeout(function () { _this2.setState({ running: false, timer: undefined }); }, this.props.timeout || s.graph.nodes().length * 8); this.setState({ running: true, timer: timer, drawEdges: drawEdges }); } //strip force atlas options from component props }, { key: "_stripOptions", value: function _stripOptions(props) { return Object.assign({}, props, { sigma: undefined, children: undefined }); } }]); return ForceAtlas2; }(React.Component); _defineProperty(ForceAtlas2, "defaultProps", { worker: true, linLogMode: true }); _defineProperty(ForceAtlas2, "propTypes", { worker: PropTypes.bool, barnesHutOptimize: PropTypes.bool, barnesHutTheta: PropTypes.number, adjustSizes: PropTypes.bool, iterationsPerRender: PropTypes.number, linLogMode: PropTypes.bool, outboundAttractionDistribution: PropTypes.bool, edgeWeightInfluence: PropTypes.number, scalingRatio: PropTypes.number, strongGravityMode: PropTypes.bool, slowDown: PropTypes.number, gravity: PropTypes.number, timeout: PropTypes.number, sigma: function (_sigma) { function sigma() { return _sigma.apply(this, arguments); } sigma.toString = function () { return _sigma.toString(); }; return sigma; }(function () { return (typeof sigma === "function" ? PropTypes.instanceOf(sigma) : PropTypes.any).apply(this, arguments); }), children: PropTypes.any }); export default ForceAtlas2; import PropTypes from "prop-types";