Projekt

Obecné

Profil

« Předchozí | Další » 

Revize e93dcfbc

Přidáno uživatelem Pavel Fidranský před více než 6 roky(ů)

Vertex related archetypes highlighting, refactoring of the whole highlighting functionality

Zobrazit rozdíly:

sources/src/main/webapp/css/main.css
325 325
	fill: #5896FF;
326 326
}
327 327

  
328
.viewport .node--highlighted-archetype > rect {
329
	fill: yellowgreen;
330
}
331

  
328 332
.viewport .node--highlighted-required.node--highlighted-provided > rect {
329 333
	fill: url(#node--highlighted-required-provided);
330 334
}
......
337 341
	dominant-baseline: central;
338 342
}
339 343

  
344
.viewport .vertex .related-archetype {
345
	dominant-baseline: central;
346
}
347

  
340 348
.context-menu {
341 349
	position: absolute;
342 350
	font-family: 'Arial', sans-serif;
sources/src/main/webapp/js/components/group.js
25 25
	var excluded = false;
26 26

  
27 27
	var highlighted = false;
28
	var highlightedRequired = false;
29
	var highlightedProvided = false;
30 28
	var highlightedRequiredNeighbours = false;
31 29
	var highlightedProvidedNeighbours = false;
30
	var highlightedArchetypeNeighbours = false;
32 31
	var found = false;
33 32
	var dimmed = false;
34 33

  
......
255 254
		}
256 255
	};
257 256

  
257
	/**
258
	 * Toggles inner state of the group marking whether highlighting of its requirements is active.
259
	 * @param {boolean} newValue True to highlight the neighbours, false to unhighlight.
260
	 */
261
	this.setHighlightedRequiredNeighbours = function(newValue) {
262
		highlightedRequiredNeighbours = newValue;
263
	};
264

  
265
	/**
266
	 * Toggles inner state of the group marking whether highlighting of its dependents is active.
267
	 * @param {boolean} newValue True to highlight the neighbours, false to unhighlight.
268
	 */
269
	this.setHighlightedProvidedNeighbours = function(newValue) {
270
		highlightedProvidedNeighbours = newValue;
271
	};
272

  
273
	/**
274
	 * Toggles inner state of the group marking whether highlighting of instances of a vertex archetype is active.
275
	 * @param {boolean} newValue True to highlight the neighbours, false to unhighlight.
276
	 */
277
	this.setHighlightedArchetypeNeighbours = function(newValue) {
278
		highlightedArchetypeNeighbours = newValue;
279
	};
280

  
258 281
	/**
259 282
	 * Toggles highlighting of the group to mark it as requirement of some other node.
260 283
	 * @param {boolean} newValue True to highlight, false to unhighlight.
261 284
	 */
