@progress/kendo-angular-diagrams 21.0.0-develop.8 → 21.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,13 +2,15 @@
2
2
  * Copyright © 2025 Progress Software Corporation. All rights reserved.
3
3
  * Licensed under commercial license. See LICENSE.md in the project root for more information
4
4
  *-------------------------------------------------------------------------------------------*/
5
- import { events, loadTheme, Diagram } from '@progress/kendo-diagram-common';
6
- export { ArrowMarker, Circle, CircleMarker, Collate, Connection, Connector, DataInputOutput, DataStorage, Database, Decision, Delay, Diagram, DirectAccessStorage, Display, Document, Extract, FlowchartShapeType, Group, Image, InternalStorage, Layout, Line, LogicalOr, ManualInputOutput, ManualOperation, MarkerType, Merge, MultiLineTextBlock, MultipleDocuments, OffPageConnector, OnPageConnector, Path, Point, Polyline, PredefinedProcess, Preparation, Process, Rect, Rectangle, Shape, Sort, SummingJunction, Terminator, TextBlock } from '@progress/kendo-diagram-common';
5
+ import { Shape, Connection, placeTooltip, events, convertToDiagramModel, loadTheme, Diagram } from '@progress/kendo-diagram-common';
6
+ export { ArrowMarker, Circle, CircleMarker, Collate, Connection, Connector, DataInputOutput, DataStorage, Database, Decision, Delay, DirectAccessStorage, Display, Document, Extract, FlowchartShapeType, Group, Image, InternalStorage, Layout, Line, LogicalOr, ManualInputOutput, ManualOperation, MarkerType, Merge, MultiLineTextBlock, MultipleDocuments, OffPageConnector, OnPageConnector, Path, Point, Polyline, PredefinedProcess, Preparation, Process, Rect, Rectangle, Shape, Sort, SummingJunction, Terminator, TextBlock, convertToDiagramModel } from '@progress/kendo-diagram-common';
7
7
  import * as i0 from '@angular/core';
8
- import { EventEmitter, Component, HostBinding, Input, Output, NgModule } from '@angular/core';
8
+ import { Directive, EventEmitter, Component, HostBinding, Input, Output, ViewChild, ContentChild, NgModule } from '@angular/core';
9
9
  import { validatePackage } from '@progress/kendo-licensing';
10
10
  import { getLicenseMessage, shouldShowValidationUI, hasObservers, isDocumentAvailable, WatermarkOverlayComponent } from '@progress/kendo-angular-common';
11
- import { NgIf } from '@angular/common';
11
+ import * as i1 from '@progress/kendo-angular-popup';
12
+ import { PopupService } from '@progress/kendo-angular-popup';
13
+ import { NgIf, NgTemplateOutlet } from '@angular/common';
12
14
 
13
15
  /**
14
16
  * @hidden
@@ -18,8 +20,8 @@ const packageMetadata = {
18
20
  productName: 'Kendo UI for Angular',
19
21
  productCode: 'KENDOUIANGULAR',
20
22
  productCodes: ['KENDOUIANGULAR'],
21
- publishDate: 1761844729,
22
- version: '21.0.0-develop.8',
23
+ publishDate: 1762934790,
24
+ version: '21.0.0',
23
25
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/?utm_medium=product&utm_source=kendoangular&utm_campaign=kendo-ui-angular-purchase-license-keys-warning',
24
26
  };
25
27
 
@@ -49,6 +51,90 @@ const SHAPE_DEFAULTS = {
49
51
  selectable: true,
50
52
  };
51
53
 
54
+ /**
55
+ * Defines a custom template for shape tooltips within the `kendo-diagram` component.
56
+ * Use this directive to customize how tooltips appear when hovering over shapes.
57
+ *
58
+ * @example
59
+ * ```ts
60
+ * import { Component } from '@angular/core';
61
+ *
62
+ * _@Component({
63
+ * selector: 'my-app',
64
+ * template: `
65
+ * <kendo-diagram>
66
+ * <ng-template kendoDiagramShapeTooltipTemplate let-dataItem>
67
+ * {{dataItem.tooltipContent}}
68
+ * </ng-template>
69
+ * </kendo-diagram>
70
+ * `
71
+ * })
72
+ * class AppComponent {
73
+ * }
74
+ *
75
+ * ```
76
+ */
77
+ class ShapeTooltipTemplateDirective {
78
+ /**
79
+ * @hidden
80
+ */
81
+ templateRef;
82
+ constructor(templateRef) {
83
+ this.templateRef = templateRef;
84
+ }
85
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ShapeTooltipTemplateDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
86
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: ShapeTooltipTemplateDirective, isStandalone: true, selector: "[kendoDiagramShapeTooltipTemplate]", ngImport: i0 });
87
+ }
88
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ShapeTooltipTemplateDirective, decorators: [{
89
+ type: Directive,
90
+ args: [{
91
+ selector: '[kendoDiagramShapeTooltipTemplate]',
92
+ standalone: true,
93
+ }]
94
+ }], ctorParameters: () => [{ type: i0.TemplateRef }] });
95
+
96
+ /**
97
+ * Defines a custom template for connection tooltips within the `kendo-diagram` component.
98
+ * Use this directive to customize how tooltips appear when hovering over connections.
99
+ *
100
+ * @example
101
+ * ```ts
102
+ * import { Component } from '@angular/core';
103
+ *
104
+ * _@Component({
105
+ * selector: 'my-app',
106
+ * template: `
107
+ * <kendo-diagram>
108
+ * <ng-template kendoDiagramConnectionTooltipTemplate let-dataItem>
109
+ * {{dataItem.tooltipContent}}
110
+ * </ng-template>
111
+ * </kendo-diagram>
112
+ * `
113
+ * })
114
+ * class AppComponent {
115
+ * }
116
+ *
117
+ * ```
118
+ */
119
+ class ConnectionTooltipTemplateDirective {
120
+ /**
121
+ * @hidden
122
+ */
123
+ templateRef;
124
+ constructor(templateRef) {
125
+ this.templateRef = templateRef;
126
+ }
127
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ConnectionTooltipTemplateDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
128
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: ConnectionTooltipTemplateDirective, isStandalone: true, selector: "[kendoDiagramConnectionTooltipTemplate]", ngImport: i0 });
129
+ }
130
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ConnectionTooltipTemplateDirective, decorators: [{
131
+ type: Directive,
132
+ args: [{
133
+ selector: '[kendoDiagramConnectionTooltipTemplate]',
134
+ standalone: true,
135
+ }]
136
+ }], ctorParameters: () => [{ type: i0.TemplateRef }] });
137
+
52
138
  /**
53
139
  * Represents the [Kendo UI Diagram component for Angular](slug:overview_diagram).
54
140
  *
@@ -63,41 +149,57 @@ class DiagramComponent {
63
149
  wrapperElement;
64
150
  renderer;
65
151
  zone;
152
+ popupService;
153
+ viewContainer;
66
154
  diagramClass = true;
67
155
  /**
68
156
  * Defines the default configuration options applicable to all connections.
69
- * Changing the property value dynamically triggers a reinitialization of the Diagram.
157
+ * Changing the property value dynamically triggers a reinitialization of the `Diagram`.
158
+ *
70
159
  */
71
160
  connectionDefaults = CONNECTION_DEFAULTS;
72
161
  /**
73
- * Defines the connections that render between the shapes in the Diagram.
74
- * Changing this property dynamically reinitializes the Diagram.
162
+ * Defines the connections that render between the shapes in the `Diagram` (see [Connections article](slug:diagram_connections)).
163
+ * Accepts either an array of `ConnectionOptions` or an array of any objects
164
+ * that will be mapped using the `connectionModelFields` configuration.
165
+ * Changing this property dynamically reinitializes the `Diagram`.
166
+ *
75
167
  */
76
168
  connections = [];
77
169
  /**
78
- * A set of settings to configure the Diagram behavior when the user attempts to drag, resize, or remove shapes.
79
- * Changing the property value dynamically triggers a reinitialization of the Diagram.
170
+ * Defines the field mapping configuration for connections data binding ([see example](slug:diagram_data_binding#field-mapping)).
171
+ * Maps source object properties to `Diagram` connection properties.
172
+ * Only used when `connections` is an array of custom objects instead of `ConnectionOptions`.
173
+ */
174
+ connectionModelFields;
175
+ /**
176
+ * A set of settings to configure the `Diagram` behavior when the user attempts to drag, resize, or remove shapes.
177
+ * Changing the property value dynamically triggers a reinitialization of the `Diagram`.
178
+ *
80
179
  * @default true
81
180
  */
82
181
  editable = { drag: true, resize: true, remove: true };
83
182
  /**
84
- * The layout of a diagram consists of arranging the shapes (sometimes also the connections) in some fashion in order to achieve an aesthetically pleasing experience to the user.
85
- * Changing the property value dynamically triggers a reinitialization of the Diagram.
183
+ * Defines the layout configuration for arranging shapes and connections in the `Diagram` (see [Layout article](slug:diagram_layouts)).
184
+ * Changing the property value dynamically triggers a reinitialization of the `Diagram`.
185
+ *
86
186
  */
87
187
  layout;
88
188
  /**
89
- * Defines the pannable options. Use this setting to disable Diagram pan or change the key that activates the pan behavior.
189
+ * Defines the pannable options. Use this setting to disable `Diagram` pan or change the key that activates the pan behavior.
190
+ *
90
191
  * @default true
91
192
  */
