"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.GraphVisualization = GraphVisualization; var _react = _interopRequireWildcard(require("react")); var _classnames = _interopRequireDefault(require("classnames")); var _d = _interopRequireDefault(require("d3")); var _persistence = require("../../services/persistence"); var _icon_renderer = require("../icon_renderer"); 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. */ function registerZooming(element) { const blockScroll = function () { _d.default.event.preventDefault(); }; _d.default.select(element).on('mousewheel', blockScroll).on('DOMMouseScroll', blockScroll).call(_d.default.behavior.zoom().on('zoom', () => { const event = _d.default.event; _d.default.select(element).select('g').attr('transform', 'translate(' + event.translate + ')' + 'scale(' + event.scale + ')').attr('style', 'stroke-width: ' + 1 / event.scale); })); } function makeEdgeId(edge) { return `${(0, _persistence.makeNodeId)(edge.source.data.field, edge.source.data.term)}-${(0, _persistence.makeNodeId)(edge.target.data.field, edge.target.data.term)}`; } function GraphVisualization({ workspace, selectSelected, onSetControl, onSetMergeCandidates }) { const svgRoot = (0, _react.useRef)(null); const nodeClick = (n, event) => { // Selection logic - shift key+click helps selects multiple nodes // Without the shift key we deselect all prior selections (perhaps not // a great idea for touch devices with no concept of shift key) if (!event.shiftKey) { const prevSelection = n.isSelected; workspace.selectNone(); n.isSelected = prevSelection; } if (workspace.toggleNodeSelection(n)) { selectSelected(n); } else { onSetControl('none'); } workspace.changeHandler(); }; const handleMergeCandidatesCallback = termIntersects => { const mergeCandidates = [...termIntersects]; onSetMergeCandidates(mergeCandidates); onSetControl('mergeTerms'); }; const edgeClick = edge => { // no multiple selection for now const currentSelection = workspace.getEdgeSelection(); if (currentSelection.length && currentSelection[0] !== edge) { workspace.clearEdgeSelection(); } if (!edge.isSelected) { workspace.addEdgeToSelection(edge); } else { workspace.removeEdgeFromSelection(edge); } onSetControl('edgeSelection'); if (edge.isSelected) { workspace.getAllIntersections(handleMergeCandidatesCallback, [edge.topSrc, edge.topTarget]); } }; return /*#__PURE__*/_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", className: "gphGraph", width: "100%", height: "100%", pointerEvents: "all", id: "graphSvg", ref: element => { if (element && svgRoot.current !== element) { svgRoot.current = element; registerZooming(element); } } }, /*#__PURE__*/_react.default.createElement("g", null, /*#__PURE__*/_react.default.createElement("g", null, workspace.edges && workspace.edges.map(edge => /*#__PURE__*/_react.default.createElement("g", { key: makeEdgeId(edge), className: "gphEdge--wrapper" }, /*#__PURE__*/_react.default.createElement("line", { x1: edge.topSrc.kx, y1: edge.topSrc.ky, x2: edge.topTarget.kx, y2: edge.topTarget.ky, className: (0, _classnames.default)('gphEdge', { 'gphEdge--selected': edge.isSelected }), strokeLinecap: "round", style: { strokeWidth: edge.width } }), /*#__PURE__*/_react.default.createElement("line", { x1: edge.topSrc.kx, y1: edge.topSrc.ky, x2: edge.topTarget.kx, y2: edge.topTarget.ky, onClick: () => { edgeClick(edge); }, className: "gphEdge gphEdge--clickable", style: { strokeWidth: Math.max(edge.width, 15) } })))), workspace.nodes && workspace.nodes.filter(node => !node.parent).map(node => { const iconOffset = (0, _icon_renderer.getIconOffset)(node.icon); const kx = node.kx || 0; const ky = node.ky || 0; return /*#__PURE__*/_react.default.createElement("g", { key: (0, _persistence.makeNodeId)(node.data.field, node.data.term), onClick: e => { nodeClick(node, e); }, onMouseDown: e => { // avoid selecting text when selecting nodes if (e.ctrlKey || e.shiftKey) { e.preventDefault(); } }, className: "gphNode" }, /*#__PURE__*/_react.default.createElement("circle", { cx: kx, cy: ky, r: node.scaledSize, className: (0, _classnames.default)('gphNode__circle', { 'gphNode__circle--selected': node.isSelected }), style: { fill: node.color } }), /*#__PURE__*/_react.default.createElement(_icon_renderer.IconRenderer, { icon: node.icon, color: node.color, x: kx - ((iconOffset === null || iconOffset === void 0 ? void 0 : iconOffset.x) || 0), y: ky - ((iconOffset === null || iconOffset === void 0 ? void 0 : iconOffset.y) || 0) }), node.label.length < 30 && /*#__PURE__*/_react.default.createElement("text", { className: "gphNode__label", textAnchor: "middle", transform: "translate(0,22)", x: kx, y: ky }, node.label), node.label.length >= 30 && /*#__PURE__*/_react.default.createElement("foreignObject", { width: "100", height: "20", transform: "translate(-50,15)", x: kx, y: ky }, /*#__PURE__*/_react.default.createElement("p", { className: "gphNode__label gphNode__label--html gphNoUserSelect" }, node.label)), node.numChildren > 0 && /*#__PURE__*/_react.default.createElement("g", null, /*#__PURE__*/_react.default.createElement("circle", { r: "5", className: "gphNode__markerCircle", transform: "translate(10,10)", cx: kx, cy: ky }), /*#__PURE__*/_react.default.createElement("text", { className: "gphNode__markerText", textAnchor: "middle", transform: "translate(10,12)", x: kx, y: ky }, node.numChildren))); }))); }