How to use placer method in stryker-parent

Best JavaScript code snippet using stryker-parent

NodePlacerPanel.js

Source:NodePlacerPanel.js Github

copy

Full Screen

1/****************************************************************************2 ** @license3 ** This demo file is part of yFiles for HTML 2.1.4 ** Copyright (c) 2000-2018 by yWorks GmbH, Vor dem Kreuzberg 28,5 ** 72070 Tuebingen, Germany. All rights reserved.6 **7 ** yFiles demo files exhibit yFiles for HTML functionalities. Any redistribution8 ** of demo files in source code or binary form, with or without9 ** modification, is not permitted.10 **11 ** Owners of a valid software license for a yFiles for HTML version that this12 ** demo is shipped with are allowed to use the demo source code as basis13 ** for their own yFiles for HTML powered applications. Use of such programs is14 ** governed by the rights and conditions as set out in the yFiles for HTML15 ** license agreement.16 **17 ** THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESS OR IMPLIED18 ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF19 ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN20 ** NO EVENT SHALL yWorks BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,21 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED22 ** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR23 ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF24 ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING25 ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS26 ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.27 **28 ***************************************************************************/29'use strict'30define(['yfiles/layout-tree', 'resources/demo-app'], (31 /** @type {yfiles_namespace} */ /** typeof yfiles */ yfiles,32 app33) => {34 // a map which stores the specified node placer for each layer35 const nodePlacers = new yfiles.collections.Mapper()36 // a list of svg colors that are assigned to the layers37 const layerColors = [38 'crimson',39 'darkturquoise',40 'cornflowerblue',41 'darkslateblue',42 'gold',43 'mediumslateblue',44 'forestgreen',45 'mediumvioletred',46 'darkcyan',47 'chocolate',48 'orange',49 'limegreen',50 'mediumorchid',51 'royalblue',52 'orangered'53 ]54 // a list of fill colors that are assigned to the layers55 const layerFills = [56 yfiles.view.Fill.CRIMSON,57 yfiles.view.Fill.DARK_TURQUOISE,58 yfiles.view.Fill.CORNFLOWER_BLUE,59 yfiles.view.Fill.DARK_SLATE_BLUE,60 yfiles.view.Fill.GOLD,61 yfiles.view.Fill.MEDIUM_SLATE_BLUE,62 yfiles.view.Fill.FOREST_GREEN,63 yfiles.view.Fill.MEDIUM_VIOLET_RED,64 yfiles.view.Fill.DARK_CYAN,65 yfiles.view.Fill.CHOCOLATE,66 yfiles.view.Fill.ORANGE,67 yfiles.view.Fill.LIME_GREEN,68 yfiles.view.Fill.MEDIUM_ORCHID,69 yfiles.view.Fill.ROYAL_BLUE,70 yfiles.view.Fill.ORANGE_RED71 ]72 /**73 * A panel that provides access to customize the node placers for each layer.74 */75 class NodePlacerPanel {76 /**77 * Creates a new instance of NodePlacerPanel.78 * @param {yfiles.graph.IGraph} graph79 */80 constructor(graph) {81 // initialize the preview component where the node placer settings are demonstrated on a small graph82 this.previewComponent = new yfiles.view.GraphComponent('previewComponent')83 createPreviewGraph(this.previewComponent)84 runPreviewLayout(null, this.previewComponent)85 // connect the UI elements of this panel that are not specific for one node placer86 bindActions(this)87 // initialize layer size88 this.$layer = 089 this.$maxLayer = this.updateMaxLayer(graph)90 // initializes change listener handling91 this.changeListeners = []92 // create node placer configurations93 this.nodePlacerConfigurations = new yfiles.collections.Map()94 this.nodePlacerConfigurations.set(95 'DefaultNodePlacer',96 new DefaultNodePlacerConfiguration(this)97 )98 this.nodePlacerConfigurations.set('SimpleNodePlacer', new SimpleNodePlacerConfiguration(this))99 this.nodePlacerConfigurations.set('BusNodePlacer', new BusNodePlacerConfiguration(this))100 this.nodePlacerConfigurations.set(101 'DoubleLineNodePlacer',102 new DoubleLineNodePlacerConfiguration(this)103 )104 this.nodePlacerConfigurations.set(105 'LeftRightNodePlacer',106 new LeftRightNodePlacerConfiguration(this)107 )108 this.nodePlacerConfigurations.set(109 'AspectRatioNodePlacer',110 new AspectRatioNodePlacerConfiguration(this)111 )112 this.nodePlacerConfigurations.set(113 'AssistantNodePlacer',114 new AssistantNodePlacerConfiguration(this)115 )116 this.nodePlacerConfigurations.set(117 'CompactNodePlacer',118 new CompactNodePlacerConfiguration(this)119 )120 // choose DefaultNodePlacer as initial node placer for all layers121 this.currentNodePlacerConfiguration = this.nodePlacerConfigurations.get('DefaultNodePlacer')122 this.currentNodePlacerConfiguration.visible = true123 this.currentNodePlacerConfiguration.updatePanel()124 this.panelChanged()125 }126 /**127 * Returns a map which provides a {@link yfiles.tree.INodePlacer} for each layer128 * @return {yfiles.collections.Mapper.<yfiles.tree.INodePlacer>}129 */130 get nodePlacers() {131 return nodePlacers132 }133 /**134 * Returns the current layer whose settings are accessible through this panel.135 * @return {number}136 */137 get layer() {138 return this.$layer139 }140 /**141 * Sets the current layer whose settings are accessible through this panel.142 * @param {number} layer143 */144 set layer(layer) {145 this.$layer = layer146 document.getElementById('layer-index').value = layer147 this.onLayerChanged(layer)148 }149 /**150 * Returns the maximum layer for the current graph.151 * @return {number}152 */153 get maxLayer() {154 return this.$maxLayer155 }156 /**157 * Updates the maximum layer for the current graph. This should be called when nodes were added/removed.158 * @param {yfiles.graph.IGraph} graph159 */160 updateMaxLayer(graph) {161 let max = 0162 graph.nodes.forEach(node => {163 max = Math.max(max, node.tag.layer)164 })165 if (this.$maxLayer !== max) {166 const layerIndex = document.getElementById('layer-index')167 layerIndex.max = max168 }169 this.$maxLayer = max170 }171 /**172 * Returns a list of fill colors that can be used to color the nodes in the color of their layer.173 * @return {Array.<yfiles.view.Fill>}174 */175 static get layerFills() {176 return layerFills177 }178 /**179 * Updates the node placer map and preview graph.180 * This method is called when there are changes in the panel and notifies all registered change listeners.181 */182 panelChanged() {183 const nodePlacer = this.currentNodePlacerConfiguration.createNodePlacer()184 const layerIndex = document.getElementById('layer-index').value185 this.nodePlacers.set(layerIndex, nodePlacer)186 runPreviewLayout(nodePlacer, this.previewComponent)187 this.updateChangeListeners()188 }189 /**190 * Updates which node placer configuration is used in this panel and the layout of the preview graph.191 * @param {number} newLayer192 */193 onLayerChanged(newLayer) {194 const layer = newLayer % layerColors.length195 const layerDiv = document.getElementById('layer-section')196 layerDiv.setAttribute('style', `background-color:${layerColors[layer]}`)197 const layerLabel = document.getElementById('layer-label')198 const cssClass =199 layer === 1 || layer === 4 || layer === 10 || layer === 11200 ? 'layer-label-black'201 : 'layer-label-white'202 layerLabel.setAttribute('class', cssClass)203 const resetButton = document.getElementById('reset-node-placer')204 const resetCssClass =205 layer === 1 || layer === 4 || layer === 10 || layer === 11206 ? 'reset-node-placer-black'207 : 'reset-node-placer-white'208 resetButton.setAttribute('class', resetCssClass)209 const layerIndex = document.getElementById('layer-index').value210 const nodePlacer = nodePlacers.get(layerIndex) || new yfiles.tree.DefaultNodePlacer()211 const configurationName = getConfigurationName(nodePlacer)212 app.setComboboxValue('select-node-placer', configurationName)213 const configuration = this.nodePlacerConfigurations.get(configurationName)214 configuration.adoptSettings(nodePlacer)215 this.currentNodePlacerConfiguration.visible = false216 this.currentNodePlacerConfiguration = configuration217 this.currentNodePlacerConfiguration.visible = true218 const rotationElement = document.getElementById('rotation')219 const spacingElement = document.getElementById('rotatable-spacing')220 if (configuration.rotatable) {221 rotationElement.style.display = 'block'222 spacingElement.style.display = 'block'223 } else {224 rotationElement.style.display = 'none'225 spacingElement.style.display = 'none'226 }227 this.currentNodePlacerConfiguration.updatePanel()228 this.nodePlacers.set(layerIndex, nodePlacer)229 runPreviewLayout(nodePlacer, this.previewComponent)230 }231 /**232 * Adds the given listener to the list of listeners that are notified when the node placer settings change.233 * @param {function} listener234 */235 addChangeListener(listener) {236 this.changeListeners.push(listener)237 }238 /**239 * Removes the given listener to the list of listeners that are notified when the node placer settings change.240 * @param {function} listener241 */242 removeChangeListener(listener) {243 const index = this.changeListeners.indexOf(listener)244 if (index >= 0) {245 this.changeListeners.splice(index, 1)246 }247 }248 /**249 * Notifies all registered change listeners.250 */251 updateChangeListeners() {252 this.changeListeners.forEach(listener => {253 listener()254 })255 }256 }257 /**258 * Calculates a preview layout. This method is called when node placer settings are changed.259 * @param {yfiles.tree.INodePlacer} nodePlacer260 * @param {yfiles.view.GraphComponent} graphComponent261 */262 function runPreviewLayout(nodePlacer, graphComponent) {263 const treeLayout = new yfiles.tree.TreeLayout()264 const treeLayoutData = new yfiles.tree.TreeLayoutData()265 const leafNodePlacer = new yfiles.tree.LeafNodePlacer()266 treeLayoutData.nodePlacers.delegate = node => {267 if (graphComponent.graph.inDegree(node) === 0) {268 return nodePlacer269 }270 return leafNodePlacer271 }272 treeLayoutData.assistantNodes.delegate = node => node.tag && node.tag.assistant273 graphComponent.morphLayout(treeLayout, '0.2s', treeLayoutData)274 }275 /**276 * Wires up the UI elements that are not node placer specific.277 * @param {NodePlacerPanel} panel278 */279 function bindActions(panel) {280 const layerIndex = document.getElementById('layer-index')281 layerIndex.addEventListener('input', () => {282 layerIndex.value = Math.max(layerIndex.min, Math.min(layerIndex.value, layerIndex.max))283 panel.onLayerChanged(layerIndex.value)284 })285 const selectNodePlacer = document.getElementById('select-node-placer')286 selectNodePlacer.addEventListener('change', () => {287 panel.currentNodePlacerConfiguration.visible = false288 panel.currentNodePlacerConfiguration = panel.nodePlacerConfigurations.get(289 selectNodePlacer.value290 )291 panel.currentNodePlacerConfiguration.visible = true292 panel.currentNodePlacerConfiguration.adoptSettings(293 panel.currentNodePlacerConfiguration.getDefaultNodePlacer()294 )295 const rotationElement = document.getElementById('rotation')296 const spacingElement = document.getElementById('rotatable-spacing')297 if (panel.currentNodePlacerConfiguration.rotatable) {298 rotationElement.style.display = 'block'299 spacingElement.style.display = 'block'300 } else {301 rotationElement.style.display = 'none'302 spacingElement.style.display = 'none'303 }304 panel.panelChanged()305 })306 const resetNodePlacer = document.getElementById('reset-node-placer')307 resetNodePlacer.addEventListener('click', () => {308 panel.currentNodePlacerConfiguration.visible = false309 panel.currentNodePlacerConfiguration = panel.nodePlacerConfigurations.get('DefaultNodePlacer')310 panel.currentNodePlacerConfiguration.visible = true311 panel.currentNodePlacerConfiguration.adoptSettings(new yfiles.tree.DefaultNodePlacer())312 const rotationElement = document.getElementById('rotation')313 const spacingElement = document.getElementById('rotatable-spacing')314 rotationElement.style.display = 'none'315 spacingElement.style.display = 'none'316 selectNodePlacer.selectedIndex = 0317 panel.panelChanged()318 })319 const rotationLeft = document.getElementById('rotation-left')320 rotationLeft.addEventListener('click', () => {321 const configuration = panel.currentNodePlacerConfiguration322 configuration.modificationMatrix = configuration.modificationMatrix.multiply(323 yfiles.tree.RotatableNodePlacerMatrix.ROT90324 )325 panel.panelChanged()326 })327 const rotationRight = document.getElementById('rotation-right')328 rotationRight.addEventListener('click', () => {329 const configuration = panel.currentNodePlacerConfiguration330 configuration.modificationMatrix = configuration.modificationMatrix.multiply(331 yfiles.tree.RotatableNodePlacerMatrix.ROT270332 )333 panel.panelChanged()334 })335 const mirrorHorizontal = document.getElementById('mirror-horizontal')336 mirrorHorizontal.addEventListener('click', () => {337 const configuration = panel.currentNodePlacerConfiguration338 configuration.modificationMatrix = configuration.modificationMatrix.multiply(339 yfiles.tree.RotatableNodePlacerMatrix.MIR_HOR340 )341 panel.panelChanged()342 })343 const mirrorVertical = document.getElementById('mirror-vertical')344 mirrorVertical.addEventListener('click', () => {345 const configuration = panel.currentNodePlacerConfiguration346 configuration.modificationMatrix = configuration.modificationMatrix.multiply(347 yfiles.tree.RotatableNodePlacerMatrix.MIR_VERT348 )349 panel.panelChanged()350 })351 }352 /**353 * Returns the configuration name to retrieve the correct configuration for the given node placer.354 * @param {yfiles.tree.INodePlacer} nodePlacer355 * @return {string|null}356 */357 function getConfigurationName(nodePlacer) {358 if (nodePlacer instanceof yfiles.tree.DefaultNodePlacer) {359 return 'DefaultNodePlacer'360 } else if (nodePlacer instanceof yfiles.tree.SimpleNodePlacer) {361 return 'SimpleNodePlacer'362 } else if (nodePlacer instanceof yfiles.tree.BusNodePlacer) {363 return 'BusNodePlacer'364 } else if (nodePlacer instanceof yfiles.tree.DoubleLineNodePlacer) {365 return 'DoubleLineNodePlacer'366 } else if (nodePlacer instanceof yfiles.tree.LeftRightNodePlacer) {367 return 'LeftRightNodePlacer'368 } else if (nodePlacer instanceof yfiles.tree.AspectRatioNodePlacer) {369 return 'AspectRatioNodePlacer'370 } else if (nodePlacer instanceof yfiles.tree.AssistantNodePlacer) {371 return 'AssistantNodePlacer'372 } else if (yfiles.tree.CompactNodePlacer.isInstance(nodePlacer)) {373 return 'CompactNodePlacer'374 }375 return null376 }377 /**378 * Creates a small preview graph that demonstrates the node placer settings on a small sample.379 * @param {yfiles.view.GraphComponent} graphComponent380 */381 function createPreviewGraph(graphComponent) {382 const graph = graphComponent.graph383 const root = graph.createNode({384 layout: new yfiles.geometry.Rect(0, 0, 60, 30),385 style: new yfiles.styles.ShapeNodeStyle({386 shape: yfiles.styles.ShapeNodeShape.ROUND_RECTANGLE,387 fill: 'crimson',388 stroke: 'white'389 })390 })391 for (let i = 0; i < 5; i++) {392 if (i > 0) {393 graph.createEdge(394 root,395 graph.createNode({396 layout: new yfiles.geometry.Rect(0, 0, i < 4 ? 60 : 80, 30),397 style: new yfiles.styles.ShapeNodeStyle({398 shape: yfiles.styles.ShapeNodeShape.ROUND_RECTANGLE,399 fill: 'gray',400 stroke: 'white'401 })402 })403 )404 } else {405 graph.createEdge(406 root,407 graph.createNode({408 layout: new yfiles.geometry.Rect(0, 0, 60, 30),409 style: new yfiles.styles.ShapeNodeStyle({410 shape: yfiles.styles.ShapeNodeShape.ROUND_RECTANGLE,411 fill: 'gray',412 stroke: '2px dashed black'413 }),414 tag: { assistant: true }415 })416 )417 }418 }419 }420 /**421 * Base class for a node placer configuration. It provides methods to retrieve a configured422 * {@link yfiles.tree.INodePlacer} and manages the user input.423 */424 class NodePlacerConfiguration {425 /**426 * Creates a new instance of NodePlacerConfiguration.427 * @param {HTMLElement} div428 * @param {yfiles.tree.INodePlacer} nodePlacer429 * @param {Element} panel430 */431 constructor(div, nodePlacer, panel) {432 this.$div = div433 this.$visible = false434 this.adoptSettings(nodePlacer)435 this.bindActions(panel)436 this.updatePanel()437 }438 /**439 * Returns whether or not the represented node placer is rotatable. This is used to determine if the440 * rotation/mirroring-buttons should be visible.441 * @return {boolean}442 */443 get rotatable() {444 return false445 }446 /**447 * Returns whether or not these node placer settings are currently active/visible.448 * @return {boolean}449 */450 get visible() {451 return this.$visible452 }453 /**454 * Sets whether or not these node placer settings should be active/visible.455 * It also updates the description text.456 * @param {boolean} visible457 */458 set visible(visible) {459 this.$visible = visible460 const description = document.getElementById('node-placer-description')461 if (visible) {462 this.$div.style.display = 'block'463 description.innerHTML = this.getDescriptionText()464 } else {465 this.$div.style.display = 'none'466 description.innerHTML = ''467 }468 }469 /**470 * Creates a configured {@link INodePlacer} according to the current settings.471 * This method is called when the map of node placers is updated.472 */473 createNodePlacer() {}474 /**475 * Updates the configuration settings according to the given {@link INodePlacer}.476 * This method is call when the configuration is changed or reset.477 * @param {yfiles.tree.INodePlacer} nodePlacer478 */479 adoptSettings(nodePlacer) {}480 /**481 * Updates the UI after the configuration changed.482 * @see {@link NodePlacerConfiguration#adoptSettings}483 */484 updatePanel() {}485 /**486 * Wires up the UI for this configuration.487 * @param {NodePlacerPanel} panel488 */489 bindActions(panel) {}490 /**491 * Returns the description text for this configuration.492 * @return {string}493 */494 getDescriptionText() {}495 /**496 * Returns the node placer for this configuration with initial settings.497 * @return {yfiles.tree.INodePlacer}498 */499 getDefaultNodePlacer() {}500 }501 /**502 * Base class for all node placer configurations representing node placers inheriting503 * {@link yfiles.tree.RotatableNodePlacerBase}.504 * It will handle the rotation and spacing properties by default.505 */506 class RotatableNodePlacerConfiguration extends NodePlacerConfiguration {507 /**508 * Returns true for all configurations based on this class.509 * @return {boolean}510 */511 get rotatable() {512 return true513 }514 /** @type {yfiles.tree.RotatableNodePlacerBase} */515 get modificationMatrix() {516 return this.$modificationMatrix517 }518 /** @type {yfiles.tree.RotatableNodePlacerBase} */519 set modificationMatrix(value) {520 this.$modificationMatrix = value521 }522 /** @type {number */523 get spacing() {524 return this.$spacing525 }526 /** @type {number */527 set spacing(value) {528 this.$spacing = value529 }530 adoptSettings(nodePlacer) {531 this.spacing = nodePlacer.spacing532 this.modificationMatrix =533 nodePlacer.modificationMatrix || yfiles.tree.RotatableNodePlacerMatrix.DEFAULT534 }535 updatePanel() {536 const spacing = document.getElementById('spacing')537 spacing.value = this.spacing538 const spacingLabel = document.getElementById('spacing-label')539 spacingLabel.innerHTML = this.spacing540 }541 bindActions(panel) {542 const spacing = document.getElementById('spacing')543 spacing.addEventListener('change', () => {544 this.spacing = Number.parseInt(spacing.value)545 panel.panelChanged()546 })547 const spacingLabel = document.getElementById('spacing-label')548 spacing.addEventListener('input', () => {549 spacingLabel.innerHTML = spacing.value550 })551 }552 }553 class DefaultNodePlacerConfiguration extends NodePlacerConfiguration {554 /**555 * Creates a new instance of DefaultNodePlacerConfiguration.556 * @param {Element} panel557 */558 constructor(panel) {559 super(560 document.getElementById('default-node-placer-settings'),561 new yfiles.tree.DefaultNodePlacer(),562 panel563 )564 }565 /** @type {yfiles.tree.ChildPlacement} */566 get childPlacement() {567 return this.$childPlacement568 }569 /** @type {yfiles.tree.ChildPlacement} */570 set childPlacement(value) {571 this.$childPlacement = value572 }573 /** @type {yfiles.tree.RoutingStyle} */574 get routingStyle() {575 return this.$routingStyle576 }577 /** @type {yfiles.tree.RoutingStyle} */578 set routingStyle(value) {579 this.$routingStyle = value580 }581 /** @type {number} */582 get horizontalDistance() {583 return this.$horizontalDistance584 }585 /** @type {number} */586 set horizontalDistance(value) {587 this.$horizontalDistance = value588 }589 /** @type {number} */590 get verticalDistance() {591 return this.$verticalDistance592 }593 /** @type {number} */594 set verticalDistance(value) {595 this.$verticalDistance = value596 }597 /** @type {number} */598 get minimumChannelSegmentDistance() {599 return this.$minimumChannelSegmentDistance600 }601 /** @type {number} */602 set minimumChannelSegmentDistance(value) {603 this.$minimumChannelSegmentDistance = value604 }605 /** @type {yfiles.tree.RootAlignment} */606 get rootAlignment() {607 return this.$rootAlignment608 }609 /** @type {yfiles.tree.RootAlignment} */610 set rootAlignment(value) {611 this.$rootAlignment = value612 }613 createNodePlacer() {614 const nodePlacer = new yfiles.tree.DefaultNodePlacer()615 nodePlacer.childPlacement = this.childPlacement616 nodePlacer.routingStyle = this.routingStyle617 nodePlacer.horizontalDistance = this.horizontalDistance618 nodePlacer.verticalDistance = this.verticalDistance619 nodePlacer.minimumChannelSegmentDistance = this.minimumChannelSegmentDistance620 nodePlacer.rootAlignment = this.rootAlignment621 return nodePlacer622 }623 adoptSettings(nodePlacer) {624 this.childPlacement = nodePlacer.childPlacement625 this.routingStyle = nodePlacer.routingStyle626 this.horizontalDistance = nodePlacer.horizontalDistance627 this.verticalDistance = nodePlacer.verticalDistance628 this.minimumChannelSegmentDistance = nodePlacer.minimumChannelSegmentDistance629 this.rootAlignment = nodePlacer.rootAlignment630 this.updatePanel()631 }632 updatePanel() {633 const childPlacement = document.getElementById('select-child-placement')634 switch (this.childPlacement) {635 default:636 case yfiles.tree.ChildPlacement.HORIZONTAL_DOWNWARD:637 childPlacement.selectedIndex = 0638 break639 case yfiles.tree.ChildPlacement.HORIZONTAL_UPWARD:640 childPlacement.selectedIndex = 1641 break642 case yfiles.tree.ChildPlacement.VERTICAL_TO_LEFT:643 childPlacement.selectedIndex = 2644 break645 case yfiles.tree.ChildPlacement.VERTICAL_TO_RIGHT:646 childPlacement.selectedIndex = 3647 break648 }649 const routingStyle = document.getElementById('routing-style')650 switch (this.routingStyle) {651 default:652 case yfiles.tree.RoutingStyle.FORK:653 routingStyle.selectedIndex = 0654 break655 case yfiles.tree.RoutingStyle.FORK_AT_ROOT:656 routingStyle.selectedIndex = 1657 break658 case yfiles.tree.RoutingStyle.STRAIGHT:659 routingStyle.selectedIndex = 2660 break661 case yfiles.tree.RoutingStyle.POLYLINE:662 routingStyle.selectedIndex = 3663 break664 }665 const horizontalDistance = document.getElementById('horizontal-distance')666 horizontalDistance.value = this.horizontalDistance667 const horizontalDistanceLabel = document.getElementById('horizontal-distance-label')668 horizontalDistanceLabel.innerHTML = this.horizontalDistance669 const verticalDistance = document.getElementById('vertical-distance')670 verticalDistance.value = this.verticalDistance671 const verticalDistanceLabel = document.getElementById('vertical-distance-label')672 verticalDistanceLabel.innerHTML = this.verticalDistance673 const minimumChannelSegmentDistance = document.getElementById(674 'minimum-channel-segment-distance'675 )676 minimumChannelSegmentDistance.value = this.minimumChannelSegmentDistance677 const minimumChannelSegmentDistanceLabel = document.getElementById(678 'minimum-channel-segment-distance-label'679 )680 minimumChannelSegmentDistanceLabel.innerHTML = this.minimumChannelSegmentDistance681 const rootAlignment = document.getElementById('root-alignment')682 switch (this.rootAlignment) {683 default:684 case yfiles.tree.RootAlignment.LEADING_OFFSET:685 rootAlignment.selectedIndex = 0686 break687 case yfiles.tree.RootAlignment.LEADING:688 rootAlignment.selectedIndex = 1689 break690 case yfiles.tree.RootAlignment.CENTER:691 rootAlignment.selectedIndex = 2692 break693 case yfiles.tree.RootAlignment.MEDIAN:694 rootAlignment.selectedIndex = 3695 break696 case yfiles.tree.RootAlignment.TRAILING:697 rootAlignment.selectedIndex = 4698 break699 case yfiles.tree.RootAlignment.TRAILING_OFFSET:700 rootAlignment.selectedIndex = 5701 break702 case yfiles.tree.RootAlignment.LEADING_ON_BUS:703 rootAlignment.selectedIndex = 6704 break705 case yfiles.tree.RootAlignment.TRAILING_ON_BUS:706 rootAlignment.selectedIndex = 7707 break708 }709 }710 getDescriptionText() {711 return (712 '<h2>DefaultNodePlacer</h2>' +713 'This node placer arranges the child nodes horizontally aligned below their root node. It offers options' +714 ' to change the orientation of the subtree, the edge routing style, and the alignment of the root node.'715 )716 }717 bindActions(panel) {718 const childPlacement = document.getElementById('select-child-placement')719 childPlacement.addEventListener('change', () => {720 switch (childPlacement.selectedIndex) {721 default:722 case 0:723 this.childPlacement = yfiles.tree.ChildPlacement.HORIZONTAL_DOWNWARD724 break725 case 1:726 this.childPlacement = yfiles.tree.ChildPlacement.HORIZONTAL_UPWARD727 break728 case 2:729 this.childPlacement = yfiles.tree.ChildPlacement.VERTICAL_TO_LEFT730 break731 case 3:732 this.childPlacement = yfiles.tree.ChildPlacement.VERTICAL_TO_RIGHT733 break734 }735 panel.panelChanged()736 })737 const routingStyle = document.getElementById('routing-style')738 routingStyle.addEventListener('change', () => {739 switch (routingStyle.selectedIndex) {740 default:741 case 0:742 this.routingStyle = yfiles.tree.RoutingStyle.FORK743 break744 case 1:745 this.routingStyle = yfiles.tree.RoutingStyle.FORK_AT_ROOT746 break747 case 2:748 this.routingStyle = yfiles.tree.RoutingStyle.STRAIGHT749 break750 case 3:751 this.routingStyle = yfiles.tree.RoutingStyle.POLYLINE752 break753 }754 panel.panelChanged()755 })756 const horizontalDistance = document.getElementById('horizontal-distance')757 horizontalDistance.addEventListener('change', () => {758 this.horizontalDistance = Number.parseInt(horizontalDistance.value)759 panel.panelChanged()760 })761 const horizontalDistanceLabel = document.getElementById('horizontal-distance-label')762 horizontalDistance.addEventListener('input', () => {763 horizontalDistanceLabel.innerHTML = horizontalDistance.value764 })765 const verticalDistance = document.getElementById('vertical-distance')766 verticalDistance.addEventListener('change', () => {767 this.verticalDistance = Number.parseInt(verticalDistance.value)768 panel.panelChanged()769 })770 const verticalDistanceLabel = document.getElementById('vertical-distance-label')771 verticalDistance.addEventListener('input', () => {772 verticalDistanceLabel.innerHTML = verticalDistance.value773 })774 const minimumChannelSegmentDistance = document.getElementById(775 'minimum-channel-segment-distance'776 )777 minimumChannelSegmentDistance.addEventListener('change', () => {778 this.minimumChannelSegmentDistance = Number.parseInt(minimumChannelSegmentDistance.value)779 panel.panelChanged()780 })781 const minimumChannelSegmentDistanceLabel = document.getElementById(782 'minimum-channel-segment-distance-label'783 )784 minimumChannelSegmentDistance.addEventListener('input', () => {785 minimumChannelSegmentDistanceLabel.innerHTML = minimumChannelSegmentDistance.value786 })787 const rootAlignment = document.getElementById('root-alignment')788 rootAlignment.addEventListener('change', () => {789 switch (rootAlignment.selectedIndex) {790 default:791 case 0:792 this.rootAlignment = yfiles.tree.RootAlignment.LEADING_OFFSET793 break794 case 1:795 this.rootAlignment = yfiles.tree.RootAlignment.LEADING796 break797 case 2:798 this.rootAlignment = yfiles.tree.RootAlignment.CENTER799 break800 case 3:801 this.rootAlignment = yfiles.tree.RootAlignment.MEDIAN802 break803 case 4:804 this.rootAlignment = yfiles.tree.RootAlignment.TRAILING805 break806 case 5:807 this.rootAlignment = yfiles.tree.RootAlignment.TRAILING_OFFSET808 break809 case 6:810 this.rootAlignment = yfiles.tree.RootAlignment.LEADING_ON_BUS811 break812 case 7:813 this.rootAlignment = yfiles.tree.RootAlignment.TRAILING_ON_BUS814 break815 }816 panel.panelChanged()817 })818 }819 getDefaultNodePlacer() {820 return new yfiles.tree.DefaultNodePlacer()821 }822 }823 class SimpleNodePlacerConfiguration extends RotatableNodePlacerConfiguration {824 /**825 * Creates a new instance of SimpleNodePlacerConfiguration.826 * @param {Element} panel827 */828 constructor(panel) {829 super(830 document.getElementById('simple-node-placer-settings'),831 new yfiles.tree.SimpleNodePlacer(),832 panel833 )834 }835 /** @type {boolean} */836 get createBus() {837 return this.$createBus838 }839 /** @type {boolean} */840 set createBus(value) {841 this.$createBus = value842 }843 /** @type {yfiles.tree.RootNodeAlignment} */844 get rootAlignment() {845 return this.$rootAlignment846 }847 /** @type {yfiles.tree.RootNodeAlignment} */848 set rootAlignment(value) {849 this.$rootAlignment = value850 }851 /** @type {number} */852 get minimumChannelSegmentDistance() {853 return this.$minimumChannelSegmentDistance854 }855 /** @type {number} */856 set minimumChannelSegmentDistance(value) {857 this.$minimumChannelSegmentDistance = value858 }859 createNodePlacer() {860 const nodePlacer = new yfiles.tree.SimpleNodePlacer(this.modificationMatrix)861 nodePlacer.createBus = this.createBus862 nodePlacer.rootAlignment = this.rootAlignment863 nodePlacer.minimumChannelSegmentDistance = this.minimumChannelSegmentDistance864 nodePlacer.spacing = this.spacing865 return nodePlacer866 }867 adoptSettings(nodePlacer) {868 super.adoptSettings(nodePlacer)869 this.createBus = nodePlacer.createBus870 this.rootAlignment = nodePlacer.rootAlignment871 this.minimumChannelSegmentDistance = nodePlacer.minimumChannelSegmentDistance872 this.updatePanel()873 }874 updatePanel() {875 super.updatePanel()876 const createBus = document.getElementById('create-bus')877 createBus.checked = this.createBus878 const rootAlignment = document.getElementById('simple-root-node-alignment')879 switch (this.rootAlignment) {880 default:881 case yfiles.tree.RootNodeAlignment.LEADING:882 rootAlignment.selectedIndex = 0883 break884 case yfiles.tree.RootNodeAlignment.LEFT:885 rootAlignment.selectedIndex = 1886 break887 case yfiles.tree.RootNodeAlignment.CENTER:888 rootAlignment.selectedIndex = 2889 break890 case yfiles.tree.RootNodeAlignment.CENTER_OVER_CHILDREN:891 rootAlignment.selectedIndex = 3892 break893 case yfiles.tree.RootNodeAlignment.MEDIAN:894 rootAlignment.selectedIndex = 4895 break896 case yfiles.tree.RootNodeAlignment.RIGHT:897 rootAlignment.selectedIndex = 5898 break899 case yfiles.tree.RootNodeAlignment.TRAILING:900 rootAlignment.selectedIndex = 6901 break902 }903 const minimumChannelSegmentDistance = document.getElementById('min-channel-segment-distance')904 minimumChannelSegmentDistance.value = this.minimumChannelSegmentDistance905 }906 getDescriptionText() {907 return (908 '<h2>SimpleNodePlacer</h2>' +909 'This node placer arranges the child nodes horizontally aligned below their root node. It supports rotated' +910 'subtrees and offers options to change the alignment of the root node.'911 )912 }913 bindActions(panel) {914 super.bindActions(panel)915 const createBus = document.getElementById('create-bus')916 createBus.addEventListener('change', () => {917 this.createBus = createBus.checked918 panel.panelChanged()919 })920 const rootAlignment = document.getElementById('simple-root-node-alignment')921 rootAlignment.addEventListener('change', () => {922 switch (rootAlignment.selectedIndex) {923 default:924 case 0:925 this.rootAlignment = yfiles.tree.RootNodeAlignment.LEADING926 break927 case 1:928 this.rootAlignment = yfiles.tree.RootNodeAlignment.LEFT929 break930 case 2:931 this.rootAlignment = yfiles.tree.RootNodeAlignment.CENTER932 break933 case 3:934 this.rootAlignment = yfiles.tree.RootNodeAlignment.CENTER_OVER_CHILDREN935 break936 case 4:937 this.rootAlignment = yfiles.tree.RootNodeAlignment.MEDIAN938 break939 case 5:940 this.rootAlignment = yfiles.tree.RootNodeAlignment.RIGHT941 break942 case 6:943 this.rootAlignment = yfiles.tree.RootNodeAlignment.TRAILING944 break945 }946 panel.panelChanged()947 })948 const minimumChannelSegmentDistance = document.getElementById('min-channel-segment-distance')949 minimumChannelSegmentDistance.addEventListener('change', () => {950 this.minimumChannelSegmentDistance = Number.parseInt(minimumChannelSegmentDistance.value)951 panel.panelChanged()952 })953 const minimumChannelSegmentDistanceLabel = document.getElementById(954 'min-channel-segment-distance-label'955 )956 minimumChannelSegmentDistance.addEventListener('input', () => {957 minimumChannelSegmentDistanceLabel.innerHTML = minimumChannelSegmentDistance.value958 })959 }960 getDefaultNodePlacer() {961 return new yfiles.tree.SimpleNodePlacer()962 }963 }964 class BusNodePlacerConfiguration extends RotatableNodePlacerConfiguration {965 /**966 * Creates a new instance of BusNodePlacerConfiguration.967 * @param {Element} panel968 */969 constructor(panel) {970 super(971 document.getElementById('bus-node-placer-settings'),972 new yfiles.tree.BusNodePlacer(),973 panel974 )975 }976 createNodePlacer() {977 const nodePlacer = new yfiles.tree.BusNodePlacer(this.modificationMatrix)978 nodePlacer.spacing = this.spacing979 return nodePlacer980 }981 adoptSettings(nodePlacer) {982 super.adoptSettings(nodePlacer)983 this.updatePanel()984 }985 getDescriptionText() {986 return (987 '<h2>BusNodePlacer</h2>' +988 'This node placer arranges the child nodes evenly distributed in two lines to the left and right of the root node.'989 )990 }991 getDefaultNodePlacer() {992 return new yfiles.tree.BusNodePlacer()993 }994 }995 class DoubleLineNodePlacerConfiguration extends RotatableNodePlacerConfiguration {996 /**997 * Creates a new instance of DoubleLineNodePlacerConfiguration.998 * @param {Element} panel999 */1000 constructor(panel) {1001 super(1002 document.getElementById('double-line-node-placer-settings'),1003 new yfiles.tree.DoubleLineNodePlacer(),1004 panel1005 )1006 }1007 /** @type {yfiles.tree.RootNodeAlignment} */1008 get rootAlignment() {1009 return this.$rootAlignment1010 }1011 /** @type {yfiles.tree.RootNodeAlignment} */1012 set rootAlignment(value) {1013 this.$rootAlignment = value1014 }1015 createNodePlacer() {1016 const nodePlacer = new yfiles.tree.DoubleLineNodePlacer(this.modificationMatrix)1017 nodePlacer.spacing = this.spacing1018 nodePlacer.rootAlignment = this.rootAlignment1019 return nodePlacer1020 }1021 adoptSettings(nodePlacer) {1022 super.adoptSettings(nodePlacer)1023 this.rootAlignment = nodePlacer.rootAlignment1024 this.updatePanel()1025 }1026 getDescriptionText() {1027 return (1028 '<h2>DoubleLineNodePlacer</h2>' +1029 'This node placer arranges the child nodes staggered in two lines below their root node. It supports rotated' +1030 ' subtrees and offers options to change the alignment of the root node.'1031 )1032 }1033 updatePanel() {1034 super.updatePanel()1035 const rootAlignment = document.getElementById('double-line-root-node-alignment')1036 switch (this.rootAlignment) {1037 default:1038 case yfiles.tree.RootNodeAlignment.LEADING:1039 rootAlignment.selectedIndex = 01040 break1041 case yfiles.tree.RootNodeAlignment.LEFT:1042 rootAlignment.selectedIndex = 11043 break1044 case yfiles.tree.RootNodeAlignment.CENTER:1045 rootAlignment.selectedIndex = 21046 break1047 case yfiles.tree.RootNodeAlignment.CENTER_OVER_CHILDREN:1048 rootAlignment.selectedIndex = 31049 break1050 case yfiles.tree.RootNodeAlignment.MEDIAN:1051 rootAlignment.selectedIndex = 41052 break1053 case yfiles.tree.RootNodeAlignment.RIGHT:1054 rootAlignment.selectedIndex = 51055 break1056 case yfiles.tree.RootNodeAlignment.TRAILING:1057 rootAlignment.selectedIndex = 61058 break1059 }1060 }1061 bindActions(panel) {1062 super.bindActions(panel)1063 const rootAlignment = document.getElementById('double-line-root-node-alignment')1064 rootAlignment.addEventListener('change', () => {1065 switch (rootAlignment.selectedIndex) {1066 default:1067 case 0:1068 this.rootAlignment = yfiles.tree.RootNodeAlignment.LEADING1069 break1070 case 1:1071 this.rootAlignment = yfiles.tree.RootNodeAlignment.LEFT1072 break1073 case 2:1074 this.rootAlignment = yfiles.tree.RootNodeAlignment.CENTER1075 break1076 case 3:1077 this.rootAlignment = yfiles.tree.RootNodeAlignment.CENTER_OVER_CHILDREN1078 break1079 case 4:1080 this.rootAlignment = yfiles.tree.RootNodeAlignment.MEDIAN1081 break1082 case 5:1083 this.rootAlignment = yfiles.tree.RootNodeAlignment.RIGHT1084 break1085 case 6:1086 this.rootAlignment = yfiles.tree.RootNodeAlignment.TRAILING1087 break1088 }1089 panel.panelChanged()1090 })1091 }1092 getDefaultNodePlacer() {1093 return new yfiles.tree.DoubleLineNodePlacer()1094 }1095 }1096 class LeftRightNodePlacerConfiguration extends RotatableNodePlacerConfiguration {1097 /**1098 * Creates a new instance of LeftRightNodePlacerConfiguration.1099 * @param {Element} panel1100 */1101 constructor(panel) {1102 super(1103 document.getElementById('left-right-node-placer-settings'),1104 new yfiles.tree.LeftRightNodePlacer(),1105 panel1106 )1107 }1108 /** @type {boolean} */1109 get lastOnBottom() {1110 return this.$lastOnBottom1111 }1112 /** @type {boolean} */1113 set lastOnBottom(value) {1114 this.$lastOnBottom = value1115 }1116 createNodePlacer() {1117 const nodePlacer = new yfiles.tree.LeftRightNodePlacer(this.modificationMatrix)1118 nodePlacer.spacing = this.spacing1119 nodePlacer.placeLastOnBottom = this.lastOnBottom1120 return nodePlacer1121 }1122 adoptSettings(nodePlacer) {1123 super.adoptSettings(nodePlacer)1124 this.lastOnBottom = nodePlacer.placeLastOnBottom1125 this.updatePanel()1126 }1127 getDescriptionText() {1128 return (1129 '<h2>LeftRightNodePlacer</h2>' +1130 'This node placer arranges the child nodes below their root node, left and right of the downward extending bus-like routing.'1131 )1132 }1133 updatePanel() {1134 const lastOnBottom = document.getElementById('last-on-bottom')1135 lastOnBottom.checked = this.lastOnBottom1136 }1137 bindActions(panel) {1138 super.bindActions(panel)1139 const lastOnBottom = document.getElementById('last-on-bottom')1140 lastOnBottom.addEventListener('change', () => {1141 this.lastOnBottom = lastOnBottom.checked1142 panel.panelChanged()1143 })1144 }1145 getDefaultNodePlacer() {1146 return new yfiles.tree.LeftRightNodePlacer()1147 }1148 }1149 class AspectRatioNodePlacerConfiguration extends NodePlacerConfiguration {1150 /**1151 * Creates a new instance of AspectRatioNodePlacerConfiguration.1152 * @param {Element} panel1153 */1154 constructor(panel) {1155 super(1156 document.getElementById('aspect-ratio-node-placer-settings'),1157 new yfiles.tree.AspectRatioNodePlacer(),1158 panel1159 )1160 }1161 /** @type {number} */1162 get aspectRatio() {1163 return this.$aspectRatio1164 }1165 /** @type {number} */1166 set aspectRatio(value) {1167 this.$aspectRatio = value1168 }1169 /** @type {yfiles.tree.FillStyle} */1170 get fillStyle() {1171 return this.$fillStyle1172 }1173 /** @type {yfiles.tree.FillStyle} */1174 set fillStyle(value) {1175 this.$fillStyle = value1176 }1177 /** @type {boolean} */1178 get horizontal() {1179 return this.$horizontal1180 }1181 /** @type {boolean} */1182 set horizontal(value) {1183 this.$horizontal = value1184 }1185 /** @type {number} */1186 get horizontalDistance() {1187 return this.$horizontalDistance1188 }1189 /** @type {number} */1190 set horizontalDistance(value) {1191 this.$horizontalDistance = value1192 }1193 /** @type {number} */1194 get verticalDistance() {1195 return this.$verticalDistance1196 }1197 /** @type {number} */1198 set verticalDistance(value) {1199 this.$verticalDistance = value1200 }1201 createNodePlacer() {1202 const nodePlacer = new yfiles.tree.AspectRatioNodePlacer()1203 nodePlacer.aspectRatio = this.aspectRatio1204 nodePlacer.fillStyle = this.fillStyle1205 nodePlacer.horizontalDistance = this.horizontalDistance1206 nodePlacer.verticalDistance = this.verticalDistance1207 nodePlacer.horizontal = this.horizontal1208 return nodePlacer1209 }1210 adoptSettings(nodePlacer) {1211 this.aspectRatio = nodePlacer.aspectRatio1212 this.fillStyle = nodePlacer.fillStyle1213 this.horizontalDistance = nodePlacer.horizontalDistance1214 this.verticalDistance = nodePlacer.verticalDistance1215 this.horizontal = nodePlacer.horizontal1216 this.updatePanel()1217 }1218 getDescriptionText() {1219 return (1220 '<h2>AspectRatioNodePlacer</h2>' +1221 'This node placer arranges the child nodes such that a given aspect ratio is obeyed.'1222 )1223 }1224 updatePanel() {1225 const aspectRatio = document.getElementById('aspect-ratio')1226 aspectRatio.value = this.aspectRatio1227 const fillStyle = document.getElementById('fill-style')1228 switch (this.fillStyle) {1229 default:1230 case yfiles.tree.FillStyle.JUSTIFY:1231 fillStyle.selectedIndex = 01232 break1233 case yfiles.tree.FillStyle.LEADING:1234 fillStyle.selectedIndex = 11235 break1236 case yfiles.tree.FillStyle.CENTERED:1237 fillStyle.selectedIndex = 21238 break1239 case yfiles.tree.FillStyle.TRAILING:1240 fillStyle.selectedIndex = 31241 break1242 }1243 const horizontalDistance = document.getElementById('aspect-ratio-horizontal-distance')1244 horizontalDistance.value = this.horizontalDistance1245 const horizontalDistanceLabel = document.getElementById(1246 'aspect-ratio-horizontal-distance-label'1247 )1248 horizontalDistanceLabel.innerHTML = this.horizontalDistance1249 const verticalDistance = document.getElementById('aspect-ratio-vertical-distance')1250 verticalDistance.value = this.verticalDistance1251 const verticalDistanceLabel = document.getElementById('aspect-ratio-vertical-distance-label')1252 verticalDistanceLabel.innerHTML = this.verticalDistance1253 const horizontal = document.getElementById('horizontal')1254 horizontal.checked = this.horizontal1255 }1256 bindActions(panel) {1257 const aspectRatio = document.getElementById('aspect-ratio')1258 aspectRatio.addEventListener('change', () => {1259 this.aspectRatio = Math.max(0.1, Math.min(Number.parseFloat(aspectRatio.value), 2))1260 aspectRatio.value = this.aspectRatio // in case the range is not met1261 panel.panelChanged()1262 })1263 const fillStyle = document.getElementById('fill-style')1264 fillStyle.addEventListener('change', () => {1265 switch (fillStyle.selectedIndex) {1266 default:1267 case 0:1268 this.fillStyle = yfiles.tree.FillStyle.JUSTIFY1269 break1270 case 1:1271 this.fillStyle = yfiles.tree.FillStyle.LEADING1272 break1273 case 2:1274 this.fillStyle = yfiles.tree.FillStyle.CENTERED1275 break1276 case 3:1277 this.fillStyle = yfiles.tree.FillStyle.TRAILING1278 break1279 }1280 panel.panelChanged()1281 })1282 const horizontalDistance = document.getElementById('aspect-ratio-horizontal-distance')1283 horizontalDistance.addEventListener('change', () => {1284 this.horizontalDistance = Number.parseInt(horizontalDistance.value)1285 panel.panelChanged()1286 })1287 const horizontalDistanceLabel = document.getElementById(1288 'aspect-ratio-horizontal-distance-label'1289 )1290 horizontalDistance.addEventListener('input', () => {1291 horizontalDistanceLabel.innerHTML = horizontalDistance.value1292 })1293 const verticalDistance = document.getElementById('aspect-ratio-vertical-distance')1294 verticalDistance.addEventListener('change', () => {1295 this.verticalDistance = Number.parseInt(verticalDistance.value)1296 panel.panelChanged()1297 })1298 const verticalDistanceLabel = document.getElementById('aspect-ratio-vertical-distance-label')1299 verticalDistance.addEventListener('input', () => {1300 verticalDistanceLabel.innerHTML = verticalDistance.value1301 })1302 const horizontal = document.getElementById('horizontal')1303 horizontal.addEventListener('change', () => {1304 this.horizontal = horizontal.checked1305 panel.panelChanged()1306 })1307 }1308 getDefaultNodePlacer() {1309 return new yfiles.tree.AspectRatioNodePlacer()1310 }1311 }1312 class AssistantNodePlacerConfiguration extends RotatableNodePlacerConfiguration {1313 /**1314 * Creates a new instance of AssistantNodePlacerConfiguration.1315 * @param {Element} panel1316 */1317 constructor(panel) {1318 super(1319 document.getElementById('assistant-node-placer-settings'),1320 new yfiles.tree.AssistantNodePlacer(),1321 panel1322 )1323 }1324 /** @type {yfiles.tree.INodePlacer} */1325 get childNodePlacer() {1326 return this.$childNodePlacer1327 }1328 /** @type {yfiles.tree.INodePlacer} */1329 set childNodePlacer(value) {1330 this.$childNodePlacer = value1331 }1332 createNodePlacer() {1333 const nodePlacer = new yfiles.tree.AssistantNodePlacer(this.modificationMatrix)1334 nodePlacer.spacing = this.spacing1335 nodePlacer.childNodePlacer = this.childNodePlacer1336 return nodePlacer1337 }1338 adoptSettings(nodePlacer) {1339 super.adoptSettings(nodePlacer)1340 this.childNodePlacer = nodePlacer.childNodePlacer1341 this.updatePanel()1342 }1343 getDescriptionText() {1344 return (1345 '<h2>AssistantNodePlacer</h2>' +1346 'This node placer delegates to two different node placers to arrange the child nodes: Nodes that are marked' +1347 ' as <em>Assistants</em> are placed using the <a href="https://docs.yworks.com/yfileshtml/#/api/yfiles.tree.LeftRightNodePlacer" target="_blank">yfiles.tree.LeftRightNodePlacer</a>. The other children are arranged' +1348 ' below the assistant nodes using the child node placer.'1349 )1350 }1351 updatePanel() {1352 super.updatePanel()1353 const childNodePlacer = document.getElementById('child-node-placer')1354 if (this.childNodePlacer instanceof yfiles.tree.DefaultNodePlacer) {1355 childNodePlacer.selectedIndex = 01356 } else if (this.childNodePlacer instanceof yfiles.tree.SimpleNodePlacer) {1357 childNodePlacer.selectedIndex = 11358 } else if (this.childNodePlacer instanceof yfiles.tree.BusNodePlacer) {1359 childNodePlacer.selectedIndex = 21360 } else if (this.childNodePlacer instanceof yfiles.tree.DoubleLineNodePlacer) {1361 childNodePlacer.selectedIndex = 31362 } else if (this.childNodePlacer instanceof yfiles.tree.LeftRightNodePlacer) {1363 childNodePlacer.selectedIndex = 41364 } else if (this.childNodePlacer instanceof yfiles.tree.AspectRatioNodePlacer) {1365 childNodePlacer.selectedIndex = 51366 }1367 }1368 bindActions(panel) {1369 super.bindActions(panel)1370 const childNodePlacer = document.getElementById('child-node-placer')1371 childNodePlacer.addEventListener('change', () => {1372 switch (childNodePlacer.selectedIndex) {1373 default:1374 case 0:1375 this.childNodePlacer = new yfiles.tree.DefaultNodePlacer()1376 break1377 case 1:1378 this.childNodePlacer = new yfiles.tree.SimpleNodePlacer()1379 break1380 case 2:1381 this.childNodePlacer = new yfiles.tree.BusNodePlacer()1382 break1383 case 3:1384 this.childNodePlacer = new yfiles.tree.DoubleLineNodePlacer()1385 break1386 case 4:1387 this.childNodePlacer = new yfiles.tree.LeftRightNodePlacer()1388 break1389 case 5:1390 this.childNodePlacer = new yfiles.tree.AspectRatioNodePlacer()1391 break1392 }1393 panel.panelChanged()1394 })1395 }1396 getDefaultNodePlacer() {1397 return new yfiles.tree.AssistantNodePlacer()1398 }1399 }1400 class CompactNodePlacerConfiguration extends NodePlacerConfiguration {1401 /**1402 * Creates a new instance of AspectRatioNodePlacerConfiguration.1403 * @param {Element} panel1404 */1405 constructor(panel) {1406 super(1407 document.getElementById('compact-node-placer-settings'),1408 new yfiles.tree.CompactNodePlacer(),1409 panel1410 )1411 }1412 /** @type {number} */1413 get preferredAspectRatio() {1414 return this.$preferredAspectRatio1415 }1416 /** @type {number} */1417 set preferredAspectRatio(value) {1418 this.$preferredAspectRatio = value1419 }1420 /** @type {number} */1421 get verticalDistance() {1422 return this.$verticalDistance1423 }1424 /** @type {number} */1425 set verticalDistance(value) {1426 this.$verticalDistance = value1427 }1428 /** @type {number} */1429 get horizontalDistance() {1430 return this.$horizontalDistance1431 }1432 /** @type {number} */1433 set horizontalDistance(value) {1434 this.$horizontalDistance = value1435 }1436 /** @type {number} */1437 get minimumFirstSegmentLength() {1438 return this.$minimumFirstSegmentLength1439 }1440 /** @type {number} */1441 set minimumFirstSegmentLength(value) {1442 this.$minimumFirstSegmentLength = value1443 }1444 /** @type {number} */1445 get minimumLastSegmentLength() {1446 return this.$minimumLastSegmentLength1447 }1448 /** @type {number} */1449 set minimumLastSegmentLength(value) {1450 this.$minimumLastSegmentLength = value1451 }1452 createNodePlacer() {1453 const nodePlacer = new yfiles.tree.CompactNodePlacer()1454 nodePlacer.preferredAspectRatio = this.preferredAspectRatio1455 nodePlacer.verticalDistance = this.verticalDistance1456 nodePlacer.horizontalDistance = this.horizontalDistance1457 nodePlacer.minimumFirstSegmentLength = this.minimumFirstSegmentLength1458 nodePlacer.minimumLastSegmentLength = this.minimumLastSegmentLength1459 return nodePlacer1460 }1461 adoptSettings(nodePlacer) {1462 this.preferredAspectRatio = nodePlacer.preferredAspectRatio1463 this.verticalDistance = nodePlacer.verticalDistance1464 this.horizontalDistance = nodePlacer.horizontalDistance1465 this.minimumFirstSegmentLength = nodePlacer.minimumFirstSegmentLength1466 this.minimumLastSegmentLength = nodePlacer.minimumLastSegmentLength1467 }1468 getDescriptionText() {1469 return (1470 '<h2>CompactNodePlacer</h2>' +1471 'This node placer uses a dynamic optimization approach that chooses a placement strategy of the children ' +1472 'of the associated local root such that the overall result is compact with respect to a specified aspect ratio.'1473 )1474 }1475 updatePanel() {1476 const preferredAspectRatio = document.getElementById('compact-preferred-aspect-ratio')1477 preferredAspectRatio.value = this.preferredAspectRatio1478 const preferredAspectRatioLabel = document.getElementById(1479 'compact-preferred-aspect-ratio-label'1480 )1481 preferredAspectRatioLabel.innerHTML = this.preferredAspectRatio1482 const verticalDistance = document.getElementById('compact-vertical-distance')1483 verticalDistance.value = this.verticalDistance1484 const verticalDistanceLabel = document.getElementById('compact-vertical-distance-label')1485 verticalDistanceLabel.innerHTML = this.verticalDistance1486 const horizontalDistance = document.getElementById('compact-horizontal-distance')1487 horizontalDistance.value = this.horizontalDistance1488 const horizontalDistanceLabel = document.getElementById('compact-horizontal-distance-label')1489 horizontalDistanceLabel.innerHTML = this.horizontalDistance1490 const minimumFirstSegmentLength = document.getElementById(1491 'compact-minimum-first-segment-length'1492 )1493 minimumFirstSegmentLength.value = this.minimumFirstSegmentLength1494 const minimumFirstSegmentLengthLabel = document.getElementById(1495 'compact-minimum-first-segment-length-label'1496 )1497 minimumFirstSegmentLengthLabel.innerHTML = this.minimumFirstSegmentLength1498 const minimumLastSegmentLength = document.getElementById(1499 'compact-minimum-last-segment-length'1500 )1501 minimumLastSegmentLength.value = this.minimumLastSegmentLength1502 const minimumLastSegmentLengthLabel = document.getElementById(1503 'compact-minimum-last-segment-length-label'1504 )1505 minimumLastSegmentLengthLabel.innerHTML = this.minimumLastSegmentLength1506 }1507 bindActions(panel) {1508 const preferredAspectRatio = document.getElementById('compact-preferred-aspect-ratio')1509 preferredAspectRatio.addEventListener('change', () => {1510 this.preferredAspectRatio = Number.parseInt(preferredAspectRatio.value)1511 panel.panelChanged()1512 })1513 const preferredAspectRatioLabel = document.getElementById(1514 'compact-preferred-aspect-ratio-label'1515 )1516 preferredAspectRatio.addEventListener('input', () => {1517 preferredAspectRatioLabel.innerHTML = preferredAspectRatio.value1518 })1519 const verticalDistance = document.getElementById('compact-vertical-distance')1520 verticalDistance.addEventListener('change', () => {1521 this.verticalDistance = Number.parseInt(verticalDistance.value)1522 panel.panelChanged()1523 })1524 const verticalDistanceLabel = document.getElementById('compact-vertical-distance-label')1525 verticalDistance.addEventListener('input', () => {1526 verticalDistanceLabel.innerHTML = verticalDistance.value1527 })1528 const horizontalDistance = document.getElementById('compact-horizontal-distance')1529 horizontalDistance.addEventListener('change', () => {1530 this.horizontalDistance = Number.parseInt(horizontalDistance.value)1531 panel.panelChanged()1532 })1533 const horizontalDistanceLabel = document.getElementById('compact-horizontal-distance-label')1534 horizontalDistance.addEventListener('input', () => {1535 horizontalDistanceLabel.innerHTML = horizontalDistance.value1536 })1537 const minimumFirstSegmentLength = document.getElementById(1538 'compact-minimum-first-segment-length'1539 )1540 minimumFirstSegmentLength.addEventListener('change', () => {1541 this.minimumFirstSegmentLength = Number.parseInt(minimumFirstSegmentLength.value)1542 panel.panelChanged()1543 })1544 const minimumFirstSegmentLengthLabel = document.getElementById(1545 'compact-minimum-first-segment-length-label'1546 )1547 minimumFirstSegmentLength.addEventListener('input', () => {1548 minimumFirstSegmentLengthLabel.innerHTML = minimumFirstSegmentLength.value1549 })1550 const minimumLastSegmentLength = document.getElementById(1551 'compact-minimum-last-segment-length'1552 )1553 minimumLastSegmentLength.addEventListener('change', () => {1554 this.minimumLastSegmentLength = Number.parseInt(minimumLastSegmentLength.value)1555 panel.panelChanged()1556 })1557 const minimumLastSegmentLengthLabel = document.getElementById(1558 'compact-minimum-last-segment-length-label'1559 )1560 minimumLastSegmentLength.addEventListener('input', () => {1561 minimumLastSegmentLengthLabel.innerHTML = minimumLastSegmentLength.value1562 })1563 }1564 getDefaultNodePlacer() {1565 return new yfiles.tree.CompactNodePlacer()1566 }1567 }1568 return NodePlacerPanel...

Full Screen

Full Screen

TreeFeature.jsx

Source:TreeFeature.jsx Github

copy

Full Screen

1import {ConfInput, NumberInput} from '../../../ui/Input';2import React, { useCallback, useMemo } from 'react';3import { BlockStateProvider } from '../../state/BlockStateProvider';4import { Button } from '../../../ui/Button';5import {Heightmap} from "../Heightmap";6import { TREE_DECORATORS_OPTIONS } from './FeatureConfigDefaults';7import { UniformInt } from '../../utils/UniformInt';8import { useCrudPreset } from '../../../hooks/form';9import Select from '../../../ui/Select';10export function TreeFeature({configuration, onChange}) {11 const handleTrunkProviderChange = useCallback(function(trunk_provider) {12 onChange({ ...configuration, trunk_provider });13 }, [configuration, onChange]);14 const handleLeavesProviderChange = useCallback(function(leaves_provider) {15 onChange({ ...configuration, leaves_provider });16 }, [configuration, onChange]);17 const handleFoliagePlacerChange = useCallback(function(foliage_placer) {18 onChange({ ...configuration, foliage_placer });19 }, [configuration, onChange]);20 const handleTrunkPlacerChange = useCallback(function(trunk_placer) {21 onChange({ ...configuration, trunk_placer: { ...configuration.trunk_placer, ...trunk_placer } });22 }, [configuration, onChange]);23 const handleDecoratorsChange = useCallback(function(decorators) {24 onChange({ ...configuration, decorators });25 }, [configuration, onChange]);26 const handleConfigChange = useCallback(function(config) {27 onChange({ ...configuration, ...config });28 }, [configuration, onChange]);29 const handleIgnoreVinesChange = useCallback(function(e) {30 onChange({ ...configuration, ignore_vines: e.target.checked });31 }, [configuration, onChange]);32 const handleHeightmapChange = useCallback(function(option) {33 onChange({ ...configuration, heightmap: option.value });34 }, [configuration, onChange]);35 return <div>36 <p className="help text-muted">A tree necessarily needs <span title="Dirt, grass block, podzol, coarse dirt or mycelium">a soil block</span> or a farmland block underneath to be generated.</p>37 <fieldset>38 <legend>Trunk provider</legend>39 <BlockStateProvider block={configuration.trunk_provider} onChange={handleTrunkProviderChange} />40 </fieldset>41 <fieldset>42 <legend>Leaves provider</legend>43 <BlockStateProvider block={configuration.leaves_provider} onChange={handleLeavesProviderChange} />44 </fieldset>45 <FoliagePlacer placer={configuration.foliage_placer} onChange={handleFoliagePlacerChange} />46 <TrunkPlacer placer={configuration.trunk_placer} onChange={handleTrunkPlacerChange} />47 <TreeDecorators data={configuration.decorators} onChange={handleDecoratorsChange}></TreeDecorators>48 <fieldset>49 <legend>Config</legend>50 <Heightmap heightmap={configuration.heightmap} onChange={handleHeightmapChange} />51 <div className="form-group form-row">52 <ConfInput id="ignore_vines" checked={configuration.ignore_vines || false} onChange={handleIgnoreVinesChange}>Ignore vines</ConfInput>53 <NumberInput id="max_water_depth" value={configuration.max_water_depth} required={false} upChange={handleConfigChange}>Max water depth</NumberInput>54 </div>55 </fieldset>56 </div>;57}58const FoliagePlacer = React.memo(function({placer, onChange}) {59 const options = useMemo(function() {60 return [61 { value: 'acacia_foliage_placer', label: 'Acacia foliage placer' },62 { value: 'blob_foliage_placer', label: 'Blob foliage placer' },63 { value: 'bush_foliage_placer', label: 'Bush foliage placer' },64 { value: 'dark_oak_foliage_placer', label: 'Dark oak foliage placer' },65 { value: 'fancy_foliage_placer', label: 'Fancy foliage placer' },66 { value: 'jungle_foliage_placer', label: 'Jungle foliage placer' },67 { value: 'mega_pine_foliage_placer', label: 'Mega pine foliage placer' },68 { value: 'pine_foliage_placer', label: 'Pine foliage placer' },69 { value: 'spruce_foliage_placer', label: 'Spruce foliage placer' }70 ].map(o => {71 o.value = 'minecraft:' + o.value;72 return o;73 });74 }, []);75 const handleTypeChange = useCallback(function(option) {76 const type = option.value;77 if (type === 'minecraft:acacia_foliage_placer' || type === 'minecraft:mega_pine_foliage_placer') {78 delete placer.height;79 } else if (type !== 'minecraft:acacia_foliage_placer') {80 delete placer.crown_height;81 }82 onChange({ ...placer, type });83 }, [onChange, placer]);84 const handleChange = useCallback(function(value) {85 onChange({ ...placer, ...value })86 }, [onChange, placer]);87 const selected = useMemo(function() {88 return options.find(o => o.value === placer.type) || options[0];89 }, [options, placer.type]);90 return <fieldset>91 <legend>Foliage placer</legend>92 <div className="form-group">93 <label htmlFor="foliage_placer_type">Type</label>94 <Select options={options} name="foliage_placer_type" value={selected} onChange={handleTypeChange} />95 </div>96 <div className="form-group form-row">97 <UniformInt id="radius" value={placer.radius} maxBase={8} maxSpread={8} upChange={handleChange}>Radius</UniformInt>98 <UniformInt id="offset" value={placer.offset} maxBase={8} maxSpread={8} upChange={handleChange}>Offset</UniformInt>99 {(placer.type === 'minecraft:blob_foliage_placer' ||100 placer.type === 'minecraft:bush_foliage_placer' ||101 placer.type === 'minecraft:fancy_foliage_placer' ||102 placer.type === 'minecraft:jungle_foliage_placer'103 ) && <NumberInput id="height" value={placer.height} upChange={handleChange} max={16} defaultValue={3}>Height</NumberInput>}104 105 {placer.type === 'minecraft:mega_pine_foliage_placer' && <UniformInt id="crown_height" value={placer.crown_height} maxBase={16} maxSpread={8} upChange={handleChange}>Crown height</UniformInt>}106 {placer.type === 'minecraft:pine_foliage_placer' && <UniformInt id="height" value={placer.height} maxBase={16} maxSpread={8} upChange={handleChange}>Height</UniformInt>}107 {placer.type === 'minecraft:spruce_foliage_placer' && <UniformInt id="trunk_height" value={placer.trunk_height} maxBase={16} maxSpread={8} upChange={handleChange}>Trunk height</UniformInt>}108 </div>109 </fieldset>110});111const TrunkPlacer = React.memo(function({placer, onChange}) {112 const options = useMemo(function() {113 return [114 { value: 'straight_trunk_placer', label: 'Straight trunk placer' },115 { value: 'forking_trunk_placer', label: 'Forking trunk placer' },116 { value: 'giant_trunk_placer', label: 'Giant trunk placer' },117 { value: 'mega_jungle_trunk_placer', label: 'Mega jungle trunk placer' },118 { value: 'dark_oak_trunk_placer', label: 'Dark oak trunk placer' },119 { value: 'fancy_trunk_placer', label: 'Fancy trunk placer' }120 ].map(o => {121 o.value = 'minecraft:' + o.value;122 return o;123 });124 }, []);125 const handleTypeChange = useCallback(function(option) {126 onChange({ type: option.value });127 }, [onChange]);128 const selected = useMemo(function() {129 return options.find(o => o.value === placer.type) || options[0];130 }, [placer.type, options]);131 return <fieldset>132 <legend>Trunk placer</legend>133 <div className="form-group">134 <label htmlFor="foliage_placer_type">Type</label>135 <Select options={options} name="foliage_placer_type" defaultValue={selected} onChange={handleTypeChange} />136 </div>137 <div className="form-group form-row">138 <NumberInput id="base_height" value={placer.base_height} upChange={onChange} max="32">Base height</NumberInput>139 <NumberInput id="height_rand_a" value={placer.height_rand_a} upChange={onChange} max="24">First height rand</NumberInput>140 <NumberInput id="height_rand_b" value={placer.height_rand_b} upChange={onChange} max="24">Second height rand</NumberInput>141 </div>142 </fieldset>143});144const TreeDecorators = React.memo(function({data, onChange}) {145 const [decorators, handleAdd, handleChange, handleRemove] = useCrudPreset(onChange, data, function(decorators) {146 // Get the first non taken decorator147 return { type: (TREE_DECORATORS_OPTIONS.filter(o => !decorators.some(d => d.type === o.value))[0] || { value: 'minecraft:alter_ground' }).value };148 });149 150 return <fieldset>151 <legend>Tree decorators {decorators.length < 5 && <Button onClick={handleAdd}>Add decorator</Button>}</legend>152 {decorators.map((decorator, i) => {153 const options = TREE_DECORATORS_OPTIONS.filter(o => o.value === decorator.type || !decorators.some(d => d.type === o.value));154 return <TreeDecorator data={decorator} key={decorator.type} onChange={handleChange} options={options}>155 <Button cat="danger mlm" onClick={e => handleRemove(e, i)}>Remove</Button>156 </TreeDecorator>157 })}158 </fieldset>159});160const TreeDecorator = React.memo(function({children, data, options, onChange}) {161 const handleSelectChange = useCallback(function(option) {162 onChange({ type: option.value, ...option.default }, data);163 }, [data, onChange]);164 const handleAlterGroundChange = useCallback(function(provider) {165 onChange({ type: data.type, provider }, data);166 }, [data, onChange]);167 const handleProbabilityChange = useCallback(function(probability) {168 onChange({ type: data.type, probability }, data);169 }, [data, onChange]);170 const CustomTag = ['minecraft:leave_vine', 'minecraft:trunk_vine'].indexOf(data.type) < 0 ? 'fieldset' : 'div';171 const selected = useMemo(function() {172 return options.find(o => o.value === data.type);173 }, [data.type, options]);174 return <CustomTag>175 <legend style={{ fontWeight: 'normal', fontSize: 'inherit' }}>176 <div style={{ width: '200px', display: 'inline-block' }}><Select options={options} value={selected} onChange={handleSelectChange} /></div>177 {children}178 </legend>179 <div className="form-group">180 {data.type === 'minecraft:alter_ground' && <BlockStateProvider block={data.provider} onChange={handleAlterGroundChange} />}181 {(data.type === 'minecraft:beehive' || data.type === 'minecraft:cocoa') && <NumberInput id="probability" value={data.probability} onChange={handleProbabilityChange} max="1" step="0.05" defaultValue="0.05">Probability</NumberInput>}182 </div>183 </CustomTag>...

Full Screen

Full Screen

imageViewer.js

Source:imageViewer.js Github

copy

Full Screen

1var dragTarget = null;2var dragXStart = 0;3var dragYStart = 0;4var zoomLevels = new Map();5var positions = new Map();6const baseWidth = 600;7function initImageViewers(numImages) {8 var containers = document.getElementsByClassName("image-container");9 [].forEach.call(containers, function (e) {10 var wheelOpt = false;11 try {12 window.addEventListener("test", null, Object.defineProperty({}, 'passive', {13 get: function () { wheelOpt = { passive: false }; }14 }));15 } catch (exc) { }16 e.addEventListener("keypress", onKeyDownImage);17 e.addEventListener("mousemove", onMouseMove);18 e.addEventListener("mouseout", onMouseOut);19 e.addEventListener("wheel", onScrollContainer, wheelOpt);20 var placer = e.getElementsByClassName("image-placer")[0];21 placer.addEventListener("wheel", onScrollImage, wheelOpt);22 // Set the initial size of the image23 var img = placer.getElementsByTagName("img")[0];24 placer.style.top = "0px";25 placer.style.left = "0px";26 placer.style.height = ((img.naturalHeight / img.naturalWidth) * baseWidth).toString() + "px";27 placer.style.width = baseWidth.toString() + "px";28 // Add logic to the buttons29 var labels = document.getElementsByClassName("method-label");30 for (i = 0; i < labels.length; ++i) {31 for (idx = 1; idx <= numImages; ++idx) {32 if (labels[i].classList.contains("method-" + idx.toString())) {33 let container = labels[i].parentElement.parentElement.getElementsByClassName("image-container")[0];34 let thisIndex = idx;35 labels[i].addEventListener("click", function () { flipImage(container, thisIndex); })36 }37 }38 }39 zoomLevels.set(e, 1.0);40 positions.set(e, [0, 0]);41 });42}43function flipImage(container, index) {44 // Only proceed if the number is mapped to an existing image45 var selected = container.getElementsByClassName("image-" + index.toString());46 if (selected.length == 0) return;47 // Hide the currently visible elements48 var visible = container.parentElement.getElementsByClassName("visible");49 // We iterate in reverse order, because removing the class also removes the element from the list50 for (i = visible.length - 1; i >= 0; --i)51 visible[i].classList.remove("visible");52 // Show the image and its label53 selected[0].classList.add("visible");54 container.parentElement.getElementsByClassName("method-" + index.toString())[0].classList.add("visible");55}56function onKeyDownImage(event) {57 flipImage(event.currentTarget, event.key)58}59function shiftImage(container, deltaX, deltaY) {60 positions.get(container)[0] += deltaX;61 positions.get(container)[1] += deltaY;62 var placer = container.getElementsByClassName("image-placer")[0];63 placer.style.top = positions.get(container)[1].toString() + "px";64 placer.style.left = positions.get(container)[0].toString() + "px";65}66function scaleImage(container, scale) {67 zoomLevels.set(container, scale);68 var placer = container.getElementsByClassName("image-placer")[0];69 var aspect = placer.getElementsByTagName("img")[0].naturalHeight / placer.getElementsByTagName("img")[0].naturalWidth;70 placer.style.width = (baseWidth * scale).toString() + "px";71 placer.style.height = (baseWidth * aspect * scale).toString() + "px";72}73function onMouseOut(event) {74 dragTarget = null;75}76function onMouseMove(event) {77 // Only consider if the left mouse button is pressed78 if ((event.buttons & 1) == 0) {79 dragTarget = null;80 return;81 }82 // Remember the initial position where the drag started83 if (dragTarget === null) {84 dragXStart = event.screenX;85 dragYStart = event.screenY;86 dragTarget = event.currentTarget;87 return;88 }89 // Compute the change in position since the last event90 var deltaX = event.screenX - dragXStart;91 var deltaY = event.screenY - dragYStart;92 dragXStart = event.screenX;93 dragYStart = event.screenY;94 // Update the position of the image95 shiftImage(dragTarget, deltaX, deltaY)96}97function computeZoomScale(container, evt, left, top) {98 const ScrollSpeed = 0.25;99 const MaxScale = 1000;100 const MinScale = 0.05;101 var direction = evt.wheelDeltaY < 0 ? 1 : -1;102 var factor = 1.0 - direction * ScrollSpeed;103 var scale = zoomLevels.get(container);104 if (scale * factor > MaxScale) {105 return;106 }107 else if (scale * factor < MinScale) {108 return;109 }110 scale *= factor;111 // Adjust the position of the top left corner, so we get a scale pivot at the mouse cursor.112 var relX = evt.offsetX - left;113 var relY = evt.offsetY - top;114 var deltaX = (1 - factor) * relX;115 var deltaY = (1 - factor) * relY;116 shiftImage(container, deltaX, deltaY);117 scaleImage(container, scale);118}119function onScrollContainer(evt) {120 if (evt.altKey) return; // holding alt allows to scroll over the image121 var left = positions.get(evt.currentTarget)[0];122 var top = positions.get(evt.currentTarget)[1];123 computeZoomScale(evt.currentTarget, evt, left, top);124 evt.preventDefault();125}126function onScrollImage(evt) {127 if (evt.altKey) return; // holding alt allows to scroll over the image128 computeZoomScale(evt.currentTarget.parentElement, evt, 0, 0);129 evt.stopPropagation();130 evt.preventDefault();...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1var placer = require('stryker-parent').placer;2var placer = require('stryker-child').placer;3var placer = require('stryker-parent').placer;4var placer = require('stryker-child').placer;5var placer = require('stryker-parent').placer;6var placer = require('stryker-child').placer;7var placer = require('stryker-parent').placer;8var placer = require('stryker-child').placer;9var placer = require('stryker-parent').placer;10var placer = require('stryker-child').placer;11var placer = require('stryker-parent').placer;12var placer = require('stryker-child').placer;13var placer = require('stryker-parent').placer;14var placer = require('stryker-child').placer;15var placer = require('stryker-parent').placer;16var placer = require('stryker-child').placer;17var placer = require('stryker-parent').placer;18var placer = require('stryker-child').placer;19var placer = require('stryker-parent').placer;20var placer = require('stryker-child').placer;21var placer = require('stryker-parent').placer;22var placer = require('stryker-child').placer;

Full Screen

Using AI Code Generation

copy

Full Screen

1var placer = require('stryker-parent').placer;2console.log(placer('test'));3var placer2 = require('stryker-parent2').placer;4console.log(placer2('test'));5var placer = require('stryker-parent').placer;6console.log(placer('test'));7var placer2 = require('stryker-parent2').placer;8console.log(placer2('test'));9var placer = require('stryker-parent').placer;10console.log(placer('test'));11var placer2 = require('stryker-parent2').placer;12console.log(placer2('test'));13var placer = require('stryker-parent').placer;14console.log(placer('test'));15var placer2 = require('stryker-parent2').placer;16console.log(placer2('test'));17var placer = require('stryker-parent').placer;18console.log(placer('test'));19var placer2 = require('stryker-parent2').placer;20console.log(placer2('test'));21var placer = require('stryker-parent').placer;22console.log(placer('test'));23var placer2 = require('stryker-parent2').placer;24console.log(placer2('test'));25var placer = require('stryker-parent').placer;26console.log(placer('test'));27var placer2 = require('stryker-parent2').placer;28console.log(placer2('test'));

Full Screen

Using AI Code Generation

copy

Full Screen

1var placer = require('stryker-parent').placer;2placer.place('test.js', 'test.js');3var placer = require('stryker-parent').placer;4placer.place('test.js', 'test.js');5var placer = require('stryker-parent').placer;6placer.place('test.js', 'test.js');7var placer = require('stryker-parent').placer;8placer.place('test.js', 'test.js');9var placer = require('stryker-parent').placer;10placer.place('test.js', 'test.js');11var placer = require('stryker-parent').placer;12placer.place('test.js', 'test.js');13var placer = require('stryker-parent').placer;14placer.place('test.js', 'test.js');15var placer = require('stryker-parent').placer;16placer.place('test.js', 'test.js');17var placer = require('stryker-parent').placer;18placer.place('test.js', 'test.js');19var placer = require('stryker-parent').placer;20placer.place('test.js', 'test.js');21var placer = require('stryker-parent').placer;22placer.place('test.js', 'test.js');23var placer = require('stryker-parent').placer;24placer.place('test.js', 'test.js');25var placer = require('stryker-parent').placer;26placer.place('test.js', 'test.js');27var placer = require('stryker-parent').placer;28placer.place('test.js', 'test.js');

Full Screen

Using AI Code Generation

copy

Full Screen

1const { Stryker } = require('@stryker-mutator/core');2const { mutatorDescriptor } = require('@stryker-mutator/core/src/di');3const config = {4 mutator: mutatorDescriptor('javascript'),5 jest: {6 config: require('./jest.config')7 }8};9const stryker = new Stryker(config);10stryker.runMutationTest().then(() => {11 console.log('Done!');12}).catch(error => {13 console.error(error);14 process.exit(1);15});

Full Screen

Using AI Code Generation

copy

Full Screen

1var placer = require('stryker-parent').placer;2placer.place('test.js', 'test.json');3placer.place('test.js', 'test.json', 'test2.json');4{5}6{7}8console.log(require('./test.json').name);9console.log(require('./test2.json').name);10var placer = require('stryker-parent').placer;11placer.place('test.js', 'test.json');12placer.place('test.js', 'test.json', 'test2.json');13{14}15{16}17console.log(require('./test.json').name);18console.log(require('./test2.json').name);19var placer = require('stryker-parent').placer;20placer.place('test.js', 'test.json');21placer.place('test.js', 'test.json', 'test2.json');22{23}24{25}26console.log(require('./test.json').name);27console.log(require('./test2.json').name);28var placer = require('stryker-parent').placer;29placer.place('test.js', 'test.json');30placer.place('test.js', 'test.json', 'test2.json');31{32}33{34}35console.log(require('./test.json').name);36console.log(require('./test2.json').name);37var placer = require('stryker-parent').placer;38placer.place('test.js', '

Full Screen

Using AI Code Generation

copy

Full Screen

1var placer = require('stryker-parent').placer;2placer.place('test/resources/test.js', 'test/resources/test2.js', 'test/resources/test2.js', function(err) {3 if (err) {4 console.log('Error placing file');5 } else {6 console.log('File placed successfully');7 }8});9var placer = require('stryker-parent').placer;10placer.place('test/resources/test.js', 'test/resources/test2.js', 'test/resources/test2.js', function(err) {11 if (err) {12 console.log('Error placing file');13 } else {14 console.log('File placed successfully');15 }16});17var placer = require('stryker-parent').placer;18placer.place('test/resources/test.js', 'test/resources/test2.js', 'test/resources/test2.js', function(err) {19 if (err) {20 console.log('Error placing file');21 } else {22 console.log('File placed successfully');23 }24});25var placer = require('stryker-parent').placer;26placer.place('test/resources/test.js', 'test/resources/test2.js', 'test/resources/test2.js', function(err) {27 if (err) {28 console.log('Error placing file');29 } else {30 console.log('File placed successfully');31 }32});33var placer = require('stryker-parent').placer;34placer.place('test/resources/test.js', 'test/resources/test2.js', 'test/resources/test2.js', function(err) {35 if (err) {36 console.log('Error placing file');37 } else {38 console.log('File placed successfully');39 }40});41var placer = require('stryker-parent').placer;42placer.place('test/resources/test.js', 'test/resources/test2.js', 'test/resources/test2.js', function(err) {43 if (err) {44 console.log('Error placing file');45 } else {46 console.log('File placed successfully');47 }48});

Full Screen

Using AI Code Generation

copy

Full Screen

1var placer = require('stryker-parent').placer;2var child = require('child_process');3var ls = child.spawn('node', [placer('test.js')]);4ls.stdout.on('data', function (data) {5 console.log('stdout: ' + data);6});7ls.stderr.on('data', function (data) {8 console.log('stderr: ' + data);9});10ls.on('close', function (code) {11 console.log('child process exited with code ' + code);12});13var ls = child.spawn('node', [placer('test.js')]);14ls.stdout.on('data', function (data) {15 console.log('stdout: ' + data);16});17ls.stderr.on('data', function (data) {18 console.log('stderr: ' + data);19});20ls.on('close', function (code) {21 console.log('child process exited with code ' + code);22});23var ls = child.spawn('node', [placer('test.js')]);24ls.stdout.on('data', function (data) {25 console.log('stdout: ' + data);26});27ls.stderr.on('data', function (data) {28 console.log('stderr: ' + data);29});30ls.on('close', function (code) {31 console.log('child process exited with code ' + code);32});33var ls = child.spawn('node', [placer('test.js')]);34ls.stdout.on('data', function (data) {35 console.log('stdout: ' + data);36});37ls.stderr.on('data', function (data) {38 console.log('stderr: ' + data);39});40ls.on('close', function (code) {41 console.log('child process exited with code ' + code);42});43var ls = child.spawn('node', [placer('test.js')]);44ls.stdout.on('data', function (data) {45 console.log('stdout: ' + data);46});47ls.stderr.on('data', function (data) {48 console.log('stderr: ' + data);49});50ls.on('close', function (code) {51 console.log('child process exited with code ' + code);52});53var ls = child.spawn('node

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run stryker-parent automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful