Угловой + Jointjs + HTML-элемент - PullRequest
       17

Угловой + Jointjs + HTML-элемент

0 голосов
/ 25 сентября 2019

Я пытаюсь создать приложение Jointjs на Angular v8, я подготовил то же самое на обычном HTML, JS, и, кажется, работает нормально.

Требование:

  • Перетащите &Выпадающие окна из левого бокового меню
  • При перетаскивании данные должны быть преобразованы в поля с входными и выходными портами, HTML-закрытие и Div перекрывают поле

var graph = new joint.dia.Graph;

		var paper = new joint.dia.Paper({
			el: document.getElementById('editor'),
			model: graph,
			width: '80%',
			height: '100%',
			gridSize: 1
		});
		$(function () {
			$('#menu').jstree({
				'core': {
					'data': [
						{
							"text": "Root node", "children": [
								{
									"text": "Child node 1", "children": [
										{ "text": "Node 11" }, { "text": "Node 12" }]
								},
								{
									"text": "Child node 2", "children": [
										{ "text": "Node 21" }, { "text": "Node 22" }]
								}
							]
						}
					]
				},
				'plugins': ['dnd']
			});

			$(document)
				.on('dnd_move.vakata', function (e, data) {
					var t = $(data.event.target);
					if (!t.closest('.jstree').length) {
						if (t.closest('.drop').length) {
							//alert("drop zone found") ;
							data.helper.find('.jstree-icon').removeClass('jstree-er').addClass('jstree-ok');
						}
						else {
							data.helper.find('.jstree-icon').removeClass('jstree-ok').addClass('jstree-er');
						}
					}
				})
				.on('dnd_stop.vakata', function (e, data) {
					//alert(data.event.pageX + " : " + data.event.pageY) ;
					var t = $(data.event.target);
					if (!t.closest('.jstree').length) {
						if (t.closest('.drop').length) {
							createDropShape(data.event.pageX, data.event.pageY, t.closest('.drop').position(), "hello", "");
							//$(data.element).clone().appendTo(t.closest('.drop'));
						}
					}
				});
		});


		(function () {
			// Create a custom element.
			// ------------------------
			joint.shapes.html = {};
			//joint.shapes.test.Element = $.extend(joint.shapes.devs.Model, joint.shapes.basic.Rect);
			joint.shapes.html.Element = joint.shapes.devs.Model.extend({
				defaults: joint.util.deepSupplement({
					type: 'html.Element',
					attrs: {
						rect: { stroke: 'none', 'fill-opacity': 0 }
					}
				}, joint.shapes.devs.Model.prototype.defaults)
			});

			joint.shapes.html.ElementView = joint.dia.ElementView.extend({
				template: [
					'<div class="html-element">',
					'<button class="delete">x</button>',
					'<label>Test</label>',
					'</div>'
				].join(''),

				initialize: function () {
					_.bindAll(this, 'updateBox');
					joint.dia.ElementView.prototype.initialize.apply(this, arguments);

					this.$box = $(_.template(this.template)());
					// Prevent paper from handling pointerdown.
					this.$box.find('input,select').on('mousedown click', function (evt) {
						evt.stopPropagation();
					});
					// This is an example of reacting on the input change and storing the input data in the cell model.
					this.$box.find('input').on('change', _.bind(function (evt) {
						this.model.set('input', $(evt.target).val());
					}, this));
					this.$box.find('select').on('change', _.bind(function (evt) {
						this.model.set('select', $(evt.target).val());
					}, this));
					this.$box.find('select').val(this.model.get('select'));
					this.$box.find('.delete').on('click', _.bind(this.model.remove, this.model));
					// Update the box position whenever the underlying model changes.
					this.model.on('change', this.updateBox, this);
					// Remove the box when the model gets removed from the graph.
					this.model.on('remove', this.removeBox, this);

					this.updateBox();
				},
				render: function () {
					joint.dia.ElementView.prototype.render.apply(this, arguments);
					this.paper.$el.prepend(this.$box);
					this.updateBox();
					return this;
				},
				updateBox: function () {
					// Set the position and dimension of the box so that it covers the JointJS element.
					var bbox = this.model.getBBox();
					// Example of updating the HTML with a data stored in the cell model.
					this.$box.find('label').text(this.model.get('label'));
					this.$box.find('span').text(this.model.get('select'));
					this.$box.css({
						width: bbox.width,
						height: bbox.height,
						left: bbox.x,
						top: bbox.y,
						transform: 'rotate(' + (this.model.get('angle') || 0) + 'deg)'
					});
				},
				removeBox: function (evt) {
					this.$box.remove();
				}
			});
		}());
		function createDropShape(pageX, pageY, parentPosition, shapeText, icon) {

			var x = pageX - parentPosition.left;
			var y = pageY - parentPosition.top;
			/*rect.position(x, y);
			rect.resize(100, 40);
			rect.attr({
				body: {
					fill: 'blue'
				},
				label: {
					text: shapeText,
					fill: 'white'
				}
			});
			rect.addTo(graph);*/

			var m1 = new joint.shapes.html.Element({
				position: { x:x, y:y },
				size: { width: 90, height: 90 },
				inPorts: ['in1', 'in2'],
				outPorts: ['out'],
				ports: {
					groups: {
						'in': {
							attrs: {
								'.port-body': {
									fill: '#16A085'
								}
							}
						},
						'out': {
							attrs: {
								'.port-body': {
									fill: '#E74C3C'
								}
							}
						}
					}
				},
				attrs: {
					'.label': { text: 'hello', 'ref-x': .5, 'ref-y': .2 },
					rect: { fill: '#2ECC71' }
				}
			});
			graph.addCell(m1);
		}
#paper-html-elements {
			position: relative;
			border: 1px solid gray;
			display: inline-block;
			background: transparent;
			overflow: hidden;
		}
		#paper-html-elements svg {
			background: transparent;
		}
		#paper-html-elements svg .link {
			z-index: 2;
		}
		.html-element {
			position: absolute;
			background: #3498DB;
			/* Make sure events are propagated to the JointJS element so, e.g. dragging works.*/
			pointer-events: none;
			-webkit-user-select: none;
			border-radius: 4px;
			border: 2px solid #2980B9;
			box-shadow: inset 0 0 5px black, 2px 2px 1px gray;
			padding: 5px;
			box-sizing: border-box;
			z-index: 2;
		}
		.html-element select,
		.html-element input,
		.html-element button {
			/* Enable interacting with inputs only. */
			pointer-events: auto;
		}
		.html-element button.delete {
			color: white;
			border: none;
			background-color: #C0392B;
			border-radius: 20px;
			width: 15px;
			height: 15px;
			line-height: 15px;
			text-align: middle;
			position: absolute;
			top: -15px;
			left: -15px;
			padding: 0;
			margin: 0;
			font-weight: bold;
			cursor: pointer;
		}
		.html-element button.delete:hover {
			width: 20px;
			height: 20px;
			line-height: 20px;
		}
		.html-element select {
			position: absolute;
			right: 2px;
			bottom: 28px;
		}
		.html-element input {
			position: absolute;
			bottom: 0;
			left: 0;
			right: 0;
			border: none;
			color: #333;
			padding: 5px;
			height: 16px;
		}
		.html-element label {
			color: #333;
			text-shadow: 1px 0 0 lightgray;
			font-weight: bold;
		}
		.html-element span {
			position: absolute;
			top: 2px;
			right: 9px;
			color: white;
			font-size: 10px;
		}
		#menu,
		#editor {
			float: left;
			min-height:500px;
      border:1px solid red;
		}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.4.0/backbone-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jointjs/3.0.4/joint.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jointjs/3.0.4/joint.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js"></script>
<div id="container">
		<div id="menu" class="jstree jstree-default">

		</div>
		<div id="editor" class="drop">

		</div>
	</div>

Хотите знать, как это будет работать с angular, пробовал несколько вещей, так как Jointjs работал с Angular, но перекрывающийся HTML на объекте svg jointjs не работает

...