UNPKG

@kieler/klighd-core

Version:

Core KLighD diagram visualization with Sprotty

408 lines 19.9 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.KEdgeView = exports.KLabelView = exports.KPortView = exports.KNodeView = exports.SKGraphView = void 0; /* * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient * * http://rtsys.informatik.uni-kiel.de/kieler * * Copyright 2019-2023 by * + Kiel University * + Department of Computer Science * + Real-Time and Embedded Systems Group * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. * * SPDX-License-Identifier: EPL-2.0 */ /** @jsx svg */ const helper_methods_1 = require("@kieler/klighd-interactive/lib/helper-methods"); const interactive_view_1 = require("@kieler/klighd-interactive/lib/interactive-view"); const klighd_interactive_mouselistener_1 = require("@kieler/klighd-interactive/lib/klighd-interactive-mouselistener"); const layered_relative_constraint_view_1 = require("@kieler/klighd-interactive/lib/layered/layered-relative-constraint-view"); const inversify_1 = require("inversify"); const sprotty_1 = require("sprotty"); const actions_1 = require("./actions/actions"); const depth_map_1 = require("./depth-map"); const di_symbols_1 = require("./di.symbols"); const overpass_1 = require("./fonts/overpass"); const render_options_registry_1 = require("./options/render-options-registry"); const skgraph_models_1 = require("./skgraph-models"); const views_rendering_1 = require("./views-rendering"); const views_styles_1 = require("./views-styles"); /** * IView component that turns an SGraph element and its children into a tree of virtual DOM elements. * Extends the SGraphView by initializing the context for KGraph rendering. */ let SKGraphView = class SKGraphView { render(model, context) { const ctx = context; this.actionDispatcher.dispatch(actions_1.SendModelContextAction.create(model, ctx)); if (!ctx.renderingDefs) { // Make sure not to create a new map all the time ctx.renderingDefs = new Map(); } ctx.renderingDefs.set('font', fontDefinition()); ctx.mListener = this.mListener; ctx.renderOptionsRegistry = this.renderOptionsRegistry; const viewport = (0, sprotty_1.findParentByFeature)(model, sprotty_1.isViewport); if (viewport) { ctx.viewport = viewport; } ctx.titleStorage.clear(); // Add depthMap to context for rendering, when required. const smartZoomOption = ctx.renderOptionsRegistry.getValue(render_options_registry_1.UseSmartZoom); // Only enable, if option is found. const useSmartZoom = smartZoomOption !== null && smartZoomOption !== void 0 ? smartZoomOption : false; if (useSmartZoom && ctx.targetKind !== 'hidden') { ctx.depthMap = depth_map_1.DepthMap.getDM(); if (!ctx.forceRendering && ctx.viewport && ctx.depthMap) { ctx.depthMap.updateDetailLevels(ctx.viewport, ctx.renderOptionsRegistry); } } else { ctx.depthMap = undefined; } const transform = `scale(${model.zoom}) translate(${-model.scroll.x},${-model.scroll.y})`; return ((0, sprotty_1.svg)("svg", { "class-sprotty-graph": true }, (0, sprotty_1.svg)("g", { transform: transform }, context.renderChildren(model)))); } }; exports.SKGraphView = SKGraphView; __decorate([ (0, inversify_1.inject)(klighd_interactive_mouselistener_1.KlighdInteractiveMouseListener), __metadata("design:type", klighd_interactive_mouselistener_1.KlighdInteractiveMouseListener) ], SKGraphView.prototype, "mListener", void 0); __decorate([ (0, inversify_1.inject)(di_symbols_1.DISymbol.RenderOptionsRegistry), __metadata("design:type", render_options_registry_1.RenderOptionsRegistry) ], SKGraphView.prototype, "renderOptionsRegistry", void 0); __decorate([ (0, inversify_1.inject)(sprotty_1.TYPES.IActionDispatcher), __metadata("design:type", Object) ], SKGraphView.prototype, "actionDispatcher", void 0); exports.SKGraphView = SKGraphView = __decorate([ (0, inversify_1.injectable)() ], SKGraphView); /** * IView component that translates a KNode and its children into a tree of virtual DOM elements. */ let KNodeView = class KNodeView { render(node, context) { // Add new level to title and position array for correct placement of titles const ctx = context; if (!ctx.forceRendering && ctx.depthMap) { const containingRegion = ctx.depthMap.getContainingRegion(node, ctx.viewport, ctx.renderOptionsRegistry); if (ctx.depthMap && containingRegion && containingRegion.detail !== depth_map_1.DetailLevel.FullDetails) { // Make sure this node and its children are not drawn as long as it is not on full details. node.areChildAreaChildrenRendered = true; node.areNonChildAreaChildrenRendered = true; return undefined; } } // reset these properties, if the diagram is drawn a second time node.areChildAreaChildrenRendered = false; node.areNonChildAreaChildrenRendered = false; const result = []; const isShadow = node.shadow; let shadow; let interactiveNodes; let interactiveConstraints; if (isShadow) { // Render shadow of the node shadow = (0, views_rendering_1.getRendering)(node.data, node, new views_styles_1.KStyles(false), ctx); if (this.mListener.relativeConstraintMode) { // render visualization for relative constraints result.push((0, layered_relative_constraint_view_1.renderRelativeConstraint)(node.parent, node)); } } if ((0, helper_methods_1.isChildSelected)(node)) { if (node.properties['org.eclipse.elk.interactiveLayout'] && ctx.mListener.hasDragged) { // Render the visualization for interactive layout interactiveNodes = (0, interactive_view_1.renderInteractiveLayout)(node, this.mListener.relativeConstraintMode); } } // Render nodes and constraint icon. All nodes that are not moved do not have a shadow and have their opacity set to 0.1. node.shadow = false; let rendering; if (!ctx.mListener.hasDragged || (0, helper_methods_1.isChildSelected)(node.parent)) { if (node.forbidden) { node.opacity = 0.1; } // Node should only be visible if the node is in the same hierarchical level as the moved node or no node is moved at all rendering = (0, views_rendering_1.getRendering)(node.data, node, new views_styles_1.KStyles(false), ctx); if (ctx.renderOptionsRegistry.getValue(render_options_registry_1.ShowConstraintOption) && node.parent.properties && node.parent.properties['org.eclipse.elk.interactiveLayout']) { // render icon visualizing the set Constraints interactiveConstraints = (0, interactive_view_1.renderConstraints)(node); } // Currently does not work, since it changes the order of teh nodes in the dom. // After setting a constraint and deleting it afterwards this leads to the problem that one node is there twice and one is gone // until the diagram is again updated. // if (node.selected) { // let root = node.parent // while ((root as SKNode).parent) { // root = (root as SKNode).parent // } // new BringToFrontCommand(new BringToFrontAction([node.id])).execute({ // root: root as SModelRoot, // modelFactory: this.graphFactory, // duration: 100, // modelChanged: undefined!, // logger: new ConsoleLogger(), // syncer: new AnimationFrameSyncer() // }) // } } else { node.opacity = 0.1; rendering = (0, views_rendering_1.getRendering)(node.data, node, new views_styles_1.KStyles(false), ctx); } node.shadow = isShadow; node.highlight = false; if (node.id === '$root') { // The root node should not be rendered, only its children should. const children = ctx.renderChildren(node); // Add all color and shadow definitions put into the context by the child renderings. const defs = (0, sprotty_1.svg)("defs", null); ctx.renderingDefs.forEach((value) => { ; defs.children.push(value); }); result.push(defs); if (interactiveNodes) { result.push(interactiveNodes); } result.push(...children); const title = ctx.titleStorage.getTitle(); if (title !== undefined) { result.push(title); } return (0, sprotty_1.svg)("g", null, ...result); } // Add renderings that are not undefined if (shadow !== undefined) { result.push(shadow); } if (rendering !== undefined) { result.push(rendering); } else { const title = ctx.titleStorage.getTitle(); if (title !== undefined) { result.push(title); } return ((0, sprotty_1.svg)("g", null, title !== null && title !== void 0 ? title : [], ctx.renderChildren(node))); } if (interactiveNodes) { result.push(interactiveNodes); } if (interactiveConstraints) { result.push(interactiveConstraints); } // Default case. If no child area children or no non-child area children are already rendered within the rendering, add the children by default. if (!node.areChildAreaChildrenRendered) { result.push(...ctx.renderChildren(node)); } else if (!node.areNonChildAreaChildrenRendered) { result.push(...ctx.renderNonChildAreaChildren(node)); } const title = ctx.titleStorage.getTitle(); if (title !== undefined) { result.push(title); } return (0, sprotty_1.svg)("g", null, ...result); } }; exports.KNodeView = KNodeView; __decorate([ (0, inversify_1.inject)(klighd_interactive_mouselistener_1.KlighdInteractiveMouseListener), __metadata("design:type", klighd_interactive_mouselistener_1.KlighdInteractiveMouseListener) ], KNodeView.prototype, "mListener", void 0); exports.KNodeView = KNodeView = __decorate([ (0, inversify_1.injectable)() ], KNodeView); /** * IView component that translates a KPort and its children into a tree of virtual DOM elements. */ let KPortView = class KPortView { render(port, context) { var _a, _b, _c, _d; // Add new level to title and position array for correct placement of titles const ctx = context; if (!ctx.forceRendering && ctx.depthMap) { const containingRegion = ctx.depthMap.getContainingRegion(port, ctx.viewport, ctx.renderOptionsRegistry); if (ctx.depthMap && containingRegion && containingRegion.detail !== depth_map_1.DetailLevel.FullDetails) { port.areChildAreaChildrenRendered = true; port.areNonChildAreaChildrenRendered = true; return undefined; } } port.areChildAreaChildrenRendered = false; port.areNonChildAreaChildrenRendered = false; const rendering = (0, views_rendering_1.getRendering)(port.data, port, new views_styles_1.KStyles(false), ctx); // If no rendering could be found, just render its children. if (rendering === undefined) { const element = ((0, sprotty_1.svg)("g", null, (_a = ctx.titleStorage.getTitle()) !== null && _a !== void 0 ? _a : [], ctx.renderChildren(port))); return element; } // Default case. If no child area children or no non-child area children are already rendered within the rendering, add the children by default. let element; if (!port.areChildAreaChildrenRendered) { element = ((0, sprotty_1.svg)("g", null, rendering, (_b = ctx.titleStorage.getTitle()) !== null && _b !== void 0 ? _b : [], ctx.renderChildren(port))); } else if (!port.areNonChildAreaChildrenRendered) { element = ((0, sprotty_1.svg)("g", null, rendering, (_c = ctx.titleStorage.getTitle()) !== null && _c !== void 0 ? _c : [], ctx.renderNonChildAreaChildren(port))); } else { element = ((0, sprotty_1.svg)("g", null, rendering, (_d = ctx.titleStorage.getTitle()) !== null && _d !== void 0 ? _d : [])); } return element; } }; exports.KPortView = KPortView; exports.KPortView = KPortView = __decorate([ (0, inversify_1.injectable)() ], KPortView); /** * IView component that translates a KLabel and its children into a tree of virtual DOM elements. */ let KLabelView = class KLabelView { render(label, context) { var _a, _b, _c, _d; // Add new level to title and position array for correct placement of titles const ctx = context; if (!ctx.forceRendering && ctx.depthMap) { const containingRegion = ctx.depthMap.getContainingRegion(label, ctx.viewport, ctx.renderOptionsRegistry); if (ctx.depthMap && containingRegion && containingRegion.detail !== depth_map_1.DetailLevel.FullDetails) { label.areChildAreaChildrenRendered = true; label.areNonChildAreaChildrenRendered = true; return undefined; } } label.areChildAreaChildrenRendered = false; label.areNonChildAreaChildrenRendered = false; // let parent = label.parent if (ctx.mListener.hasDragged) { // Nodes that are not on the same hierarchy are less visible. label.opacity = 0.1; } const rendering = (0, views_rendering_1.getRendering)(label.data, label, new views_styles_1.KStyles(false), ctx); // If no rendering could be found, just render its children. if (rendering === undefined) { const element = ((0, sprotty_1.svg)("g", null, (_a = ctx.titleStorage.getTitle()) !== null && _a !== void 0 ? _a : [], ctx.renderChildren(label))); return element; } // Default case. If no child area children or no non-child area children are already rendered within the rendering, add the children by default. let element; if (!label.areChildAreaChildrenRendered) { element = ((0, sprotty_1.svg)("g", null, rendering, (_b = ctx.titleStorage.getTitle()) !== null && _b !== void 0 ? _b : [], ctx.renderChildren(label))); } else if (!label.areNonChildAreaChildrenRendered) { element = ((0, sprotty_1.svg)("g", null, rendering, (_c = ctx.titleStorage.getTitle()) !== null && _c !== void 0 ? _c : [], ctx.renderNonChildAreaChildren(label))); } else { element = ((0, sprotty_1.svg)("g", null, rendering, (_d = ctx.titleStorage.getTitle()) !== null && _d !== void 0 ? _d : [])); } return element; } }; exports.KLabelView = KLabelView; exports.KLabelView = KLabelView = __decorate([ (0, inversify_1.injectable)() ], KLabelView); /** * IView component that translates a KEdge and its children into a tree of virtual DOM elements. */ let KEdgeView = class KEdgeView { render(edge, context) { const ctx = context; if (!ctx.forceRendering && ctx.depthMap) { const containingRegion = ctx.depthMap.getContainingRegion(edge, ctx.viewport, ctx.renderOptionsRegistry); if (ctx.depthMap && containingRegion && containingRegion.detail !== depth_map_1.DetailLevel.FullDetails) { edge.areChildAreaChildrenRendered = true; edge.areNonChildAreaChildrenRendered = true; return undefined; } } edge.areChildAreaChildrenRendered = false; edge.areNonChildAreaChildrenRendered = false; const s = edge.source; const t = edge.target; // Do not draw edges without a source or target. if (s === undefined || t === undefined) { return (0, sprotty_1.svg)("g", null); } // edge should be greyed out if the source or target is moved if (s !== undefined && t !== undefined && s instanceof skgraph_models_1.SKNode && t instanceof skgraph_models_1.SKNode) { edge.moved = (s.selected || t.selected) && ctx.mListener.hasDragged; } let rendering; if (!ctx.mListener.hasDragged || (0, helper_methods_1.isChildSelected)(edge.parent)) { // edge should only be visible if it is in the same hierarchical level as // the moved node or no node is moved at all rendering = (0, views_rendering_1.getRendering)(edge.data, edge, new views_styles_1.KStyles(false), ctx); } edge.moved = false; // Also get the renderings for all junction points const junctionPointRenderings = (0, views_rendering_1.getJunctionPointRenderings)(edge, ctx); // If no rendering could be found, just render its children. if (rendering === undefined) { return ((0, sprotty_1.svg)("g", null, ctx.renderChildren(edge), ...junctionPointRenderings)); } // Default case. If no child area children or no non-child area children are already rendered within the rendering, add the children by default. if (!edge.areChildAreaChildrenRendered) { return ((0, sprotty_1.svg)("g", null, rendering, ctx.renderChildren(edge), ...junctionPointRenderings)); } if (!edge.areNonChildAreaChildrenRendered) { return ((0, sprotty_1.svg)("g", null, rendering, ctx.renderNonChildAreaChildren(edge), ...junctionPointRenderings)); } return ((0, sprotty_1.svg)("g", null, rendering, ...junctionPointRenderings)); } }; exports.KEdgeView = KEdgeView; exports.KEdgeView = KEdgeView = __decorate([ (0, inversify_1.injectable)() ], KEdgeView); function fontDefinition() { // TODO: maybe find a way to only include the font if it is used in the SVG. return ((0, sprotty_1.svg)("style", null, overpass_1.overpassRegularStyle, overpass_1.overpassMonoRegularStyle)); } //# sourceMappingURL=views.js.map