262 285
	this.setHighlightedRequired = function(newValue) {
263
		highlightedRequired = newValue;
264

  
265 286
		if (newValue) {
266 287
			rootElement.classList.add('node--highlighted-required');
267 288
		} else {
......
274 295
	 * @param {boolean} newValue True to highlight, false to unhighlight.
275 296
	 */
276 297
	this.setHighlightedProvided = function(newValue) {
277
		highlightedProvided = newValue;
278

  
279 298
		if (newValue) {
280 299
			rootElement.classList.add('node--highlighted-provided');
281 300
		} else {
......
284 303
	};
285 304
	
286 305
	/**
287
	 * Toggles highlighting of the group when only its requirements should be highlighted. Anytime this value is changed, generic 
288
	 * {@link Group#setHighlighted} method should be called too.
289
	 * @param {boolean} newValue True to highlight the group when only its requirements should be highlighted, false to unhighlight.
290
	 */
291
	this.setHighlightedRequiredNeighbours = function(newValue) {
292
		highlightedRequiredNeighbours = newValue;
293

  
294
		if (newValue) {
295
			rootElement.classList.add('node--highlighted-required-neighbours');
296
		} else {
297
			rootElement.classList.remove('node--highlighted-required-neighbours');
298
		}
299
	};
300
	
301
	/**
302
	 * Toggles highlighting of the group when only its dependents should be highlighted. Anytime this value is changed, generic 
303
	 * {@link Group#setHighlighted} method should be called too.
304
	 * @param {boolean} newValue True to highlight the group when only its dependents should be highlighted, false to unhighlight.
306
	 * Toggles highlighting of the group to mark it as instance of archetype related to some other node.
307
	 * @param {boolean} newValue True to highlight, false to unhighlight.
305 308
	 */
306
	this.setHighlightedProvidedNeighbours = function(newValue) {
307
		highlightedProvidedNeighbours = newValue;
308

  
309
	this.setHighlightedArchetype = function(newValue) {
309 310
		if (newValue) {
310
			rootElement.classList.add('node--highlighted-provided-neighbours');
311
			rootElement.classList.add('node--highlighted-archetype');
311 312
		} else {
312
			rootElement.classList.remove('node--highlighted-provided-neighbours');
313
			rootElement.classList.remove('node--highlighted-archetype');
313 314
		}
314 315
	};
315 316

  
......
393 394
		rootElement = excluded ? renderExcluded.call(this) : renderIncluded.call(this);
394 395

  
395 396
		this.setHighlighted(highlighted);
396
		this.setHighlightedRequiredNeighbours(highlightedRequiredNeighbours);
397
		this.setHighlightedProvidedNeighbours(highlightedProvidedNeighbours);
398 397

  
399 398
		return rootElement;
400 399
	};
......
716 715
			this.setHighlightedRequiredNeighbours(highlighted);
717 716
			this.setHighlightedProvidedNeighbours(highlighted);
718 717

  
719
			highlightNeighbours.call(this);
718
			prepareHighlighting.call(this);
719
			highlightRequiredNeighbours.call(this);
720
			highlightProvidedNeighbours.call(this);
720 721
			return;
721 722
		}
722 723

  
......
730 731
				this.setHighlighted(!highlighted);
731 732
				this.setHighlightedRequiredNeighbours(highlighted);
732 733
				this.setHighlightedProvidedNeighbours(highlighted);
733

  
734
				highlightNeighbours.call(this);
734
	
735
				prepareHighlighting.call(this);
736
				highlightRequiredNeighbours.call(this);
737
				highlightProvidedNeighbours.call(this);
735 738
				break;
736 739

  
737 740
			case 'exclude':
......
851 854
	}
852 855
	
853 856
	/**
854
	 * Highlights all neighbours of vertices in the group. They are either highlighted as required or provided, or dimmed.
857
	 * Prepares highlighting of all graph components so that only the wished ones need to be modified.
855 858
	 */
856
	function highlightNeighbours() {
859
	function prepareHighlighting() {
857 860
		this.setDimmed(false);
861

  
858 862
		this.setHighlightedRequired(false);
859 863
		this.setHighlightedProvided(false);
864
		this.setHighlightedArchetype(false);
860 865

  
861 866
		if (highlighted) {
862 867
			// dim and unhighlight all nodes but this
......
868 873
				node.setHighlighted(false);
869 874
				node.setHighlightedRequired(false);
870 875
				node.setHighlightedProvided(false);
871
				node.setHighlightedRequiredNeighbours(false);
872
				node.setHighlightedProvidedNeighbours(false);
876
				node.setHighlightedArchetype(false);
873 877
			}, this);
874 878

  
875 879
			// dim and unhighlight all edges
876 880
			app.edgeList.forEach(function(edge) {
877
				edge.setHidden(edge.getFrom().isExcluded() || edge.getTo().isExcluded());
878 881
				edge.setDimmed(true);
879 882

  
880 883
				edge.setHighlighted(false);
......
882 885
				edge.setHighlightedProvided(false);
883 886
			});
884 887

  
885
			// highlight required neighbours
886
			this.getInEdgeList().forEach(function(edge) {
887
				edge.setHidden(false);
888
				edge.setDimmed(false);
889
				edge.setHighlightedRequired(true);
890

  
891
				edge.getFrom().setDimmed(false);
892
				edge.getFrom().setHighlightedRequired(true);
893
			});
894
			
895
			// highlight provided neighbours
896
			this.getOutEdgeList().forEach(function(edge) {
897
				edge.setHidden(false);
898
				edge.setDimmed(false);
899
				edge.setHighlightedProvided(true);
900

  
901
				edge.getTo().setDimmed(false);
902
				edge.getTo().setHighlightedProvided(true);
903
			});
904

  
905 888
		} else {
906 889
			app.nodeList.forEach(function(node) {
890
				if (node === this) return;
891

  
907 892
				node.setDimmed(false);
908 893

  
909 894
				node.setHighlighted(false);
910 895
				node.setHighlightedRequired(false);
911 896
				node.setHighlightedProvided(false);
912
				node.setHighlightedRequiredNeighbours(false);
913
				node.setHighlightedProvidedNeighbours(false);
897
				node.setHighlightedArchetype(false);
914 898
			}, this);
915 899

  
916 900
			app.edgeList.forEach(function(edge) {
917 901
				edge.setHidden(edge.getFrom().isExcluded() || edge.getTo().isExcluded());
902

  
918 903
				edge.setDimmed(false);
919 904

  
920 905
				edge.setHighlighted(false);
......
928 913
	 * Highlights only neighbours of vertices in the group that are required.
929 914
	 */
930 915
	function highlightRequiredNeighbours() {
931
		if (highlighted) {
932
			this.getInEdgeList().forEach(function(edge) {
933
				edge.setHidden(false);
934
				edge.setHighlightedRequired(true);
935
				edge.getFrom().setHighlightedRequired(true);
936
			});
916
		if (highlightedRequiredNeighbours === false) return;
937 917

  
938
		} else {
939
			this.getInEdgeList().forEach(function(edge) {
940
				edge.setHidden(true);
941
				edge.setHighlightedRequired(false);
942
				edge.getFrom().setHighlightedRequired(false);
943
			});
944
		}
918
		this.getInEdgeList().forEach(function(edge) {
919
			edge.setHidden(false);
920

  
921
			edge.getFrom().setDimmed(false);
922
			edge.setDimmed(false);
923

  
924
			edge.setHighlightedRequired(true);
925
			edge.getFrom().setHighlightedRequired(true);
926
		});
945 927
	}
946 928

  
947 929
	/**
948 930
	 * Highlights only neighbours of vertices in the group that are provided.
949 931
	 */
950 932
	function highlightProvidedNeighbours() {
951
		if (highlighted) {
952
			this.getOutEdgeList().forEach(function(edge) {
953
				edge.setHidden(false);
954
				edge.setHighlightedProvided(true);
955
				edge.getTo().setHighlightedProvided(true);
956
			});
933
		if (highlightedProvidedNeighbours === false) return;
957 934

  
958
		} else {
959
			this.getOutEdgeList().forEach(function(edge) {
960
				edge.setHidden(true);
961
				edge.setHighlightedProvided(false);
962
				edge.getTo().setHighlightedProvided(false);
963
			});
964
		}
935
		this.getOutEdgeList().forEach(function(edge) {
936
			edge.setHidden(false);
937

  
938
			edge.setDimmed(false);
939
			edge.getTo().setDimmed(false);
940

  
941
			edge.setHighlightedProvided(true);
942
			edge.getTo().setHighlightedProvided(true);
943
		});
944
	}
945

  
946
	/**
947
	 * Highlights only neighbours of the group that are instances of the archetype.
948
	 * @param {integer} archetypeIndex Index of the vertex archetype.
949
	 */
950
	function highlightArchetypeNeighbours(archetypeIndex) {
951
		if (highlightedArchetypeNeighbours === false) return;
965 952
	}
966 953
}
sources/src/main/webapp/js/components/vertex.js
15 15

  
16 16
	const oneCharacterWidth = 8.3;	// approximate width (in pixels) of one character using Consolas at 15px font size
17 17
	const minimumWidth = 200;
18
	const relatedArchetypeIconWidth = 20;
18 19

  
19 20
	var rootElement;
20 21
	var symbolListComponent;
......
32 33
	var iconsDisplayed = false;
33 34

  
34 35
	var highlighted = false;
35
	var highlightedRequired = false;
36
	var highlightedProvided = false;
37 36
	var highlightedRequiredNeighbours = false;
38 37
	var highlightedProvidedNeighbours = false;
38
	var highlightedArchetypeNeighbours = false;
39 39
	var found = false;
40 40
	var dimmed = false;
41 41

  
42 42
	var inEdgeList = [];
43 43
	var outEdgeList = [];
44 44
	var symbolList = [];
45
	var relatedArchetypeMap = {};
45 46
	
46 47
	/**
47 48
	 * Adds a new edge ending in the vertex. Its ending point is moved to the current position of the vertex.
......
86 87
	};
87 88

  
88 89
	/**
89
	 * 
90
	 * @param {array} symbol Node symbol to be displayed next to the vertex.
90
	 * @returns {integer} Number of incoming/outgoing edges.
91
	 */
92
	this.countEdges = function() {
93
		return inEdgeList.length + outEdgeList.length;
94
	};
95

  
96
	/**
97
	 * Increments counter of instances of a vertex archetype by one.
98
	 * @param {integer} archetypeIndex Index of the vertex archetype.
99
	 */
100
	this.incrementRelatedArchetype = function(archetypeIndex) {
101
		if (!relatedArchetypeMap.hasOwnProperty(archetypeIndex)) {
102
			relatedArchetypeMap[archetypeIndex] = 0;
103
		}
104

  
105
		relatedArchetypeMap[archetypeIndex]++;
106
	};
107

  
108
	/**
109
	 * @returns {object} Map with archetype indexes as keys and counters of their instances as values.
110
	 */
111
	this.getRelatedArchetypeMap = function() {
112
		return relatedArchetypeMap;
113
	};
114

  
115
	/**
116
	 * @returns {integer} Number of unique vertex archetypes related to the vertex.
117
	 */
118
	this.countRelatedArchetypes = function() {
119
		return Object.keys(relatedArchetypeMap).length;
120
	};
121

  
122
	/**
123
	 * Adds symbol to the list of symbols displayed next to the vertex.
124
	 * @param {array} symbol Node symbol to be added.
91 125
	 */
92 126
	this.addSymbol = function(symbol) {
93 127
		symbolList.push(symbol);
......
108 142

  
109 143
		symbolListComponent.removeChild(symbol);
110 144
	};
111

  
112
	this.countEdges = function() {
113
		return inEdgeList.length + outEdgeList.length;
114
	};
115 145
	
116 146
	/**
117 147
	 * @returns {Coordinates} Current position of the vertex.
......
240 270
		}
241 271
	};
242 272

  
273
	/**
274
	 * Toggles inner state of the vertex marking whether highlighting of its requirements is active.
275
	 * @param {boolean} newValue True to highlight the neighbours, false to unhighlight.
276
	 */
277
	this.setHighlightedRequiredNeighbours = function(newValue) {
278
		highlightedRequiredNeighbours = newValue;
279
	};
280

  
281
	/**
282
	 * Toggles inner state of the vertex marking whether highlighting of its dependents is active.
283
	 * @param {boolean} newValue True to highlight the neighbours, false to unhighlight.
284
	 */
285
	this.setHighlightedProvidedNeighbours = function(newValue) {
286
		highlightedProvidedNeighbours = newValue;
287
	};
288

  
289
	/**
290
	 * Toggles inner state of the vertex marking whether highlighting of instances of a vertex archetype is active.
291
	 * @param {boolean} newValue True to highlight the neighbours, false to unhighlight.
292
	 */
293
	this.setHighlightedArchetypeNeighbours = function(newValue) {
294
		highlightedArchetypeNeighbours = newValue;
295
	};
296

  
243 297
	/**
244 298
	 * Toggles highlighting of the vertex to mark it as requirement of some other node.
245 299
	 * @param {boolean} newValue True to highlight, false to unhighlight.
246 300
	 */
247 301
	this.setHighlightedRequired = function(newValue) {
248
		highlightedRequired = newValue;
249

  
250 302
		if (newValue) {
251 303
			rootElement.classList.add('node--highlighted-required');
252 304
		} else {
......
263 315
	 * @param {boolean} newValue True to highlight, false to unhighlight.
264 316
	 */
265 317
	this.setHighlightedProvided = function(newValue) {
266
		highlightedProvided = newValue;
267

  
268 318
		if (newValue) {
269 319
			rootElement.classList.add('node--highlighted-provided');
270 320
		} else {
......
277 327
	};
278 328
	
279 329
	/**
280
	 * Toggles highlighting of the vertex when only its requirements should be highlighted. Anytime this value is changed, generic
281
	 * {@link Vertex#setHighlighted} method should be called too.
282
	 * @param {boolean} newValue True to highlight the vertex when only its requirements should be highlighted, false to unhighlight.
330
	 * Toggles highlighting of the vertex to mark it as instance of archetype related to some other node.
331
	 * @param {boolean} newValue True to highlight, false to unhighlight.
283 332
	 */
284
	this.setHighlightedRequiredNeighbours = function(newValue) {
285
		highlightedRequiredNeighbours = newValue;
286

  
333
	this.setHighlightedArchetype = function(newValue) {
287 334
		if (newValue) {
288
			rootElement.classList.add('node--highlighted-required-neighbours');
335
			rootElement.classList.add('node--highlighted-archetype');
289 336
		} else {
290
			rootElement.classList.remove('node--highlighted-required-neighbours');
337
			rootElement.classList.remove('node--highlighted-archetype');
291 338
		}
292
	};
293 339
	
294
	/**
295
	 * Toggles highlighting of the vertex when only its dependents should be highlighted. Anytime this value is changed, generic 
296
	 * {@link Vertex#setHighlighted} method should be called too.
297
	 * @param {boolean} newValue True to highlight the vertex when only its dependents should be highlighted, false to unhighlight.
298
	 */
299
	this.setHighlightedProvidedNeighbours = function(newValue) {
300
		highlightedProvidedNeighbours = newValue;
301

  
302
		if (newValue) {
303
			rootElement.classList.add('node--highlighted-provided-neighbours');
304
		} else {
305
			rootElement.classList.remove('node--highlighted-provided-neighbours');
340
		if (group !== null) {
341
			group.setHighlightedArchetype(newValue);
306 342
		}
307 343
	};
308 344

  
......
390 426
	 * @returns {Element} HTML or SVG DOM element depending on whether the vertex is excluded.
391 427
	 */
392 428
	this.render = function() {
429
		size.width += this.countRelatedArchetypes() * relatedArchetypeIconWidth;
430

  
393 431
		rootElement = excluded ? renderExcluded.call(this) : renderIncluded.call(this);
394 432

  
395 433
		this.setHighlighted(highlighted);
396
		this.setHighlightedRequiredNeighbours(highlightedRequiredNeighbours);
397
		this.setHighlightedProvidedNeighbours(highlightedProvidedNeighbours);
398 434

  
399 435
		return rootElement;
400 436
	};
......
447 483
		// archetype icon
448 484
		var archetypeIcon = app.dom.createSvgElement('g', {
449 485
			'class': 'archetype',
450
			'transform': 'translate(7, 6)',
486
			'transform': 'translate(8, 8)',
451 487
		});
452 488
		archetypeIcon.addEventListener('click', archetypeClick.bind(this));
453 489

  
......
464 500
		nameText.appendChild(document.createTextNode(this.name));
465 501
		rootElement.appendChild(nameText);
466 502

  
503
		// related archetype icons
504
		var relatedArchetypeListContainer = app.dom.createSvgElement('g', {
505
			'transform': `translate(${size.width - this.countRelatedArchetypes() * relatedArchetypeIconWidth}, 0)`,
506
		});
507
		rootElement.appendChild(relatedArchetypeListContainer);
508

  
509
		var i = 0;
510
		for (var archetypeIndex in relatedArchetypeMap) {
511
			var relatedArchetype = app.utils.createSvgElement('g', {
512
				'class': 'related-archetype',
513
				'transform': `translate(${i * relatedArchetypeIconWidth}, 8)`,
514
			});
515
			relatedArchetype.addEventListener('click', relatedArchetypeClick.bind(this, parseInt(archetypeIndex)));
516

  
517
			relatedArchetype.innerHTML = app.archetype.icon[app.archetype.vertex[archetypeIndex].name];
518

  
519
			relatedArchetypeListContainer.appendChild(relatedArchetype);
520

  
521
			i++;
522
		}
523

  
467 524
		// symbol list
468 525
		symbolListComponent = new VertexSymbolList;
469 526
		rootElement.appendChild(symbolListComponent.render());
......
496 553
		});
497 554
		svg.appendChild(group);
498 555

  
499
		// required
500
		var required = app.utils.createSvgElement('g', {
501
			'class': 'required-counter',
556
		// related
557
		var i = 0;
558
		for (var archetypeIndex in relatedArchetypeMap) {
559
			var relatedArchetype = app.dom.createSvgElement('g', {
560
				'class': 'related-archetype',
561
				'transform': `translate(0, ${i * 20})`,
502 562
		});
503
		required.addEventListener('click', requiredClick.bind(this));
504
		group.appendChild(required);
505

  
506
		required.appendChild(app.utils.createSvgElement('line', {
507
			'x1': -50,
508
			'y1': 5,
509
			'x2': -42,
510
			'y2': 5,
511
			'stroke': 'black',
512
			'class': 'outer-floater',
513
		}));
514
		required.appendChild(app.utils.createSvgElement('line', {
515
			'x1': -20,
516
			'y1': 5,
517
			'x2': -14,
518
			'y2': 5,
519
			'stroke': 'black',
520
		}));
521
		required.appendChild(app.utils.createSvgElement('rect', {
522
			'x': -58,
523
			'y': 1,
524
			'width': 8,
525
			'height': 8,
526
			'class': 'outer-port',
527
		}));
528
		required.appendChild(app.utils.createSvgElement('path', {
529
			'class': 'lollipop',
530
			'd': 'M-31,-5 C-16,-5 -16,15 -31,16',
531
		}));
563
			relatedArchetype.addEventListener('click', relatedArchetypeClick.bind(this, parseInt(archetypeIndex)));
532 564

  
533
		var requiredCounterText = app.utils.createSvgElement('text', {
534
			'x': -36,
535
			'y': 10,
536
		});
537
		requiredCounterText.appendChild(document.createTextNode(props.importedPackages.length));
538
		required.appendChild(requiredCounterText);
565
			relatedArchetype.innerHTML = app.archetype.icon[app.archetype.vertex[archetypeIndex].name];
539 566

  
540
		// provided
541
		var provided = app.utils.createSvgElement('g', {
542
			'class': 'provided-counter',
543
		});
544
		provided.addEventListener('click', providedClick.bind(this));
545
		group.appendChild(provided);
546

  
547
		provided.appendChild(app.utils.createSvgElement('line', {
548
			'x1': -50,
549
			'y1': 35,
550
			'x2': -44,
551
			'y2': 35,
552
			'stroke': 'black',
553
			'class': 'outer-floater',
554
		}));
555
		provided.appendChild(app.utils.createSvgElement('line', {
556
			'x1': -20,
557
			'y1': 35,
558
			'x2': -14,
559
			'y2': 35,
560
			'stroke': 'black',
561
		}));
562
		provided.appendChild(app.utils.createSvgElement('rect', {
563
			'x': -58,
564
			'y': 31,
565
			'width': 8,
566
			'height': 8,
567
			'class': 'outer-port',
568
		}));
569
		provided.appendChild(app.utils.createSvgElement('circle', {
570
			'class': 'lollipop',
571
			'cx': -32,
572
			'cy': 35,
573
			'r': 11,
574
		}));
567
			group.appendChild(relatedArchetype);
575 568

  
576
		var providedCounterText = app.utils.createSvgElement('text', {
577
			'x': -36,
578
			'y': 40,
579
		});
580
		providedCounterText.appendChild(document.createTextNode(props.exportedPackages.length));
581
		provided.appendChild(providedCounterText);
569
			i++;
570
		}
582 571

  
583 572
		// name
584 573
		var nameText = app.utils.createHtmlElement('div', {
......
646 635
			this.setHighlightedRequiredNeighbours(highlighted);
647 636
			this.setHighlightedProvidedNeighbours(highlighted);
648 637

  
649
			highlightNeighbours.call(this);
638
			prepareHighlighting.call(this);
639
			highlightRequiredNeighbours.call(this);
640
			highlightProvidedNeighbours.call(this);
650 641
			return;
651 642
		}
652 643

  
......
660 651
				this.setHighlighted(!highlighted);
661 652
				this.setHighlightedRequiredNeighbours(highlighted);
662 653
				this.setHighlightedProvidedNeighbours(highlighted);
663

  
664
				highlightNeighbours.call(this);
654
	
655
				prepareHighlighting.call(this);
656
				highlightRequiredNeighbours.call(this);
657
				highlightProvidedNeighbours.call(this);
665 658
				break;
666 659

  
667 660
			case 'exclude':
......
673 666
	}
674 667

  
675 668
	/**
676
	 * Highlights the vertex as a requirement.
677
	 */
678
	function requiredClick() {
679
		this.setHighlighted(!highlighted);
680
		this.setHighlightedRequiredNeighbours(highlighted);
681
		this.setHighlightedProvidedNeighbours(false);
682

  
683
		highlightRequiredNeighbours.call(this);
684
	}
685

  
686
	/**
687
	 * Highlights the vertex as a dependent.
669
	 * Reveals vertex popover.
670
	 * @param {MouseEvent} e Click event.
688 671
	 */
689
	function providedClick() {
690
		this.setHighlighted(!highlighted);
691
		this.setHighlightedRequiredNeighbours(false);
692
		this.setHighlightedProvidedNeighbours(highlighted);
672
	function archetypeClick(e) {
673
		e.stopPropagation();
693 674

  
694
		highlightProvidedNeighbours.call(this);
675
		app.viewportComponent.vertexPopoverComponent.setContent(this.name + ` (${app.archetype.vertex[this.archetype].name})`, props.attributes);
676
		app.viewportComponent.vertexPopoverComponent.setPosition(new Coordinates(e.clientX, e.clientY));
677
		app.viewportComponent.vertexPopoverComponent.open();
695 678
	}
696 679
	
697 680
	/**
698
	 * Reveals vertex popover.
699
	 * @param {Event} e Click event.
681
	 * Archetype icon click interaction. Toggles highlighting of neighbour vertices which are instances of a vertex archetype.
682
	 * @param {integer} archetypeIndex Index of the vertex archetype.
683
	 * @param {MouseEvent} e Click event.
700 684
	 */
701
	function archetypeClick(e) {
685
	function relatedArchetypeClick(archetypeIndex, e) {
702 686
		e.stopPropagation();
703 687

  
704
		app.viewportComponent.vertexPopoverComponent.setContent(this.name + ` (${this.archetype.name})`, props.exportedPackages);
705
		app.viewportComponent.vertexPopoverComponent.setPosition(new Coordinates(e.clientX, e.clientY));
706
		app.viewportComponent.vertexPopoverComponent.open();
688
		this.setHighlighted(!highlighted);
689
		this.setHighlightedArchetypeNeighbours(highlighted);
690

  
691
		prepareHighlighting.call(this);
692
		highlightArchetypeNeighbours.call(this, archetypeIndex);
707 693
	}
708 694

  
709 695
	/**
710 696
	 * Displays symbol of the vertex next to all nodes that it is connected with.
711
	 * @param {Event} e Click event.
697
	 * @param {MouseEvent} e Click event.
712 698
	 */
713 699
	function showIconClick(e) {
714 700
		iconsDisplayed = !iconsDisplayed;
......
815 801
			document.body.removeEventListener('mouseleave', mouseUp);
816 802
		}
817 803
	}
818
	
804

  
819 805
	/**
820
	 * Highlights all neighbours of the vertex. They are either highlighted as required or provided, or dimmed.
806
	 * * Prepares highlighting of all graph components so that only the wished ones need to be modified.
821 807
	 */
822
	function highlightNeighbours() {
808
	function prepareHighlighting() {
823 809
		this.setDimmed(false);
810

  
824 811
		this.setHighlightedRequired(false);
825 812
		this.setHighlightedProvided(false);
813
		this.setHighlightedArchetype(false);
826 814

  
827 815
		if (highlighted) {
828 816
			// dim and unhighlight all nodes but this
......
834 822
				node.setHighlighted(false);
835 823
				node.setHighlightedRequired(false);
836 824
				node.setHighlightedProvided(false);
837
				node.setHighlightedRequiredNeighbours(false);
838
				node.setHighlightedProvidedNeighbours(false);
825
				node.setHighlightedArchetype(false);
839 826
			}, this);
840 827

  
841 828
			// dim and unhighlight all edges
842 829
			app.edgeList.forEach(function(edge) {
843
				edge.setHidden(edge.getFrom().isExcluded() || edge.getTo().isExcluded());
844 830
				edge.setDimmed(true);
845 831

  
846 832
				edge.setHighlighted(false);
......
848 834
				edge.setHighlightedProvided(false);
849 835
			});
850 836

  
851
			// highlight required neighbours
852
			inEdgeList.forEach(function(edge) {
853
				edge.setHidden(false);
854
				edge.setDimmed(false);
855
				edge.setHighlightedRequired(true);
856

  
857
				edge.getFrom().setDimmed(false);
858
				edge.getFrom().setHighlightedRequired(true);
859
			});
860

  
861
			// highlight provided neighbours
862
			outEdgeList.forEach(function(edge) {
863
				edge.setHidden(false);
864
				edge.setDimmed(false);
865
				edge.setHighlightedProvided(true);
866

  
867
				edge.getTo().setDimmed(false);
868
				edge.getTo().setHighlightedProvided(true);
869
			});
870

  
871 837
		} else {
872 838
			app.nodeList.forEach(function(node) {
839
				if (node === this) return;
840

  
873 841
				node.setDimmed(false);
874 842

  
875 843
				node.setHighlighted(false);
876 844
				node.setHighlightedRequired(false);
877 845
				node.setHighlightedProvided(false);
878
				node.setHighlightedRequiredNeighbours(false);
879
				node.setHighlightedProvidedNeighbours(false);
846
				node.setHighlightedArchetype(false);
880 847
			}, this);
881 848

  
882 849
			app.edgeList.forEach(function(edge) {
883 850
				edge.setHidden(edge.getFrom().isExcluded() || edge.getTo().isExcluded());
851

  
884 852
				edge.setDimmed(false);
885 853

  
886 854
				edge.setHighlighted(false);
......
894 862
	 * Highlights only neighbours of the vertex that are required.
895 863
	 */
896 864
	function highlightRequiredNeighbours() {
897
		if (highlighted) {
898
			inEdgeList.forEach(function(edge) {
899
				edge.setHidden(false);
900
				edge.setHighlightedRequired(true);
901
				edge.getFrom().setHighlightedRequired(true);
902
			});
865
		if (highlightedRequiredNeighbours === false) return;
903 866

  
904
		} else {
905
			inEdgeList.forEach(function(edge) {
906
				edge.setHidden(true);
907
				edge.setHighlightedRequired(false);
908
				edge.getFrom().setHighlightedRequired(false);
909
			});
910
		}
867
		inEdgeList.forEach(function(edge) {
868
			edge.setHidden(false);
869

  
870
			edge.setDimmed(false);
871
			edge.getFrom().setDimmed(false);
872

  
873
			edge.setHighlightedRequired(true);
874
			edge.getFrom().setHighlightedRequired(true);
875
		});
911 876
	}
912 877

  
913 878
	/**
914 879
	 * Highlights only neighbours of the vertex that are provided.
915 880
	 */
916 881
	function highlightProvidedNeighbours() {
917
		if (highlighted) {
918
			outEdgeList.filter(function(edge) {
919
				return !edge.getTo().isExcluded();
920
			}).forEach(function(edge) {
921
				edge.setHidden(false);
922
				edge.setHighlightedProvided(true);
923
				edge.getTo().setHighlightedProvided(true);
924
			});
882
		if (highlightedProvidedNeighbours === false) return;
925 883

  
926
		} else {
927
			outEdgeList.filter(function(edge) {
928
				return !edge.getTo().isExcluded();
929
			}).forEach(function(edge) {
930
				edge.setHidden(true);
931
				edge.setHighlightedProvided(false);
932
				edge.getTo().setHighlightedProvided(false);
933
			});
934
		}
884
		outEdgeList.forEach(function(edge) {
885
			edge.setHidden(false);
886

  
887
			edge.setDimmed(false);
888
			edge.getTo().setDimmed(false);
889

  
890
			edge.setHighlightedProvided(true);
891
			edge.getTo().setHighlightedProvided(true);
892
		});
893
	}
894

  
895
	/**
896
	 * Highlights only neighbours of the vertex that are instances of the archetype.
897
	 * @param {integer} archetypeIndex Index of the vertex archetype.
898
	 */
899
	function highlightArchetypeNeighbours(archetypeIndex) {
900
		if (highlightedArchetypeNeighbours === false) return;
901

  
902
		inEdgeList.filter(function(edge) {
903
			return edge.getFrom().archetype === archetypeIndex;
904
		}).forEach(function(edge) {
905
			edge.setHidden(false);
906

  
907
			edge.setDimmed(false);
908
			edge.getFrom().setDimmed(false);
909

  
910
			edge.getFrom().setHighlightedArchetype(true);
911
		});
912

  
913
		outEdgeList.filter(function(edge) {
914
			return edge.getTo().archetype === archetypeIndex;
915
		}).forEach(function(edge) {
916
			edge.setHidden(false);
917

  
918
			edge.setDimmed(false);
919
			edge.getTo().setDimmed(false);
920

  
921
			edge.getTo().setHighlightedArchetype(true);
922
		});
935 923
	}
936 924
}

Také k dispozici: Unified diff