92
193
  pannable = true;
93
194
  /**
94
- * Defines the Diagram selection options.
195
+ * Defines the `Diagram` selection options.
95
196
  *
96
- * By default, you can select shapes in the Diagram in one of two ways:
197
+ * By default, you can select shapes in the `Diagram` in one of two ways:
97
198
  * - Clicking a single shape to select it and deselect any previously selected shapes.
98
199
  * - Holding the `Ctrl/Cmd on MacOS` key while clicking multiple shapes to select them and any other shapes between them.
99
200
  *
100
201
  * Use the `selectable` configuration to allow single selection only, enable selection by drawing a rectangular area with the mouse around shapes in the canvas, or disable selection altogether.
202
+ *
101
203
  * @default true
102
204
  */
103
205
  selectable = true;
@@ -107,30 +209,39 @@ class DiagramComponent {
107
209
  */
108
210
  shapeDefaults = SHAPE_DEFAULTS;
109
211
  /**
110
- * Defines the shapes that render in the Diagram.
111
- * Changing the property value dynamically triggers a reinitialization of the Diagram.
212
+ * Defines the shapes that render in the `Diagram` (see [Shapes article](slug:diagram_shapes)).
213
+ * Accepts either an array of `ShapeOptions` or an array of any objects
214
+ * that will be mapped using the `shapeModelFields` configuration.
215
+ * Changing the property value dynamically triggers a reinitialization of the `Diagram`.
216
+ *
112
217
  */
113
218
  shapes = [];
114
219
  /**
115
- * Defines the zoom level of the Diagram.
220
+ * Defines the field mapping configuration for shapes data binding ([see example](slug:diagram_data_binding#field-mapping)).
221
+ * Maps source object properties to `Diagram` shape properties.
222
+ * Only used when `shapes` is an array of custom objects instead of `ShapeOptions`.
223
+ */
224
+ shapeModelFields;
225
+ /**
226
+ * Defines the zoom level of the `Diagram`.
116
227
  *
117
228
  * @default 1
118
229
  */
119
230
  zoom = 1;
120
231
  /**
121
- * Defines the maximum zoom level of the Diagram.
232
+ * Defines the maximum zoom level of the `Diagram`.
122
233
  *
123
234
  * @default 2
124
235
  */
125
236
  zoomMax = 2;
126
237
  /**
127
- * Defines the minimum zoom level of the Diagram.
238
+ * Defines the minimum zoom level of the `Diagram`.
128
239
  *
129
240
  * @default 0.1
130
241
  */
131
242
  zoomMin = 0.1;
132
243
  /**
133
- * Defines the zoom rate of the Diagram.
244
+ * Defines the zoom rate of the `Diagram`.
134
245
  *
135
246
  * @default 0.1
136
247
  */
@@ -168,7 +279,7 @@ class DiagramComponent {
168
279
  */
169
280
  mouseLeave = new EventEmitter();
170
281
  /**
171
- * Fires when the user pans the Diagram.
282
+ * Fires when the user pans the `Diagram`.
172
283
  */
173
284
  onPan = new EventEmitter();
174
285
  /**
@@ -176,32 +287,40 @@ class DiagramComponent {
176
287
  */
177
288
  onSelect = new EventEmitter();
178
289
  /**
179
- * Fires when the diagram has finished zooming out.
290
+ * Fires when the `Diagram` has finished zooming out.
180
291
  */
181
292
  zoomEnd = new EventEmitter();
182
293
  /**
183
- * Fires when the diagram starts zooming in or out.
294
+ * Fires when the `Diagram` starts zooming in or out.
184
295
  */
185
296
  zoomStart = new EventEmitter();
297
+ /**
298
+ * Fires when a tooltip should shown for a shape or connection.
299
+ */
300
+ tooltipShow = new EventEmitter();
301
+ /**
302
+ * Fires when a tooltip should be hidden.
303
+ */
304
+ tooltipHide = new EventEmitter();
186
305
  /**
187
306
  * @hidden
188
307
  * Represents the Diagram instance, holding the core functionality of the Diagram.
189
308
  */
190
309
  diagramWidget;
191
310
  /**
192
- * The currently selected items in the Diagram.
311
+ * The currently selected items in the `Diagram`.
193
312
  */
194
313
  get selection() {
195
314
  return this.diagramWidget?.select();
196
315
  }
197
316
  /**
198
- * The actual shapes created by the Diagram.
317
+ * The actual shapes created by the `Diagram`.
199
318
  */
200
319
  get diagramShapes() {
201
320
  return this.diagramWidget?.shapes;
202
321
  }
203
322
  /**
204
- * The actual connections created by the Diagram.
323
+ * The actual connections created by the `Diagram`.
205
324
  */
206
325
  get diagramConnections() {
207
326
  return this.diagramWidget?.connections;
@@ -214,6 +333,10 @@ class DiagramComponent {
214
333
  * @hidden
215
334
  */
216
335
  licenseMessage;
336
+ /**
337
+ * @hidden
338
+ */
339
+ customTemplate;
217
340
  options = {
218
341
  shapes: this.shapes,
219
342
  connections: this.connections,
@@ -226,22 +349,43 @@ class DiagramComponent {
226
349
  shapeDefaults: this.shapeDefaults,
227
350
  connectionDefaults: this.connectionDefaults
228
351
  };
229
- constructor(wrapperElement, renderer, zone) {
352
+ /**
353
+ * Stores the converted shapes from user data.
354
+ */
355
+ convertedShapes = [];
356
+ /**
357
+ * Stores the converted connections from user data.
358
+ */
359
+ convertedConnections = [];
360
+ /**
361
+ * Current popup instance for tooltip.
362
+ */
363
+ tooltipPopup;
364
+ defaultTooltipTemplate;
365
+ customTooltipTemplate;
366
+ shapeTooltipTemplate;
367
+ connectionTooltipTemplate;
368
+ /**
369
+ * @hidden
370
+ * The original data item provided by the user. Passed in the tooltip template context.
371
+ */
372
+ dataItem;
373
+ constructor(wrapperElement, renderer, zone, popupService, viewContainer) {
230
374
  this.wrapperElement = wrapperElement;
231
375
  this.renderer = renderer;
232
376
  this.zone = zone;
377
+ this.popupService = popupService;
378
+ this.viewContainer = viewContainer;
233
379
  const isValid = validatePackage(packageMetadata);
234
380
  this.licenseMessage = getLicenseMessage(packageMetadata);
235
381
  this.showLicenseWatermark = shouldShowValidationUI(isValid);
236
382
  }
237
383
  ngOnChanges(changes) {
238
384
  let recreate = false;
239
- if (changes['shapes']) {
240
- this.options.shapes = this.shapes;
241
- recreate = true;
242
- }
243
- if (changes['connections']) {
244
- this.options.connections = this.connections;
385
+ if (changes['shapes'] || changes['connections'] || changes['shapeModelFields'] || changes['connectionModelFields']) {
386
+ this.convertUserData();
387
+ this.options.shapes = this.convertedShapes;
388
+ this.options.connections = this.convertedConnections;
245
389
  recreate = true;
246
390
  }
247
391
  if (changes['connectionDefaults']) {
@@ -298,53 +442,37 @@ class DiagramComponent {
298
442
  }
299
443
  if (recreate) {
300
444
  this.init();
445
+ this.bindDiagramEvents();
301
446
  }
302
447
  }
303
448
  ngAfterViewInit() {
449
+ this.convertUserData();
450
+ this.options.shapes = this.convertedShapes;
451
+ this.options.connections = this.convertedConnections;
304
452
  this.renderer.setStyle(this.wrapperElement.nativeElement, 'display', 'block');
305
453
  this.init();
306
- events.forEach((eventName) => {
307
- this.diagramWidget.bind(eventName, (e) => {
308
- if (eventName === 'click') {
309
- eventName = 'diagramClick';
310
- }
311
- if (eventName === 'select') {
312
- eventName = 'onSelect';
313
- }
314
- if (eventName === 'pan') {
315
- eventName = 'onPan';
316
- }
317
- if (eventName === 'itemBoundsChange') {
318
- eventName = 'shapeBoundsChange';
319
- }
320
- const emitter = this.activeEmitter(eventName);
321
- if (emitter) {
322
- this.zone.run(() => {
323
- emitter.emit(e);
324
- });
325
- }
326
- });
327
- });
454
+ this.bindDiagramEvents();
328
455
  }
329
456
  ngOnDestroy() {
457
+ this.hideTooltip();
330
458
  this.diagramWidget?.destroy();
331
459
  }
332
460
  /**
333
- * Provides the current Diagram's shapes and connections that can be used to create a new Diagram when needed.
461
+ * Provides the current `Diagram`'s shapes and connections that can be used to create a new `Diagram` when needed.
334
462
  * @returns {DiagramState} Object containing shapes and connections arrays.
335
463
  */
336
464
  getState() {
337
465
  return this.diagramWidget?.save();
338
466
  }
339
467
  /**
340
- * Focuses the Diagram.
468
+ * Focuses the `Diagram`.
341
469
  * @returns {boolean} true if focus was set successfully.
342
470
  */
343
471
  focus() {
344
472
  return this.diagramWidget?.focus();
345
473
  }
346
474
  /**
347
- * Clears the Diagram.
475
+ * Clears the `Diagram`.
348
476
  */
349
477
  clear() {
350
478
  this.diagramWidget?.clear();
@@ -359,7 +487,7 @@ class DiagramComponent {
359
487
  return this.diagramWidget?.connected(source, target);
360
488
  }
361
489
  /**
362
- * Adds connection to the Diagram.
490
+ * Adds connection to the `Diagram`.
363
491
  * @param {Connection} Connection.
364
492
  * @param {boolean} Boolean.
365
493
  * @returns {Connection} The newly created connection.
@@ -369,7 +497,7 @@ class DiagramComponent {
369
497
  return newConnection;
370
498
  }
371
499
  /**
372
- * Adds shape to the Diagram.
500
+ * Adds shape to the `Diagram`.
373
501
  * @param {ShapeOptions | Shape | Point} If you pass a `Point`, a new Shape with default options will be created and positioned at that point.
374
502
  * @param {boolean} Boolean indicating if the action should be undoable.
375
503
  * @returns {Shape} The newly created shape.
@@ -379,7 +507,7 @@ class DiagramComponent {
379
507
  return newShape;
380
508
  }
381
509
  /**
382
- * Removes shape(s) and/or connection(s) from the Diagram.
510
+ * Removes shape(s) and/or connection(s) from the `Diagram`.
383
511
  * @param {Shape | Connection | (Shape | Connection)[]} Shape, Connection or an Array of Shapes and/or Connections.
384
512
  * @param {Boolean} Boolean indicating if the action should be undoable.
385
513
  */
@@ -387,7 +515,7 @@ class DiagramComponent {
387
515
  this.diagramWidget?.remove(items, undoable);
388
516
  }
389
517
  /**
390
- * Connects two items in the Diagram.
518
+ * Connects two items in the `Diagram`.
391
519
  * @param {Shape | Connector | Point} Shape, Shape's Connector or Point.
392
520
  * @param {Shape | Connector | Point} Shape, Shape's Connector or Point.
393
521
  * @param {ConnectionOptions} Connection options.
@@ -418,7 +546,7 @@ class DiagramComponent {
418
546
  return this.diagramWidget?.select(items, options);
419
547
  }
420
548
  /**
421
- * Selects all items in the Diagram.
549
+ * Selects all items in the `Diagram`.
422
550
  */
423
551
  selectAll() {
424
552
  this.diagramWidget?.selectAll();
@@ -602,12 +730,199 @@ class DiagramComponent {
602
730
  exportVisual() {
603
731
  return this.diagramWidget?.exportVisual();
604
732
  }
733
+ /**
734
+ * Handles the tooltipShow event from the diagram widget.
735
+ */
736
+ handleTooltipShow(event) {
737
+ this.hideTooltip();
738
+ const dataItem = event.item.dataItem;
739
+ const isShape = event.item instanceof Shape;
740
+ const isConnection = event.item instanceof Connection;
741
+ this.setCustomTemplate(isShape, isConnection);
742
+ const defaultsEnabled = isShape
743
+ ? this.options.shapeDefaults.tooltip?.visible
744
+ : this.options.connectionDefaults.tooltip?.visible;
745
+ const itemTooltipEnabled = dataItem.tooltip?.visible;
746
+ const optionsArray = isShape ? this.options.shapes : this.options.connections;
747
+ const optionsItem = optionsArray?.find((item) => item.id === event.item.id);
748
+ const hasTooltipText = !!dataItem.tooltipText || !!optionsItem?.tooltipText;
749
+ if (!dataItem.tooltipText && optionsItem?.tooltipText) {
750
+ dataItem.tooltipText = optionsItem.tooltipText;
751
+ }
752
+ const shouldShowTooltip = itemTooltipEnabled !== false && hasTooltipText && (defaultsEnabled || itemTooltipEnabled);
753
+ if (shouldShowTooltip) {
754
+ this.dataItem = dataItem;
755
+ let popupContent = this.defaultTooltipTemplate;
756
+ const showCustomTemplate = Boolean((isShape && this.shapeTooltipTemplate) || (isConnection && this.connectionTooltipTemplate));
757
+ if (showCustomTemplate) {
758
+ popupContent = this.customTooltipTemplate;
759
+ }
760
+ const popupClass = this.popupClass(isShape, dataItem);
761
+ this.showTooltip(event, popupContent, popupClass);
762
+ }
763
+ }
764
+ showTooltip(event, content, popupClass) {
765
+ this.tooltipPopup = this.popupService.open({
766
+ content: content,
767
+ appendTo: this.viewContainer,
768
+ popupClass,
769
+ animate: false
770
+ });
771
+ const contentElement = this.tooltipPopup.popupElement.querySelector('.k-popup');
772
+ if (content === this.defaultTooltipTemplate) {
773
+ this.renderer.addClass(contentElement, 'k-tooltip');
774
+ }
775
+ const popupElementRect = contentElement.getBoundingClientRect();
776
+ const zoom = event.item.diagram.zoom();
777
+ const pan = event.item.diagram.pan();
778
+ const diagramRect = this.diagramWidget.element.getBoundingClientRect();
779
+ const win = this.diagramWidget.element.ownerDocument.defaultView;
780
+ const lines = this.diagramWidget.connections.map(con => con.allPoints());
781
+ const shapes = this.diagramWidget.shapes.map(shp => shp.bounds());
782
+ const pos = placeTooltip({
783
+ hovered: event.item,
784
+ mouse: event.point,
785
+ shapes: shapes,
786
+ connections: lines,
787
+ diagramRect: diagramRect,
788
+ zoom: zoom,
789
+ pan: pan,
790
+ tooltipSize: { width: popupElementRect.width, height: popupElementRect.height },
791
+ viewportBounds: new DOMRect(0, 0, win.innerWidth, win.innerHeight)
792
+ });
793
+ this.tooltipPopup.popup.instance.offset = { left: pos.left + win.scrollX, top: pos.top + win.scrollY };
794
+ this.tooltipShow.emit({ ...this.dataItem });
795
+ }
796
+ popupClass(isShape, dataItem) {
797
+ const defaultCssClass = isShape
798
+ ? this.options.shapeDefaults?.tooltip?.cssClass
799
+ : this.options.connectionDefaults?.tooltip?.cssClass;
800
+ const itemCssClass = dataItem.tooltip?.cssClass;
801
+ const popupClass = defaultCssClass || itemCssClass;
802
+ return popupClass;
803
+ }
804
+ setCustomTemplate(isShape, isConnection) {
805
+ this.customTemplate = null;
806
+ if (isShape && this.shapeTooltipTemplate) {
807
+ this.customTemplate = this.shapeTooltipTemplate.templateRef;
808
+ }
809
+ if (isConnection && this.connectionTooltipTemplate) {
810
+ this.customTemplate = this.connectionTooltipTemplate.templateRef;
811
+ }
812
+ }
813
+ /**
814
+ * Handles the tooltipHide event from the diagram widget.
815
+ */
816
+ handleTooltipHide() {
817
+ this.hideTooltip();
818
+ this.tooltipHide.emit({ ...this.dataItem });
819
+ }
820
+ /**
821
+ * Hides the current tooltip and cleans up resources.
822
+ */
823
+ hideTooltip() {
824
+ if (this.tooltipPopup) {
825
+ this.tooltipPopup.close();
826
+ this.tooltipPopup = undefined;
827
+ }
828
+ }
605
829
  activeEmitter(name) {
606
830
  const emitter = this[name];
607
831
  if (emitter?.emit && hasObservers(emitter)) {
608
832
  return emitter;
609
833
  }
610
834
  }
835
+ /**
836
+ * Binds event handlers to the diagram widget.
837
+ */
838
+ bindDiagramEvents() {
839
+ events.forEach((eventName) => {
840
+ this.diagramWidget.bind(eventName, (e) => {
841
+ if (eventName === 'click') {
842
+ eventName = 'diagramClick';
843
+ }
844
+ if (eventName === 'select') {
845
+ eventName = 'onSelect';
846
+ }
847
+ if (eventName === 'pan') {
848
+ eventName = 'onPan';
849
+ }
850
+ if (eventName === 'itemBoundsChange') {
851
+ eventName = 'shapeBoundsChange';
852
+ }
853
+ if (eventName === 'tooltipShow') {
854
+ this.zone.run(() => {
855
+ this.handleTooltipShow(e);
856
+ });
857
+ return;
858
+ }
859
+ if (eventName === 'tooltipHide') {
860
+ this.zone.run(() => {
861
+ this.handleTooltipHide();
862
+ });
863
+ return;
864
+ }
865
+ const emitter = this.activeEmitter(eventName);
866
+ if (emitter) {
867
+ this.zone.run(() => {
868
+ emitter.emit(e);
869
+ });
870
+ }
871
+ });
872
+ });
873
+ }
874
+ /**
875
+ * Converts user data to Diagram model format using field mappings.
876
+ */
877
+ convertUserData() {
878
+ if (this.shapeModelFields || this.connectionModelFields) {
879
+ const mapping = {
880
+ shapes: {
881
+ source: () => this.shapes || [],
882
+ map: this.createFieldMapping(this.shapeModelFields)
883
+ },
884
+ connections: {
885
+ source: () => this.connections || [],
886
+ map: this.createFieldMapping(this.connectionModelFields)
887
+ }
888
+ };
889
+ const result = convertToDiagramModel({ shapes: this.shapes, connections: this.options.connections }, mapping);
890
+ this.convertedShapes = this.addDataItemProperty(result.shapes, this.shapes);
891
+ this.convertedConnections = this.addDataItemProperty(result.connections, this.connections);
892
+ }
893
+ else {
894
+ this.convertedShapes = this.addDataItemProperty(this.shapes, this.shapes);
895
+ this.convertedConnections = this.addDataItemProperty(this.connections, this.connections);
896
+ }
897
+ }
898
+ addDataItemProperty(array, sourceArray) {
899
+ if (!array || !Array.isArray(array) || array.length === 0) {
900
+ return [];
901
+ }
902
+ if (!sourceArray || !Array.isArray(sourceArray)) {
903
+ return array;
904
+ }
905
+ return array.map((item, index) => ({
906
+ ...item,
907
+ dataItem: sourceArray[index]
908
+ }));
909
+ }
910
+ /**
911
+ * Creates field mapping configuration from model fields.
912
+ */
913
+ createFieldMapping(modelFields) {
914
+ if (!modelFields) {
915
+ return {};
916
+ }
917
+ const mapping = {};
918
+ Object.keys(modelFields).forEach(key => {
919
+ const fieldName = modelFields[key];
920
+ if (fieldName) {
921
+ mapping[key] = fieldName;
922
+ }
923
+ });
924
+ return mapping;
925
+ }
611
926
  init() {
612
927
  if (!isDocumentAvailable()) {
613
928
  return;
@@ -627,10 +942,18 @@ class DiagramComponent {
627
942
  this.options[prop] = this[prop];
628
943
  this.diagramWidget?.setOptions(this.options);
629
944
  }
630
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DiagramComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
631
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: DiagramComponent, isStandalone: true, selector: "kendo-diagram", inputs: { connectionDefaults: "connectionDefaults", connections: "connections", editable: "editable", layout: "layout", pannable: "pannable", selectable: "selectable", shapeDefaults: "shapeDefaults", shapes: "shapes", zoom: "zoom", zoomMax: "zoomMax", zoomMin: "zoomMin", zoomRate: "zoomRate" }, outputs: { change: "change", diagramClick: "diagramClick", drag: "drag", dragEnd: "dragEnd", dragStart: "dragStart", shapeBoundsChange: "shapeBoundsChange", mouseEnter: "mouseEnter", mouseLeave: "mouseLeave", onPan: "pan", onSelect: "select", zoomEnd: "zoomEnd", zoomStart: "zoomStart" }, host: { properties: { "class.k-diagram": "this.diagramClass" } }, exportAs: ["kendoDiagram"], usesOnChanges: true, ngImport: i0, template: `
945
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DiagramComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }, { token: i1.PopupService }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component });
946
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: DiagramComponent, isStandalone: true, selector: "kendo-diagram", inputs: { connectionDefaults: "connectionDefaults", connections: "connections", connectionModelFields: "connectionModelFields", editable: "editable", layout: "layout", pannable: "pannable", selectable: "selectable", shapeDefaults: "shapeDefaults", shapes: "shapes", shapeModelFields: "shapeModelFields", zoom: "zoom", zoomMax: "zoomMax", zoomMin: "zoomMin", zoomRate: "zoomRate" }, outputs: { change: "change", diagramClick: "diagramClick", drag: "drag", dragEnd: "dragEnd", dragStart: "dragStart", shapeBoundsChange: "shapeBoundsChange", mouseEnter: "mouseEnter", mouseLeave: "mouseLeave", onPan: "pan", onSelect: "select", zoomEnd: "zoomEnd", zoomStart: "zoomStart", tooltipShow: "tooltipShow", tooltipHide: "tooltipHide" }, host: { properties: { "class.k-diagram": "this.diagramClass" } }, providers: [PopupService], queries: [{ propertyName: "shapeTooltipTemplate", first: true, predicate: ShapeTooltipTemplateDirective, descendants: true }, { propertyName: "connectionTooltipTemplate", first: true, predicate: ConnectionTooltipTemplateDirective, descendants: true }], viewQueries: [{ propertyName: "defaultTooltipTemplate", first: true, predicate: ["defaultTemplate"], descendants: true }, { propertyName: "customTooltipTemplate", first: true, predicate: ["customTooltipTemplate"], descendants: true }], exportAs: ["kendoDiagram"], usesOnChanges: true, ngImport: i0, template: `
632
947
  <div kendoWatermarkOverlay *ngIf="showLicenseWatermark" [licenseMessage]="licenseMessage"></div>
633
- `, isInline: true, dependencies: [{ kind: "component", type: WatermarkOverlayComponent, selector: "div[kendoWatermarkOverlay]", inputs: ["licenseMessage"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
948
+
949
+ <ng-template #customTooltipTemplate>
950
+ <ng-container [ngTemplateOutlet]="customTemplate" [ngTemplateOutletContext]="{ $implicit: dataItem }"></ng-container>
951
+ </ng-template>
952
+
953
+ <ng-template #defaultTemplate>
954
+ {{dataItem?.tooltipText}}
955
+ </ng-template>
956
+ `, isInline: true, dependencies: [{ kind: "component", type: WatermarkOverlayComponent, selector: "div[kendoWatermarkOverlay]", inputs: ["licenseMessage"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
634
957
  }
635
958
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DiagramComponent, decorators: [{
636
959
  type: Component,
@@ -640,16 +963,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
640
963
  selector: 'kendo-diagram',
641
964
  template: `
642
965
  <div kendoWatermarkOverlay *ngIf="showLicenseWatermark" [licenseMessage]="licenseMessage"></div>
966
+
967
+ <ng-template #customTooltipTemplate>
968
+ <ng-container [ngTemplateOutlet]="customTemplate" [ngTemplateOutletContext]="{ $implicit: dataItem }"></ng-container>
969
+ </ng-template>
970
+
971
+ <ng-template #defaultTemplate>
972
+ {{dataItem?.tooltipText}}
973
+ </ng-template>
643
974
  `,
644
- imports: [WatermarkOverlayComponent, NgIf]
975
+ imports: [WatermarkOverlayComponent, NgIf, NgTemplateOutlet, ShapeTooltipTemplateDirective, ConnectionTooltipTemplateDirective],
976
+ providers: [PopupService]
645
977
  }]
646
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }], propDecorators: { diagramClass: [{
978
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }, { type: i1.PopupService }, { type: i0.ViewContainerRef }], propDecorators: { diagramClass: [{
647
979
  type: HostBinding,
648
980
  args: ['class.k-diagram']
649
981
  }], connectionDefaults: [{
650
982
  type: Input
651
983
  }], connections: [{
652
984
  type: Input
985
+ }], connectionModelFields: [{
986
+ type: Input
653
987
  }], editable: [{
654
988
  type: Input
655
989
  }], layout: [{
@@ -662,6 +996,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
662
996
  type: Input
663
997
  }], shapes: [{
664
998
  type: Input
999
+ }], shapeModelFields: [{
1000
+ type: Input
665
1001
  }], zoom: [{
666
1002
  type: Input
667
1003
  }], zoomMax: [{
@@ -696,6 +1032,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
696
1032
  type: Output
697
1033
  }], zoomStart: [{
698
1034
  type: Output
1035
+ }], tooltipShow: [{
1036
+ type: Output
1037
+ }], tooltipHide: [{
1038
+ type: Output
1039
+ }], defaultTooltipTemplate: [{
1040
+ type: ViewChild,
1041
+ args: ['defaultTemplate']
1042
+ }], customTooltipTemplate: [{
1043
+ type: ViewChild,
1044
+ args: ['customTooltipTemplate']
1045
+ }], shapeTooltipTemplate: [{
1046
+ type: ContentChild,
1047
+ args: [ShapeTooltipTemplateDirective]
1048
+ }], connectionTooltipTemplate: [{
1049
+ type: ContentChild,
1050
+ args: [ConnectionTooltipTemplateDirective]
699
1051
  }] } });
700
1052
 
701
1053
  /**
@@ -718,7 +1070,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
718
1070
  * ```
719
1071
  */
720
1072
  const KENDO_DIAGRAM = [
721
- DiagramComponent
1073
+ DiagramComponent,
1074
+ ShapeTooltipTemplateDirective,
1075
+ ConnectionTooltipTemplateDirective
722
1076
  ];
723
1077
 
724
1078
  /**
@@ -754,8 +1108,8 @@ const KENDO_DIAGRAM = [
754
1108
  */
755
1109
  class DiagramModule {
756
1110
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DiagramModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
757
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: DiagramModule, imports: [DiagramComponent], exports: [DiagramComponent] });
758
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DiagramModule, imports: [KENDO_DIAGRAM] });
1111
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: DiagramModule, imports: [DiagramComponent, ShapeTooltipTemplateDirective, ConnectionTooltipTemplateDirective], exports: [DiagramComponent, ShapeTooltipTemplateDirective, ConnectionTooltipTemplateDirective] });
1112
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DiagramModule, imports: [DiagramComponent] });
759
1113
  }
760
1114
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DiagramModule, decorators: [{
761
1115
  type: NgModule,
@@ -765,9 +1119,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
765
1119
  }]
766
1120
  }] });
767
1121
 
1122
+ ;
1123
+ ;
1124
+
768
1125
  /**
769
1126
  * Generated bundle index. Do not edit.
770
1127
  */
771
1128
 
772
- export { DiagramComponent, DiagramModule, KENDO_DIAGRAM };
1129
+ export { ConnectionTooltipTemplateDirective, DiagramComponent, DiagramModule, KENDO_DIAGRAM, ShapeTooltipTemplateDirective };
773
1130