"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.CytoscapeContext = exports.Cytoscape = void 0; var _cytoscape = _interopRequireDefault(require("cytoscape")); var _cytoscapeDagre = _interopRequireDefault(require("cytoscape-dagre")); var _lodash = require("lodash"); var _react = _interopRequireWildcard(require("react")); var _use_theme = require("../../../hooks/use_theme"); var _use_trace_explorer_enabled_setting = require("../../../hooks/use_trace_explorer_enabled_setting"); var _cytoscape_options = require("./cytoscape_options"); var _use_cytoscape_event_handlers = require("./use_cytoscape_event_handlers"); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (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; } /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ _cytoscape.default.use(_cytoscapeDagre.default); const CytoscapeContext = /*#__PURE__*/(0, _react.createContext)(undefined); exports.CytoscapeContext = CytoscapeContext; function useCytoscape(options) { const [cy, setCy] = (0, _react.useState)(undefined); const ref = (0, _react.useRef)(null); (0, _react.useEffect)(() => { if (!cy) { setCy((0, _cytoscape.default)({ ...options, container: ref.current })); } }, [options, cy]); // Destroy the cytoscape instance on unmount (0, _react.useEffect)(() => { return () => { if (cy) { cy.destroy(); } }; }, [cy]); return [ref, cy]; } function CytoscapeComponent({ children, elements, height, serviceName, style }) { const theme = (0, _use_theme.useTheme)(); const isTraceExplorerEnabled = (0, _use_trace_explorer_enabled_setting.useTraceExplorerEnabledSetting)(); const [ref, cy] = useCytoscape({ ...(0, _cytoscape_options.getCytoscapeOptions)(theme, isTraceExplorerEnabled), elements }); (0, _use_cytoscape_event_handlers.useCytoscapeEventHandlers)({ cy, serviceName, theme }); // Add items from the elements prop to the cytoscape collection and remove // items that no longer are in the list, then trigger an event to notify // the handlers that data has changed. (0, _react.useEffect)(() => { if (cy && elements.length > 0) { // We do a fit if we're going from 0 to >0 elements const fit = cy.elements().length === 0; cy.add(elements); // Remove any old elements that don't exist in the new set of elements. const elementIds = elements.map(element => element.data.id); cy.elements().forEach(element => { if (!elementIds.includes(element.data('id'))) { cy.remove(element); } else { var _newElement$data; // Doing an "add" with an element with the same id will keep the original // element. Set the data with the new element data. const newElement = elements.find(el => el.data.id === element.id()); element.data((_newElement$data = newElement === null || newElement === void 0 ? void 0 : newElement.data) !== null && _newElement$data !== void 0 ? _newElement$data : element.data()); } }); cy.trigger('custom:data', [fit]); } }, [cy, elements]); // Add the height to the div style. The height is a separate prop because it // is required and can trigger rendering when changed. const divStyle = { ...style, height }; return /*#__PURE__*/_react.default.createElement(CytoscapeContext.Provider, { value: cy }, /*#__PURE__*/_react.default.createElement("div", { ref: ref, style: divStyle }, children)); } const Cytoscape = /*#__PURE__*/(0, _react.memo)(CytoscapeComponent, (prevProps, nextProps) => { const prevElementIds = prevProps.elements.map(element => element.data.id).sort(); const nextElementIds = nextProps.elements.map(element => element.data.id).sort(); const propsAreEqual = prevProps.height === nextProps.height && prevProps.serviceName === nextProps.serviceName && (0, _lodash.isEqual)(prevProps.style, nextProps.style) && (0, _lodash.isEqual)(prevElementIds, nextElementIds); return propsAreEqual; }); exports.Cytoscape = Cytoscape;