@syncfusion/ej2-treemap 20.2.36 → 20.2.38

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.
@@ -1,1575 +0,0 @@
1
- /* eslint-disable @typescript-eslint/ban-types */
2
- /* eslint-disable @typescript-eslint/dot-notation */
3
- /* eslint-disable brace-style */
4
- /* eslint-disable max-len */
5
- /**
6
- * Tree Map Components
7
- */
8
-
9
- import { Component, NotifyPropertyChanges, INotifyPropertyChanged, Property, extend, Ajax } from '@syncfusion/ej2-base';
10
- import { Complex, Collection, ModuleDeclaration } from '@syncfusion/ej2-base';
11
- import { Event, EmitType, Internationalization } from '@syncfusion/ej2-base';
12
- import { SvgRenderer } from '@syncfusion/ej2-svg-base';
13
- import { isNullOrUndefined, createElement, EventHandler, Browser, remove } from '@syncfusion/ej2-base';
14
- import { BorderModel, TitleSettingsModel, MarginModel, LevelSettingsModel, FontModel } from './model/base-model';
15
- import { LeafItemSettingsModel, TooltipSettingsModel, LegendSettingsModel, InitialDrillSettingsModel } from './model/base-model';
16
- import { HighlightSettingsModel, SelectionSettingsModel } from './model/base-model';
17
- import { Border, Margin, TitleSettings, LegendSettings, InitialDrillSettings } from './model/base';
18
- import { SelectionSettings, TooltipSettings, LevelSettings, LeafItemSettings, HighlightSettings } from './model/base';
19
- import { TreeMapModel } from './treemap-model';
20
- import { LayoutMode, TreeMapTheme, RenderingMode } from './utils/enum';
21
- import { ILoadEventArgs, ILoadedEventArgs, IPrintEventArgs } from '../treemap/model/interface';
22
- import { ILegendItemRenderingEventArgs, ILegendRenderingEventArgs, IItemDataEventArgs } from '../treemap/model/interface';
23
- import { IItemRenderingEventArgs, IResizeEventArgs, IDoubleClickEventArgs, IRightClickEventArgs } from '../treemap/model/interface';
24
- import { IItemClickEventArgs, IItemMoveEventArgs, IClickEventArgs, IMouseMoveEventArgs } from '../treemap/model/interface';
25
- import { IDrillStartEventArgs, IItemSelectedEventArgs, ITreeMapTooltipRenderEventArgs } from '../treemap/model/interface';
26
- import { IItemHighlightEventArgs, IDrillEndEventArgs, IThemeStyle } from '../treemap/model/interface';
27
- import { Size, stringToNumber, RectOption, Rect, textTrim, measureText, findChildren, removeElement, setItemTemplateContent } from '../treemap/utils/helper';
28
- import { removeClassNames, removeShape, textFormatter } from '../treemap/utils/helper';
29
- import { findPosition, Location, TextOption, renderTextElement, isContainsData, TreeMapAjax } from '../treemap/utils/helper';
30
- import { load, loaded, itemSelected, drillStart, drillEnd } from '../treemap/model/constants';
31
- import { itemClick, itemMove, click, mouseMove, resize, doubleClick, rightClick } from '../treemap/model/constants';
32
- import { LayoutPanel } from './layout/render-panel';
33
- import { TreeMapTooltip } from './user-interaction/tooltip';
34
- import { ExportType } from '../treemap/utils/enum';
35
- import { PdfPageOrientation } from '@syncfusion/ej2-pdf-export';
36
- import { TreeMapHighlight, TreeMapSelection } from './user-interaction/highlight-selection';
37
- import { TreeMapLegend } from './layout/legend';
38
- import { DataManager, Query } from '@syncfusion/ej2-data';
39
- import { getThemeStyle } from './model/theme';
40
- import { Print } from './model/print';
41
- import { ImageExport } from './model/image-export';
42
- import { PdfExport } from './model/pdf-export';
43
- /**
44
- * Represents the treemap component.
45
- * ```html
46
- * <div id="container"/>
47
- * <script>
48
- * var treemap = new TreeMap();
49
- * treemap.appendTo("#container");
50
- * </script>
51
- * ```
52
- */
53
-
54
- @NotifyPropertyChanges
55
- export class TreeMap extends Component<HTMLElement> implements INotifyPropertyChanged {
56
- //Module Declaration for treemap.
57
- /**
58
- * Sets and gets the module that is used to add tooltip in the treemap.
59
- */
60
- public treeMapTooltipModule: TreeMapTooltip;
61
- /**
62
- * Sets and gets the module that is used to add highlight functionality in the treemap.
63
- */
64
- public treeMapHighlightModule: TreeMapHighlight;
65
- /**
66
- * Sets and gets the module that is used to add selection functionality in the treemap.
67
- */
68
- public treeMapSelectionModule: TreeMapSelection;
69
- /**
70
- * Sets and gets the module that is used to add legend in the treemap.
71
- */
72
- public treeMapLegendModule: TreeMapLegend;
73
- /**
74
- * Sets and gets the module that is used to add print functionality in the treemap.
75
- *
76
- * @private
77
- */
78
- public printModule: Print;
79
- /**
80
- * Sets and gets the module that is used to add imageExport functionality in the treemap.
81
- *
82
- * @private
83
- */
84
- public imageExportModule: ImageExport;
85
- /**
86
- * Sets and gets the module that is used to add pdf export functionality in the treemap.
87
- *
88
- * @private
89
- */
90
- public pdfExportModule: PdfExport ;
91
- /**
92
- * Enables and disables the print functionality in treemap.
93
- *
94
- * @default false
95
- */
96
- @Property(false)
97
- public allowPrint: boolean;
98
- /**
99
- * Enables and disables the export to image functionality in treemap.
100
- *
101
- * @default false
102
- */
103
- @Property(false)
104
- public allowImageExport: boolean;
105
- /**
106
- * Enables and disables the export to pdf functionality in treemap.
107
- *
108
- * @default false
109
- */
110
- @Property(false)
111
- public allowPdfExport: boolean;
112
- /**
113
- * Sets and gets the width of the treemap component.
114
- *
115
- * @default null
116
- */
117
- @Property(null)
118
- public width: string;
119
- /**
120
- * Sets and gets the height of the treemap component.
121
- *
122
- * @default null
123
- */
124
- @Property(null)
125
- public height: string;
126
- /**
127
- * Sets and gets the options for customizing the color and width of the treemap border.
128
- */
129
- @Complex<BorderModel>({}, Border)
130
- public border: BorderModel;
131
- /**
132
- * Sets and gets the options for customizing the margin in the treemap component.
133
- */
134
- @Complex<MarginModel>({}, Margin)
135
- public margin: MarginModel;
136
- /**
137
- * Sets and gets the background color of the treemap.
138
- */
139
- @Property(null)
140
- public background: string;
141
- /**
142
- * Sets and gets the options for customizing the theme of the treemap component.
143
- */
144
- @Property('Material')
145
- public theme: TreeMapTheme;
146
- /**
147
- * Sets and gets the options for customizing the title of the treemap component.
148
- */
149
- @Complex<TitleSettingsModel>({}, TitleSettings)
150
- public titleSettings: TitleSettingsModel;
151
- /**
152
- * Specifies the rendering type of layout of the treemap component.
153
- */
154
- @Property('Squarified')
155
- public layoutType: LayoutMode;
156
- /**
157
- * Sets and gets the data source for the treemap component.
158
- *
159
- * @isGenericType true
160
- * @isObservable true
161
- * @default null
162
- */
163
- @Property(null)
164
- public dataSource: DataManager | TreeMapAjax | Object[];
165
- /**
166
- * Sets and gets the query to select particular data from the shape data.
167
- * This property is applicable only when the data source is created by data manager.
168
- *
169
- * @default null
170
- */
171
- @Property(null)
172
- public query: Query;
173
- /**
174
- * Sets and gets the value path of the weight from the data source, based on which the map item is rendered.
175
- */
176
- @Property(null)
177
- public weightValuePath: string;
178
- /**
179
- * Sets and gets the value path from the data source, based on it color is filled in treemap.
180
- */
181
- @Property('')
182
- public rangeColorValuePath: string;
183
- /**
184
- * Sets and gets the value path from the data source, based on it color is filled in treemap.
185
- */
186
- @Property('')
187
- public equalColorValuePath: string;
188
- /**
189
- * Sets and gets the value path from the data source, based on it color is filled in treemap.
190
- */
191
- @Property(null)
192
- public colorValuePath: string;
193
- /**
194
- * Sets and gets the set of colors to apply in the treemap items.
195
- */
196
- @Property([])
197
- public palette: string[];
198
- /**
199
- * Specifies the rendering direction of layout of the treemap items.
200
- *
201
- * @default TopLeftBottomRight
202
- */
203
- @Property('TopLeftBottomRight')
204
- public renderDirection: RenderingMode;
205
- /**
206
- * Enables or disables the drill down functionality in treemap.
207
- */
208
- @Property(false)
209
- public enableDrillDown: boolean;
210
- /**
211
- * Enables or disables the connection text in the header of the treemap.
212
- */
213
- @Property(false)
214
- public enableBreadcrumb: boolean;
215
- /**
216
- * Specifies the connection between the two words.
217
- */
218
- @Property(' - ')
219
- public breadcrumbConnector: string;
220
- /**
221
- * Enables or disables the initial drill in the treemap.
222
- */
223
- @Property(false)
224
- public drillDownView: boolean;
225
- /**
226
- * Specifies the options for customizing the initial drill down in treemap.
227
- */
228
- @Complex<InitialDrillSettingsModel>({}, InitialDrillSettings)
229
- public initialDrillDown: InitialDrillSettingsModel;
230
- /**
231
- * Sets and gets the options for customizing the leaf item of the treemap.
232
- */
233
- @Complex<LeafItemSettingsModel>({}, LeafItemSettings)
234
- public leafItemSettings: LeafItemSettingsModel;
235
- /**
236
- * Sets and gets the options for customizing the levels of the treemap.
237
- */
238
- @Collection<LevelSettingsModel>([], LevelSettings)
239
- public levels: LevelSettingsModel[];
240
- /**
241
- * Sets and gets the options for customizing the highlight of the treemap item on mouse over on the treemap component.
242
- */
243
- @Complex<HighlightSettingsModel>({}, HighlightSettings)
244
- public highlightSettings: HighlightSettingsModel;
245
- /**
246
- * Sets and gets the options for customizing the selection of the treemap item on click event on the treemap component.
247
- */
248
- @Complex<SelectionSettingsModel>({}, SelectionSettings)
249
- public selectionSettings: SelectionSettingsModel;
250
- /**
251
- * Sets and gets the options for customizing the tooltip of the treemap.
252
- */
253
- @Complex<TooltipSettingsModel>({}, TooltipSettings)
254
- public tooltipSettings: TooltipSettingsModel;
255
- /**
256
- * Sets and gets the options for customizing the legend of the treemap.
257
- */
258
- @Complex<LegendSettingsModel>({}, LegendSettings)
259
- public legendSettings: LegendSettingsModel;
260
- /**
261
- * Enables or disables the visibility state of the separator for grouping.
262
- *
263
- * @default false
264
- */
265
- @Property(false)
266
- public useGroupingSeparator: boolean;
267
- /**
268
- * Sets and gets the description for treemap.
269
- *
270
- * @default null
271
- */
272
- @Property(null)
273
- public description: string;
274
-
275
- /**
276
- * Sets and gets the tab index value for treemap.
277
- *
278
- * @default 1
279
- */
280
- @Property(1)
281
- public tabIndex: number;
282
- /**
283
- * Sets and gets format for the texts in the treemap.
284
- *
285
- * @default null
286
- */
287
- @Property(null)
288
- public format: string;
289
- /**
290
- * Triggers when the treemap is on load.
291
- *
292
- * @event
293
- */
294
- @Event()
295
- public load: EmitType<ILoadEventArgs>;
296
- /**
297
- * Triggers before the prints gets started.
298
- *
299
- * @event
300
- */
301
- @Event()
302
- public beforePrint: EmitType<IPrintEventArgs>;
303
- /**
304
- * Triggers after treemap is rendered.
305
- *
306
- * @event
307
- */
308
- @Event()
309
- public loaded: EmitType<ILoadedEventArgs>;
310
- /**
311
- * Triggers before item rendering in the treemap component.
312
- *
313
- * @event
314
- */
315
- @Event()
316
- public itemRendering: EmitType<IItemRenderingEventArgs>;
317
- /**
318
- * Triggers on performing drill down functionality in the treemap.
319
- *
320
- * @event
321
- */
322
- @Event()
323
- public drillStart: EmitType<IDrillStartEventArgs>;
324
- /**
325
- * Triggers after drill down functionality gets completed in the treemap.
326
- *
327
- * @event
328
- */
329
- @Event()
330
- public drillEnd: EmitType<IDrillEndEventArgs>;
331
- /**
332
- * Triggers after selecting a treemap item.
333
- *
334
- * @event
335
- */
336
- @Event()
337
- public itemSelected: EmitType<IItemSelectedEventArgs>;
338
- /**
339
- * Triggers after highlighting on the treemap item.
340
- *
341
- * @event
342
- */
343
- @Event()
344
- public itemHighlight: EmitType<IItemHighlightEventArgs>;
345
- /**
346
- * Triggers on rendering of the tooltip in the treemap component.
347
- *
348
- * @event
349
- */
350
- @Event()
351
- public tooltipRendering: EmitType<ITreeMapTooltipRenderEventArgs>;
352
- /**
353
- * Triggers after clicking an item in the treemap.
354
- *
355
- * @event
356
- */
357
- @Event()
358
- public itemClick: EmitType<IItemClickEventArgs>;
359
- /**
360
- * Triggers after mouse hover on the treemap item.
361
- *
362
- * @event
363
- */
364
- @Event()
365
- public itemMove: EmitType<IItemMoveEventArgs>;
366
- /**
367
- * Triggers after clicking on the treemap.
368
- *
369
- * @event
370
- */
371
- @Event()
372
- public click: EmitType<IItemClickEventArgs>;
373
- /**
374
- * Triggers after double clicking on the treemap.
375
- *
376
- * @event
377
- */
378
- @Event()
379
- public doubleClick: EmitType<IDoubleClickEventArgs>;
380
- /**
381
- * Triggers after right clicking on the treemap.
382
- *
383
- * @event
384
- */
385
- @Event()
386
- public rightClick: EmitType<IMouseMoveEventArgs>;
387
- /**
388
- * Triggers after mouse hover on the treemap.
389
- *
390
- * @event
391
- */
392
- @Event()
393
- public mouseMove: EmitType<IMouseMoveEventArgs>;
394
- /**
395
- * Triggers after resizing the treemap component.
396
- *
397
- * @event
398
- */
399
- @Event()
400
- public resize: EmitType<IResizeEventArgs>;
401
- /**
402
- * Triggers before rendering each legend item in the treemap.
403
- *
404
- * @event
405
- */
406
- @Event()
407
- public legendItemRendering: EmitType<ILegendItemRenderingEventArgs>;
408
- /**
409
- * Triggers before rendering the legend items in the treemap.
410
- *
411
- * @event
412
- * @deprecated
413
- */
414
- @Event()
415
- public legendRendering: EmitType<ILegendRenderingEventArgs>;
416
-
417
- /**
418
- * resize the treemap
419
- */
420
- private isResize: boolean = false;
421
- /**
422
- * svg renderer object.
423
- *
424
- * @private
425
- */
426
- public renderer: SvgRenderer;
427
- /**
428
- * treemap svg element object
429
- *
430
- * @private
431
- */
432
- public svgObject: Element;
433
- /**
434
- * Stores the exact size of treemap.
435
- *
436
- * @private
437
- */
438
- public availableSize: Size;
439
- /**
440
- * Internal use of internationalization instance.
441
- *
442
- * @private
443
- */
444
- public intl: Internationalization;
445
- /**
446
- * @private
447
- * Stores the area bounds.
448
- */
449
- public areaRect: Rect;
450
- /**
451
- * Define the theme style for treemap components
452
- *
453
- * @private
454
- */
455
- public themeStyle: IThemeStyle;
456
- /**
457
- * @private
458
- * Stores the legend bounds.
459
- */
460
- public totalRect: Rect;
461
- /** @private */
462
- public layout: LayoutPanel;
463
- /** @private */
464
- public orientation: string = 'Horizontal';
465
- /** @private */
466
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
467
- public drilledItems: any[] = [];
468
- /** @private */
469
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
470
- public drilledLegendItems: any;
471
- /** @private */
472
- public currentLevel: number;
473
- /** @private */
474
- public isHierarchicalData: boolean = false;
475
- /** @private */
476
- private resizeTo: number;
477
- /** @private */
478
- private mouseDown: boolean;
479
- /** @private */
480
- private drillMouseMove: boolean;
481
- /** @private */
482
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
483
- public doubleTapTimer: any;
484
- /** @private */
485
- public levelSelection: string[] = [];
486
- /** @private */
487
- public legendId: string[] = [];
488
- /** @private */
489
- public selectionId: string;
490
-
491
- /**s
492
- * Constructor for TreeMap component.
493
- */
494
- // eslint-disable-next-line @typescript-eslint/explicit-member-accessibility
495
- constructor(options?: TreeMapModel, element?: string | HTMLElement) {
496
- super(options, element);
497
- }
498
-
499
- protected preRender(): void {
500
- this.trigger(load, { treemap: this }, () => {
501
- this.initPrivateVariable();
502
- this.unWireEVents();
503
- this.createSvg();
504
- this.wireEVents();
505
- this.setCulture();
506
- });
507
-
508
- }
509
-
510
- protected render(): void {
511
- this.renderElements();
512
- }
513
-
514
- private renderElements(): void {
515
- LevelsData.levelsData = null;
516
- LevelsData.defaultLevelsData = null;
517
- LevelsData.hierarchyData = null;
518
- this.createSecondaryElement();
519
- this.addTabIndex();
520
- this.themeStyle = getThemeStyle(this.theme);
521
- this.renderBorder();
522
- this.renderTitle(this.titleSettings, 'title', null, null);
523
- if (!isNullOrUndefined(LevelsData.levelsData)) {
524
- LevelsData.defaultLevelsData = LevelsData.levelsData;
525
- }
526
- this.processDataManager();
527
- }
528
-
529
- private processDataManager(): void {
530
- let dataModule: DataManager; let queryModule: Query; let ajaxModule: Ajax;
531
- let localAjax: TreeMapAjax;
532
- if (this.dataSource instanceof DataManager) {
533
- dataModule = this.dataSource;
534
- queryModule = this.query instanceof Query ? this.query : new Query();
535
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
536
- const dataManager: Promise<any> = dataModule.executeQuery(queryModule);
537
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
538
- dataManager.then((e: any) => {
539
- this.dataSource = e['result'];
540
- this.renderTreeMapElements();
541
- });
542
- } else if (this.dataSource instanceof TreeMapAjax) {
543
- localAjax = this.dataSource as TreeMapAjax;
544
- ajaxModule = new Ajax(localAjax.dataOptions, localAjax.type, localAjax.async, localAjax.contentType);
545
- ajaxModule.onSuccess = (args: string) => {
546
- this.dataSource = JSON.parse('[' + args + ']')[0];
547
- this.renderTreeMapElements();
548
- };
549
- ajaxModule.send(localAjax.sendData);
550
- } else {
551
- this.renderTreeMapElements();
552
- }
553
- }
554
-
555
- private renderTreeMapElements(): void {
556
-
557
- this.processingData();
558
-
559
- if (this.treeMapLegendModule && this.legendSettings.visible) {
560
-
561
- this.treeMapLegendModule.renderLegend();
562
-
563
- }
564
-
565
- this.layout.processLayoutPanel();
566
-
567
- this.element.appendChild(this.svgObject);
568
-
569
- this.elementChange();
570
-
571
- this.trigger(loaded, {treemap: this, isResized: this.isResize});
572
- this.isResize = false;
573
-
574
- this.renderComplete();
575
- }
576
-
577
- protected createSvg(): void {
578
- if (this.svgObject) {
579
- while (this.svgObject.childNodes.length > 0) {
580
- this.svgObject.removeChild(this.svgObject.firstChild);
581
- }
582
- if (!this.svgObject.hasChildNodes() && this.svgObject.parentNode) {
583
- remove(this.svgObject);
584
- }
585
- }
586
- this.clearTemplate();
587
- const containerWidth: number = this.element.clientWidth;
588
- const containerHeight: number = this.element.clientHeight;
589
- this.availableSize = new Size(
590
- stringToNumber(this.width, containerWidth) || containerWidth || 600,
591
- stringToNumber(this.height, containerHeight) || containerHeight || 450
592
- );
593
- this.svgObject = this.renderer.createSvg({
594
- id: this.element.id + '_svg',
595
- width: this.availableSize.width,
596
- height: this.availableSize.height
597
- });
598
- }
599
-
600
-
601
- /**
602
- * To initilize the private varibales of treemap.
603
- *
604
- * @returns {void}
605
- */
606
- private initPrivateVariable(): void {
607
- if (this.element.id === '') {
608
- const collection: number = document.getElementsByClassName('e-treemap').length;
609
- this.element.id = 'treemap_control_' + collection;
610
- }
611
- this.renderer = new SvgRenderer(this.element.id);
612
-
613
- this.layout = new LayoutPanel(this);
614
-
615
- }
616
-
617
- private createSecondaryElement(): void {
618
- const secondaryEle: Element = document.getElementById(this.element.id + '_Secondary_Element');
619
- if (secondaryEle && secondaryEle.childElementCount > 0) {
620
- secondaryEle.parentNode.removeChild(secondaryEle);
621
- }
622
- if (isNullOrUndefined(document.getElementById(this.element.id + '_Secondary_Element'))) {
623
- const secondaryElement: Element = createElement('div', {
624
- id: this.element.id + '_Secondary_Element',
625
- styles: 'position: absolute;z-index:1;'
626
- });
627
- this.element.appendChild(secondaryElement);
628
- }
629
- }
630
-
631
- private elementChange(): void {
632
- if (this.treeMapLegendModule && this.legendSettings.visible && this.treeMapLegendModule.legendGroup && this.layout.layoutGroup
633
- && !isNullOrUndefined(this.svgObject) && !isNullOrUndefined(document.getElementById(this.layout.layoutGroup.id))
634
- && !isNullOrUndefined(document.getElementById(this.treeMapLegendModule.legendGroup.id))) {
635
- this.svgObject.insertBefore(this.layout.layoutGroup, this.treeMapLegendModule.legendGroup);
636
- }
637
- }
638
-
639
- /**
640
- * @private
641
- * Render the treemap border
642
- *
643
- * @returns {void}
644
- */
645
- private renderBorder(): void {
646
- const width: number = this.border.width;
647
- const borderElement: Element = this.svgObject.querySelector('#' + this.element.id + '_TreeMap_Border');
648
- if ((this.border.width > 0 || (this.background || this.themeStyle.backgroundColor)) && isNullOrUndefined(borderElement)) {
649
- const borderRect: RectOption = new RectOption(
650
- this.element.id + '_TreeMap_Border', this.background || this.themeStyle.backgroundColor, this.border, 1,
651
- new Rect(width / 2, width / 2, this.availableSize.width - width, this.availableSize.height - width));
652
- this.svgObject.appendChild(this.renderer.drawRectangle(borderRect) as SVGRectElement);
653
- } else if (borderElement) {
654
- borderElement.setAttribute('fill', this.background || this.themeStyle.backgroundColor);
655
- }
656
- }
657
-
658
- private renderTitle(title: TitleSettingsModel, type: string, bounds: Rect, groupEle: Element): void {
659
- const style: FontModel = title.textStyle;
660
- let height: number; const titlePadding: number = 10;
661
- const width: number = (this.availableSize.width - this.margin.right - this.margin.left);
662
- title.textStyle.fontFamily = this.themeStyle.fontFamily || title.textStyle.fontFamily;
663
- title.textStyle.size = this.themeStyle.fontSize || title.textStyle.size;
664
- if (title.text) {
665
- if (isNullOrUndefined(groupEle)) {
666
- groupEle = this.renderer.createGroup({ id: this.element.id + '_Title_Group' });
667
- }
668
- const trimmedTitle: string = textTrim(width, title.text, style);
669
- const elementSize: Size = measureText(trimmedTitle, style);
670
- const rect: Rect = (isNullOrUndefined(bounds)) ? new Rect(
671
- this.margin.left, this.margin.top, this.availableSize.width, this.availableSize.height) : bounds;
672
- const location: Location = findPosition(rect, title.alignment, elementSize, type);
673
- const options: TextOption = new TextOption(
674
- this.element.id + '_TreeMap_' + type, location.x, location.y, 'start', trimmedTitle
675
- );
676
- const titleBounds: Rect = new Rect(location.x, location.y, elementSize.width, elementSize.height);
677
- const element: Element = renderTextElement(
678
- options, style, style.color || (type === 'title' ? this.themeStyle.titleFontColor : this.themeStyle.subTitleFontColor),
679
- groupEle
680
- );
681
- element.setAttribute('aria-label', title.description || title.text);
682
- element.setAttribute('tabindex', (this.tabIndex + (type === 'title' ? 1 : 2)).toString());
683
- if ((type === 'title' && !title.subtitleSettings.text) || (type === 'subtitle')) {
684
- height = (this.availableSize.height - titleBounds.y - titlePadding - this.margin.bottom);
685
- this.areaRect = new Rect(this.margin.left, titleBounds.y + titlePadding, width, height);
686
- }
687
- if (type !== 'subtitle' && title.subtitleSettings.text) {
688
- this.renderTitle(title.subtitleSettings, 'subtitle', titleBounds, groupEle);
689
- } else {
690
- this.svgObject.appendChild(groupEle);
691
- }
692
- } else {
693
- height = (this.availableSize.height - this.margin.top - this.margin.bottom);
694
- this.areaRect = new Rect(this.margin.left, this.margin.top, width, height);
695
- }
696
- }
697
-
698
-
699
-
700
- protected processingData(): void {
701
- let path: string;
702
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
703
- this.dataSource = this.dataSource as any[];
704
- if (!isNullOrUndefined(this.dataSource) && this.dataSource.length > 0 && this.weightValuePath) {
705
- LevelsData.levelsData = [];
706
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
707
- this.dataSource.map((data: any) => {
708
- data[this.weightValuePath] = (data[this.weightValuePath]) ? (data[this.weightValuePath] as string).toString() :
709
- data[this.weightValuePath];
710
- });
711
- this.leafItemSettings.labelPath = this.leafItemSettings.labelPath || this.weightValuePath;
712
- this.checkIsHierarchicalData();
713
- if (this.levels.length === 0) {
714
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
715
- const data: any = {};
716
- data['level'] = 0;
717
- path = this.leafItemSettings.labelPath;
718
- data[path] = [];
719
- for (let i: number = 0; i < this.dataSource.length; i++) {
720
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
721
- const child: any[] = findChildren(this.dataSource[i])['values'];
722
- if (this.isHierarchicalData && child && child.length > 0) {
723
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
724
- child.forEach((currentData: any, dataIndex: number) => {
725
- if (currentData[path]) {
726
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
727
- (<any[]>data[path]).push({
728
- groupIndex: 0, name: currentData[path], levelOrderName: (currentData[path] as string).toString(),
729
- data: currentData, weight: currentData[this.weightValuePath]
730
- });
731
- }
732
- });
733
- } else {
734
- if (this.dataSource[i][path]) {
735
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
736
- (<any[]>data[path]).push({
737
- groupIndex: 0, name: this.dataSource[i][path], levelOrderName: (
738
- this.dataSource[i][path] as string).toString(), data: this.dataSource[i],
739
- weight: this.dataSource[i][this.weightValuePath]
740
- });
741
- }
742
- }
743
- }
744
- LevelsData.levelsData.push(data);
745
- } else {
746
- if (this.isHierarchicalData) {
747
- LevelsData.hierarchyData = [];
748
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
749
- LevelsData.hierarchyData = extend([], this.dataSource, LevelsData.hierarchyData, true) as any[];
750
- for (let i: number = 0; i < LevelsData.hierarchyData.length; i++) {
751
- this.processHierarchicalData(LevelsData.hierarchyData[i], i);
752
- }
753
- LevelsData.levelsData = LevelsData.hierarchyData;
754
- } else {
755
- this.processFlatJsonData();
756
- if (LevelsData.levelsData.length > 1) {
757
- this.reOrderLevelData(LevelsData.levelsData.length - 1);
758
- }
759
- }
760
- path = this.levels[0].groupPath;
761
- }
762
- if (!this.isHierarchicalData) {
763
- this.findTotalWeight(LevelsData.levelsData[0][path], 'Parent');
764
- }
765
- }
766
- }
767
-
768
- private checkIsHierarchicalData(): void {
769
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
770
- let child: any[]; this.dataSource = this.dataSource as any[];
771
- for (let i: number = 0; i < this.dataSource.length; i++) {
772
- child = findChildren(this.dataSource[i])['values'];
773
- if (child && child.length) {
774
- this.isHierarchicalData = true;
775
- break;
776
- } else if (i === this.dataSource.length - 1) {
777
- this.isHierarchicalData = false;
778
- }
779
- }
780
- }
781
-
782
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
783
- private processHierarchicalData(data: any, dataCount: number): void {
784
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
785
- let childData: any[]; const levelData: any[] = [];
786
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
787
- let newData: any = {};
788
- let levelIndex: number;
789
- const path: string = this.leafItemSettings.labelPath ? this.leafItemSettings.labelPath : this.weightValuePath;
790
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
791
- const currentData: any = {};
792
- let level: LevelSettingsModel; let key: string;
793
- newData = findChildren(data);
794
- childData = newData ? newData['values'] : null;
795
- if (childData && childData.length > 0) {
796
- key = newData['key'];
797
- for (let i: number = 0; i < this.levels.length; i++) {
798
- if (key === this.levels[i].groupPath) {
799
- level = this.levels[i];
800
- levelIndex = i;
801
- }
802
- }
803
- for (let j: number = 0; j < childData.length; j++) {
804
- childData[j]['name'] = childData[j][path];
805
- childData[j]['levelOrderName'] = (levelIndex === 0 ? childData[j]['name'] :
806
- data['levelOrderName'] + '#' + childData[j]['name']) + '';
807
- const childItemLevel: string = childData[j]['levelOrderName']; let childLevel: number;
808
- if (childItemLevel.search('#') > 0) {
809
- childLevel = childItemLevel.split('#').length - 1;
810
- }
811
- childData[j]['groupIndex'] = isNullOrUndefined(levelIndex) ? childLevel === this.levels.length
812
- ? this.levels.length : childLevel : levelIndex;
813
- if (levelIndex !== 0) {
814
- childData[j]['parent'] = data;
815
- }
816
- childData[j]['groupName'] = key;
817
- childData[j]['data'] = childData[j];
818
- childData[j]['isDrilled'] = false;
819
- childData[j]['weight'] = childData[j][this.weightValuePath];
820
- }
821
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
822
- childData.forEach((currentData: any) => {
823
- this.processHierarchicalData(currentData, dataCount);
824
- });
825
- }
826
- if (dataCount === LevelsData.hierarchyData.length - 1) {
827
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
828
- let mainData: any[] = LevelsData.hierarchyData[0][this.levels[0].groupPath];
829
- for (let k: number = 0; k < LevelsData.hierarchyData.length; k++) {
830
- childData = findChildren(LevelsData.hierarchyData[k])['values'];
831
- if (k !== 0 && childData) {
832
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
833
- childData.forEach((currentData: any) => { mainData.push(currentData); });
834
- LevelsData.hierarchyData.splice(k, 1);
835
- k -= 1;
836
- }
837
- }
838
- mainData = LevelsData.hierarchyData[0][this.levels[0].groupPath];
839
- for (let l: number = 0; l < mainData.length; l++) {
840
- newData[this.levels[0].groupPath] = mainData;
841
- mainData[l]['parent'] = newData;
842
- }
843
- }
844
- }
845
- /* eslint-disable valid-jsdoc */
846
- /**
847
- * This method is used to perform the print functionality in treemap.
848
- *
849
- * @param id - Specifies the element to print the treemap.
850
- */
851
- public print(id?: string[] | string | Element): void {
852
- if (this.allowPrint && this.printModule) {
853
- this.printModule.print(id);
854
- }
855
- }
856
- /**
857
- * This method is used to perform the export functionality for the rendered treemap.
858
- *
859
- * @param type - Specifies the index of the axis.
860
- * @param fileName - Specifies file name for exporting the rendered treemap.
861
- * @param orientation - Specifies the orientation of the pdf document.
862
- */
863
- public export(type: ExportType, fileName: string, orientation?: PdfPageOrientation, allowDownload?: boolean): Promise<string> {
864
- if (isNullOrUndefined(allowDownload)) {
865
- allowDownload = true;
866
- }
867
- if (type === 'PDF' && this.allowPdfExport && this.pdfExportModule) {
868
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
869
- return new Promise((resolve: any, reject: any) => {
870
- resolve(this.pdfExportModule.export(type, fileName, orientation, allowDownload));
871
- });
872
-
873
- } else if (this.allowImageExport && (type !== 'PDF') && this.imageExportModule) {
874
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
875
- return new Promise((resolve: any, reject: any) => {
876
- resolve(this.imageExportModule.export(type, fileName, allowDownload));
877
- });
878
- }
879
- return null;
880
- }
881
- private processFlatJsonData(): void {
882
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
883
- this.dataSource = this.dataSource as any[];
884
- let groupPath: string; let childGroupPath: string;
885
- const orderNames: string[] = []; const process: boolean = false;
886
- for (let i: number = 0; i < this.levels.length + 1; i++) {
887
- groupPath = this.levels[i] ? this.levels[i].groupPath : this.leafItemSettings.labelPath;
888
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
889
- const level: any = {};
890
- level['level'] = i;
891
- level[groupPath] = [];
892
- LevelsData.levelsData.push(level);
893
- for (let j: number = 0; j < this.dataSource.length; j++) {
894
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
895
- const currentData: any = {}; let childName: string = '';
896
- if (!isNullOrUndefined(groupPath)) {
897
- const name: string = this.dataSource[j][groupPath];
898
- if (i !== 0) {
899
- for (let k: number = 0; k <= i; k++) {
900
- const childGroupPath: string = this.levels[k] ? this.levels[k].groupPath : groupPath;
901
- childName += (this.dataSource[j][childGroupPath]) + ((k === i) ? '' : '#');
902
- }
903
- }
904
- if (!(orderNames.length > 0 ? orderNames.indexOf(childName ?
905
- childName : name) !== -1 : false)) {
906
- currentData['name'] = name;
907
- currentData['levelOrderName'] = ((childName) ? childName : name) + '';
908
- currentData['groupIndex'] = i;
909
- currentData['isDrilled'] = false;
910
- currentData['groupName'] = groupPath;
911
- currentData['data'] = this.dataSource[j];
912
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
913
- (<any[]>LevelsData.levelsData[LevelsData.levelsData.length - 1][groupPath]).push(currentData);
914
- orderNames.push((childName) ? childName : name);
915
- }
916
- }
917
- }
918
- }
919
- }
920
-
921
- /**
922
- * This method orders the treemap level data.
923
- *
924
- * @param start - Specifies the start value of the treemap level.
925
- */
926
- public reOrderLevelData(start: number): void {
927
- let currentName: string;
928
- const currentPath: string = this.levels[start] ? this.levels[start].groupPath : this.leafItemSettings.labelPath;
929
- const prevPath: string = this.levels[start - 1].groupPath;
930
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
931
- const currentData: any[] = LevelsData.levelsData[start][currentPath] as any[];
932
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
933
- const previousData: any[] = LevelsData.levelsData[start - 1][prevPath] as any[];
934
- for (let i: number = 0; i < currentData.length; i++) {
935
- currentName = currentData[i]['levelOrderName'] as string;
936
- for (let j: number = 0; j < previousData.length; j++) {
937
- previousData[j][currentPath] = isNullOrUndefined(previousData[j][currentPath]) ? [] : previousData[j][currentPath];
938
- if (this.IsChildHierarchy(currentName.split('#'), (previousData[j]['levelOrderName'] as string).split('#'))) {
939
- if (isNullOrUndefined(currentData[i]['parent'])) {
940
- currentData[i]['parent'] = previousData[j];
941
- }
942
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
943
- (<any[]>previousData[j][currentPath]).push(currentData[i]);
944
- break;
945
- }
946
- }
947
- }
948
- this.findTotalWeight(LevelsData.levelsData[LevelsData.levelsData.length - 1][currentPath], 'Child');
949
- LevelsData.levelsData.splice(start, 1);
950
- if ((start - 1) > 0) {
951
- this.reOrderLevelData(start - 1);
952
- }
953
- }
954
-
955
- private IsChildHierarchy (current: string[], previous: string[]): boolean {
956
- let isChild: boolean = false;
957
- for (let i: number = 0; i < previous.length; i++)
958
- {
959
- if (current.length < i || previous[i] !== current[i])
960
- {
961
- return false;
962
- }
963
- else
964
- {
965
- isChild = true;
966
- }
967
- }
968
- return isChild;
969
- }
970
-
971
- /**
972
- * This method finds the weight value of the treemap level.
973
- *
974
- * @param processData - Specifies the treemap data.
975
- * @param type - Specifies the type of the data.
976
- */
977
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
978
- public findTotalWeight(processData: any[], type: string): void {
979
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
980
- let totalWeight: number; const childData: any[] = [];
981
- let levelName: string; const start: number = 0; let split: string[];
982
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
983
- let groupName: string; const groupObj: any = {};
984
- for (let i: number = 0; i < processData.length; i++) {
985
- totalWeight = 0;
986
- groupName = processData[i]['groupName'];
987
- split = (processData[i]['levelOrderName'] as string).split('#');
988
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
989
- (<any[]>this.dataSource).forEach((data: any) => {
990
- if (isContainsData(split, processData[i]['levelOrderName'], data, this)) {
991
- totalWeight += parseFloat(data[this.weightValuePath]);
992
- }
993
- });
994
- if (type === 'Parent') {
995
- groupObj[groupName] = processData;
996
- processData[i]['parent'] = groupObj;
997
- }
998
- processData[i]['weight'] = totalWeight;
999
- }
1000
- }
1001
-
1002
- /**
1003
- * To unbind event handlers for treemap.
1004
- *
1005
- * @returns {void}
1006
- */
1007
- private unWireEVents(): void {
1008
- EventHandler.remove(this.element, 'click', this.clickOnTreeMap);
1009
- EventHandler.remove(this.element, 'dblclick', this.doubleClickOnTreeMap);
1010
- EventHandler.remove(this.element, 'contextmenu', this.rightClickOnTreeMap);
1011
- EventHandler.remove(this.element, Browser.touchStartEvent, this.mouseDownOnTreeMap);
1012
- EventHandler.remove(this.element, Browser.touchMoveEvent, this.mouseMoveOnTreeMap);
1013
- EventHandler.remove(this.element, Browser.touchEndEvent, this.mouseEndOnTreeMap);
1014
- EventHandler.remove(this.element, 'pointerleave mouseleave', this.mouseLeaveOnTreeMap);
1015
- window.removeEventListener('resize', this.resizeOnTreeMap);
1016
- }
1017
-
1018
- /**
1019
- * To bind event handlers for treemap.
1020
- *
1021
- * @returns {void}
1022
- */
1023
- private wireEVents(): void {
1024
- EventHandler.add(this.element, 'click', this.clickOnTreeMap, this);
1025
- EventHandler.add(this.element, 'dblclick', this.doubleClickOnTreeMap, this);
1026
- EventHandler.add(this.element, 'contextmenu', this.rightClickOnTreeMap, this);
1027
- EventHandler.add(this.element, Browser.touchStartEvent, this.mouseDownOnTreeMap, this);
1028
- EventHandler.add(this.element, Browser.touchMoveEvent, this.mouseMoveOnTreeMap, this);
1029
- EventHandler.add(this.element, Browser.touchEndEvent, this.mouseEndOnTreeMap, this);
1030
- EventHandler.add(this.element, 'pointerleave mouseleave', this.mouseLeaveOnTreeMap, this);
1031
- window.addEventListener('resize', this.resizeOnTreeMap.bind(this));
1032
- }
1033
-
1034
- /**
1035
- * Method to set culture for maps
1036
- *
1037
- * @returns {void}
1038
- */
1039
- private setCulture(): void {
1040
- this.intl = new Internationalization();
1041
- }
1042
-
1043
- /**
1044
- * To add tab index for treemap element
1045
- *
1046
- * @returns {void}
1047
- */
1048
- private addTabIndex(): void {
1049
- this.element.setAttribute('aria-label', this.description || 'TreeMap Element');
1050
- this.element.setAttribute('tabindex', this.tabIndex.toString());
1051
- }
1052
-
1053
- /**
1054
- * This method handles the window resize event on treemap.
1055
- *
1056
- * @param e - Specifies the pointer event.
1057
- */
1058
- public resizeOnTreeMap(e: Event): void {
1059
- this.isResize = true;
1060
- let args: IResizeEventArgs = {
1061
- name: resize,
1062
- cancel: false,
1063
- previousSize: this.availableSize,
1064
- currentSize: new Size(0, 0),
1065
- treemap: this
1066
- };
1067
- if (this.resizeTo) {
1068
- clearTimeout(this.resizeTo);
1069
- }
1070
- if (!isNullOrUndefined(this.element) && this.element.classList.contains('e-treemap')) {
1071
- this.resizeTo = setTimeout(
1072
- (): void => {
1073
- this.unWireEVents();
1074
- this.createSvg();
1075
- this.refreshing = true;
1076
- this.wireEVents();
1077
- args.currentSize = this.availableSize;
1078
- this.trigger(resize, args, (observedArgs: IResizeEventArgs) => {
1079
- this.render();
1080
- });
1081
- },
1082
- 500);
1083
- }
1084
- }
1085
-
1086
- /**
1087
- * This method handles the click event on the treemap.
1088
- *
1089
- * @param e - Specifies the mouse click event in the treemap.
1090
- */
1091
- public clickOnTreeMap(e: PointerEvent): void {
1092
- const targetEle: Element = <Element>e.target;
1093
- const targetId: string = targetEle.id;
1094
- let eventArgs: IItemClickEventArgs;
1095
- let itemIndex: number;
1096
- const labelText : string = targetEle.innerHTML;
1097
- const clickArgs: IClickEventArgs = { cancel: false, name: click, treemap: this, mouseEvent: e };
1098
- this.trigger(click, clickArgs);
1099
- if (targetId.indexOf('_Item_Index') > -1) {
1100
- e.preventDefault();
1101
- itemIndex = parseFloat(targetId.split('_Item_Index_')[1]);
1102
- eventArgs = {
1103
- cancel: false, name: itemClick, treemap: this, item: this.layout.renderItems[itemIndex], mouseEvent: e,
1104
- groupIndex: this.layout.renderItems[itemIndex]['groupIndex'], groupName: this.layout.renderItems[itemIndex]['name'],
1105
- text: labelText, contentItemTemplate : labelText
1106
- };
1107
- this.trigger(itemClick, eventArgs, (observedArgs: IItemClickEventArgs) => {
1108
- if (observedArgs.text !== labelText || observedArgs.contentItemTemplate !== labelText) {
1109
- if (isNullOrUndefined(this.leafItemSettings.labelTemplate)) {
1110
- observedArgs.text = textFormatter(observedArgs.text, observedArgs['item']['data'], observedArgs.treemap);
1111
- targetEle.innerHTML = observedArgs.text;
1112
- } else {
1113
- setItemTemplateContent(targetId, targetEle, observedArgs.contentItemTemplate);
1114
- }
1115
- }
1116
- });
1117
- }
1118
- const end: number = new Date().getMilliseconds();
1119
- let doubleTapTimer1: number;
1120
- if (!isNullOrUndefined(this.doubleClick)) {
1121
- if (!isNullOrUndefined(doubleTapTimer1) && end - doubleTapTimer1 < 500) {
1122
- this.doubleClickOnTreeMap(e);
1123
- }
1124
- doubleTapTimer1 = end;
1125
- }
1126
-
1127
- }
1128
-
1129
- /**
1130
- * This method handles the double click event in the treemap.
1131
- *
1132
- * @param e - Specifies the pointer event of mouse click.
1133
- */
1134
- public doubleClickOnTreeMap(e: PointerEvent): void {
1135
- const doubleClickArgs: IDoubleClickEventArgs = { cancel: false, name: doubleClick, treemap: this, mouseEvent: e };
1136
- this.trigger(doubleClick, doubleClickArgs);
1137
- //this.notify('dblclick', e);
1138
- }
1139
-
1140
- /**
1141
- * This method handles the right click event in the treemap.
1142
- *
1143
- * @param e - Specifies the pointer event of mouse click.
1144
- */
1145
- public rightClickOnTreeMap(e: PointerEvent): void {
1146
- const rightClickArgs: IRightClickEventArgs = { cancel: false, name: rightClick, treemap: this, mouseEvent: e };
1147
- this.trigger(rightClick, rightClickArgs);
1148
- }
1149
-
1150
-
1151
- /**
1152
- * This method handles the mouse down event in the treemap.
1153
- *
1154
- * @param e - Specifies the pointer event of mouse click.
1155
- */
1156
- public mouseDownOnTreeMap(e: PointerEvent): void {
1157
- if ((<Element>e.target).id.indexOf('_Item_Index') > -1) {
1158
- this.mouseDown = true;
1159
- }
1160
- this.notify(Browser.touchStartEvent, e);
1161
- }
1162
-
1163
- /**
1164
- * This method handles the mouse move event in the treemap.
1165
- *
1166
- * @param e - Specifies the pointer event of mouse click.
1167
- */
1168
- public mouseMoveOnTreeMap(e: PointerEvent): void {
1169
- const targetEle: Element = <Element>e.target;
1170
- const targetId: string = targetEle.id;
1171
- let eventArgs: IItemMoveEventArgs;
1172
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1173
- let item: any;
1174
- const moveArgs: IMouseMoveEventArgs = { cancel: false, name: mouseMove, treemap: this, mouseEvent: e };
1175
- this.trigger(mouseMove, moveArgs);
1176
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1177
- let childItems: any[];
1178
- if (targetId.indexOf('_Item_Index') > -1) {
1179
- item = this.layout.renderItems[parseFloat(targetId.split('_Item_Index_')[1])];
1180
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1181
- childItems = findChildren(item)['values'] as any[];
1182
- this.element.style.cursor = (!item['isLeafItem'] && childItems && childItems.length > 0 && this.enableDrillDown) ?
1183
- 'pointer' : 'auto';
1184
- eventArgs = { cancel: false, name: itemMove, treemap: this, item: item, mouseEvent: e };
1185
- this.trigger(itemMove, eventArgs);
1186
- }
1187
- this.notify(Browser.touchMoveEvent, e);
1188
- }
1189
-
1190
- /**
1191
- * This method calculates the selected treemap levels.
1192
- *
1193
- * @param labelText - Specifies the label text.
1194
- * @param item - Specifies the treemap item.
1195
- */
1196
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1197
- public calculateSelectedTextLevels(labelText: string, item: any): any {
1198
- //to find the levels by clicking the particular text both for drillDownView as true / false.
1199
- let drillLevel: number; let k: string; let text: String;
1200
- const levelLabels: string = item['levelOrderName'];
1201
- const levelText: string[] = levelLabels.split('#');
1202
- for (k of Object.keys(levelText)) {
1203
- if (levelText[k] === labelText) {
1204
- drillLevel = parseInt(k, 10);
1205
- text = labelText;
1206
- }
1207
- }
1208
- return { drillLevel: drillLevel, currentLevelLabel: text, levelText: levelText };
1209
- }
1210
-
1211
- /**
1212
- * This method calculates the previous level of child items in treemap.
1213
- *
1214
- * @param labelText - Specifies the label text in treemap
1215
- * @param drillLevelValues - Specifies the values of drill level.
1216
- * @param item - Specifies the treemap item.
1217
- * @param directLevel - Specifies the current level.
1218
- */
1219
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1220
- public calculatePreviousLevelChildItems(labelText: string, drillLevelValues: any, item: any, directLevel: boolean): boolean {
1221
- //By clicking any child items drilldown to the particular level.
1222
- //At the time store all the previous drilled level items in drilledItems
1223
- // This condition satisfies while drilldown View is set as false and the text contains '[+]'
1224
- let text: string; let p: number = 0; let levelItems: string; let text1: string;
1225
- const drillTextLevel: number = this.layout.renderItems[0]['levelOrderName'].split('#').length;
1226
- for (let h: number = 0; h < drillTextLevel; h++) {
1227
- text1 = h === 0 ? drillLevelValues['levelText'][h] : text1 + '#' + drillLevelValues['levelText'][h];
1228
- }
1229
- p = drillTextLevel > 1 ? drillTextLevel : p;
1230
- for (levelItems of Object['values'](this.layout.renderItems)) {
1231
- const drillLevelText: string = levelItems['levelOrderName'].split('#');
1232
- if (drillLevelText[0] === drillLevelValues['levelText'][0]) {
1233
- text = p === 0 ? isNullOrUndefined(text1) ? text1 : drillLevelValues['levelText'][p] :
1234
- directLevel ? text1 : text1 + '#' + drillLevelValues['levelText'][p];
1235
- if (text === levelItems['levelOrderName']) {
1236
- this.drilledItems.push({ name: levelItems['levelOrderName'], data: levelItems });
1237
- p++;
1238
- directLevel = true;
1239
- if (p <= item['groupIndex']) {
1240
- text = text + '#' + drillLevelValues['levelText'][p];
1241
- text1 = text;
1242
- }
1243
- }
1244
- }
1245
- }
1246
- return directLevel;
1247
- }
1248
-
1249
- /**
1250
- * This method compares the selected labels with the drill down items.
1251
- *
1252
- * @param drillLevelValues - Specifies the values of drill level.
1253
- * @param item - Specifies the treemap item.
1254
- * @param i - Specifies the treemap item.
1255
- */
1256
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1257
- public compareSelectedLabelWithDrillDownItems(drillLevelValues: any, item: any, i: number): any {
1258
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1259
- let drillLevelChild: any; const newDrillItem: any = {};
1260
- const b: number = drillLevelValues['drillLevel'] + 1;
1261
- if (b === this.drilledItems[i]['data']['groupIndex']) {
1262
- drillLevelChild = this.drilledItems[i]['data']['parent'];
1263
- drillLevelChild['isDrilled'] = true;
1264
- newDrillItem[drillLevelChild[this.drilledItems[i]['data']['groupName']]]
1265
- = [drillLevelChild];
1266
- // to remove all the items after matched drilled items
1267
- this.drilledItems.splice(i, this.drilledItems.length);
1268
- } else if (drillLevelValues['drillLevel'] === (this.drilledItems.length - 1)
1269
- || drillLevelValues['drillLevel'] === item['groupIndex']) {
1270
- newDrillItem[item['groupName']] = [item];
1271
- }
1272
- return newDrillItem;
1273
- }
1274
-
1275
- /**
1276
- * This method handles mouse end event in treemap.
1277
- *
1278
- * @param e - Specifies the pointer event of mouse.
1279
- */
1280
- public mouseEndOnTreeMap(e: PointerEvent): void {
1281
- const targetEle: Element = <Element>e.target; const targetId: string = targetEle.id; let totalRect: Rect;
1282
- let startEvent: IDrillStartEventArgs; let endEvent: IDrillEndEventArgs; let directLevel: boolean = false;
1283
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1284
- let index: number; let newDrillItem: any = {}; let item: any; const process: boolean = true;
1285
- const layoutID: string = this.element.id + '_TreeMap_' + this.layoutType + '_Layout'; let drillLevel: number;
1286
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1287
- const templateID: string = this.element.id + '_Label_Template_Group'; let drillLevelValues: any;
1288
- if (targetId.indexOf('_Item_Index') > -1 && this.enableDrillDown && !this.drillMouseMove) {
1289
- if (e.cancelable) {
1290
- e.preventDefault();
1291
- }
1292
- index = parseFloat(targetId.split('_Item_Index_')[1]);
1293
- item = this.layout.renderItems[index];
1294
- const labelText: string = targetEle.innerHTML;
1295
- if (this.enableBreadcrumb) {
1296
- drillLevelValues = this.calculateSelectedTextLevels(labelText, item);
1297
- drillLevel = drillLevelValues['drillLevel'];
1298
- if (!this.drillDownView && labelText.search('[+]') !== -1) {
1299
- directLevel = this.calculatePreviousLevelChildItems(labelText, drillLevelValues, item, directLevel);
1300
- }
1301
- }
1302
- if (this.levels.length !== 0 && !item['isLeafItem'] && findChildren(item)['values'] &&
1303
- findChildren(item)['values'].length > 0) {
1304
- if (this.drilledItems.length > 0) {
1305
- item = directLevel ? this.drilledItems[this.drilledItems.length - 1]['data'] : item;
1306
- for (let i: number = 0; i < this.drilledItems.length; i++) {
1307
- if (!isNullOrUndefined(drillLevel)) { //Compare the selected text level with drilled items
1308
- const drillLength: number = this.drilledItems.length;
1309
- newDrillItem = this.compareSelectedLabelWithDrillDownItems(drillLevelValues, item, i);
1310
- if (drillLength !== this.drilledItems.length) {
1311
- i -= 1; break;
1312
- }
1313
- } //when clicking the levels drill back to the previous level process takes place
1314
- if (item['levelOrderName'] === this.drilledItems[i]['name'] && !directLevel && isNullOrUndefined(drillLevel)) {
1315
- if (item['groupIndex'] === 0 && item['parent'][item['groupName']] instanceof Array) {
1316
- item['isDrilled'] = !(item['isDrilled']);
1317
- if (!item['isDrilled']) {
1318
- newDrillItem = item['parent'];
1319
- } else {
1320
- newDrillItem[item['groupName']] = [item];
1321
- }
1322
- } else {
1323
- item['isDrilled'] = false; item['parent']['isDrilled'] = true; item = item['parent'];
1324
- newDrillItem[item['groupName']] = [item];
1325
- }
1326
- this.drilledItems.splice(i, 1);
1327
- i -= 1; break;
1328
- } else if (i === this.drilledItems.length - 1 && isNullOrUndefined(drillLevel)) {
1329
- item['isDrilled'] = true; // click the items move to next level.
1330
- newDrillItem[item['groupName']] = [item];
1331
- }
1332
- }
1333
- } else {
1334
- item['isDrilled'] = true;
1335
- newDrillItem[item['groupName']] = [item];
1336
- }
1337
- startEvent = {
1338
- cancel: false, name: drillStart, treemap: this,
1339
- element: targetEle, groupIndex: this.enableBreadcrumb &&
1340
- this.drilledItems.length !== 0 && !isNullOrUndefined(drillLevel) ?
1341
- this.drilledItems[this.drilledItems.length - 1]['data']['groupIndex'] : item['groupIndex'],
1342
- groupName: this.enableBreadcrumb && this.drilledItems.length !== 0 && !isNullOrUndefined(drillLevel) ?
1343
- this.drilledItems[this.drilledItems.length - 1]['data']['name'] : item['name'],
1344
- rightClick: e.which === 3 ? true : false, childItems: null, item: newDrillItem
1345
- };
1346
- this.trigger(drillStart, startEvent, (observedArgs: IDrillStartEventArgs) => {
1347
- this.currentLevel = item['isDrilled'] && isNullOrUndefined(drillLevel) ? item['groupIndex'] :
1348
- (!isNullOrUndefined(drillLevel) && this.enableBreadcrumb && item['isDrilled']) ? drillLevel : null;
1349
- if (!observedArgs.cancel) {
1350
- if (document.getElementById(layoutID)) {
1351
- const layerElementId: HTMLElement = document.getElementById(layoutID);
1352
- layerElementId.parentNode.removeChild(layerElementId);
1353
- }
1354
- totalRect = extend({}, this.areaRect, totalRect, true) as Rect;
1355
- if (this.legendSettings.visible && !isNullOrUndefined(this.treeMapLegendModule)) {
1356
- if (!isNullOrUndefined(newDrillItem)) {
1357
- this.treeMapLegendModule.legendGroup.textContent = ''; this.treeMapLegendModule.legendGroup = null;
1358
- this.treeMapLegendModule.widthIncrement = 0; this.treeMapLegendModule.heightIncrement = 0;
1359
- if (this.enableBreadcrumb && !isNullOrUndefined(drillLevel)) {
1360
- this.drilledLegendItems = {
1361
- name: this.drilledItems[this.drilledItems.length - 1]['data']['levelOrderName'],
1362
- data: this.drilledItems[this.drilledItems.length - 1]['data']
1363
- };
1364
- } else {
1365
- this.drilledLegendItems = { name: item['levelOrderName'], data: item };
1366
- }
1367
- this.treeMapLegendModule.renderLegend();
1368
- }
1369
- totalRect = !isNullOrUndefined(this.totalRect) ? this.totalRect : totalRect;
1370
- }
1371
- if (document.getElementById(templateID)) {
1372
- const drillElementId: HTMLElement = document.getElementById(templateID);
1373
- drillElementId.parentNode.removeChild(drillElementId);
1374
- }
1375
- if (!isNullOrUndefined(observedArgs.childItems) && !observedArgs.cancel) {
1376
- this.layout.onDemandProcess(observedArgs.childItems);
1377
- } else {
1378
- this.layout.calculateLayoutItems(newDrillItem, totalRect);
1379
- this.layout.renderLayoutItems(newDrillItem);
1380
- }
1381
- }
1382
- });
1383
- endEvent = { cancel: false, name: drillEnd, treemap: this, renderItems: this.layout.renderItems };
1384
- this.trigger(drillEnd, endEvent);
1385
- if (process) {
1386
- if (!directLevel && isNullOrUndefined(drillLevel)) {
1387
- this.drilledItems.push({ name: item['levelOrderName'], data: item });
1388
- }
1389
- }
1390
- }
1391
- }
1392
- this.mouseDown = false;
1393
- this.notify(Browser.touchEndEvent, e);
1394
- }
1395
-
1396
- /**
1397
- * This method handles mouse leave event in treemap.
1398
- *
1399
- * @param e - Specifies the pointer event of mouse.
1400
- */
1401
- public mouseLeaveOnTreeMap(e: PointerEvent): void {
1402
- if (this.treeMapTooltipModule) {
1403
- this.treeMapTooltipModule.removeTooltip();
1404
- }
1405
- if (this.treeMapLegendModule) {
1406
- this.treeMapLegendModule.removeInteractivePointer();
1407
- }
1408
- removeClassNames(document.getElementsByClassName('treeMapHighLight'), 'treeMapHighLight', this);
1409
- if (this.treeMapHighlightModule) {
1410
- removeShape(this.treeMapHighlightModule.shapeHighlightCollection, 'highlight');
1411
- this.treeMapHighlightModule.highLightId = '';
1412
- }
1413
- }
1414
-
1415
- /**
1416
- * This method is used to select or remove the selection of treemap item based on the provided selection settings.
1417
- */
1418
- public selectItem(levelOrder: string[], isSelected ?: boolean): void {
1419
- if (isNullOrUndefined(isSelected)) {
1420
- isSelected = true;
1421
- }
1422
- let levelOrderName: string = '';
1423
- for (let i: number = 0; i < levelOrder.length; i++) {
1424
- if (i !== levelOrder.length - 1) {
1425
- levelOrderName += levelOrder[i] + '#';
1426
- } else {
1427
- levelOrderName += levelOrder[i];
1428
- }
1429
- }
1430
- if (this.treeMapSelectionModule && this.selectionSettings.enable) {
1431
- this.treeMapSelectionModule.selectTreemapItem(levelOrderName, isSelected);
1432
- }
1433
- }
1434
-
1435
-
1436
- /**
1437
- * To provide the array of modules needed for maps rendering
1438
- *
1439
- * @returns {ModuleDeclaration[]} Returns the modules
1440
- * @private
1441
- */
1442
- public requiredModules(): ModuleDeclaration[] {
1443
- const modules: ModuleDeclaration[] = [];
1444
- if (this.tooltipSettings.visible) {
1445
- modules.push({
1446
- member: 'treeMapTooltip',
1447
- args: [this]
1448
- });
1449
- }
1450
- if (this.highlightSettings.enable) {
1451
- modules.push({
1452
- member: 'treeMapHighlight',
1453
- args: [this]
1454
- });
1455
- }
1456
- if (this.selectionSettings.enable) {
1457
- modules.push({
1458
- member: 'treeMapSelection',
1459
- args: [this]
1460
- });
1461
- }
1462
- if (this.legendSettings.visible) {
1463
- modules.push({
1464
- member: 'treeMapLegend',
1465
- args: [this]
1466
- });
1467
- }
1468
- if (this.allowPrint) {
1469
- modules.push({
1470
- member: 'Print',
1471
- args: [this, Print]
1472
- });
1473
- }
1474
- if (this.allowImageExport) {
1475
- modules.push({
1476
- member: 'ImageExport',
1477
- args: [this, ImageExport]
1478
- });
1479
- }
1480
- if (this.allowPdfExport) {
1481
- modules.push({
1482
- member: 'PdfExport',
1483
- args: [this, PdfExport]
1484
- });
1485
- }
1486
- return modules;
1487
- }
1488
-
1489
- /**
1490
- * Called internally if any of the property value changed.
1491
- *
1492
- * @param {TreeMapModel} newProp - Specifies the new property
1493
- * @param {TreeMapModel} oldProp - Specifies the old property
1494
- * @returns {void}
1495
- * @private
1496
- */
1497
- public onPropertyChanged(newProp: TreeMapModel, oldProp: TreeMapModel): void {
1498
- let render: boolean = false;
1499
- for (const prop of Object.keys(newProp)) {
1500
- switch (prop) {
1501
- case 'background':
1502
- this.renderBorder();
1503
- break;
1504
- case 'height':
1505
- case 'width':
1506
- case 'layoutType':
1507
- case 'levels':
1508
- case 'drillDownView':
1509
- case 'renderDirection':
1510
- case 'leafItemSettings':
1511
- case 'legendSettings':
1512
- case 'dataSource':
1513
- render = true;
1514
- break;
1515
- }
1516
- }
1517
- if (render) {
1518
- this.createSvg();
1519
- this.renderElements();
1520
- }
1521
- }
1522
-
1523
- /**
1524
- * Gets component name.
1525
- */
1526
- public getModuleName(): string {
1527
- return 'treemap';
1528
- }
1529
-
1530
- /**
1531
- * This method is used to dispose the treemap component.
1532
- */
1533
- public destroy(): void {
1534
- this.unWireEVents();
1535
- this.drilledItems = [];
1536
- this.levelSelection = [];
1537
- this.legendId = [];
1538
- this.removeSvg();
1539
- super.destroy();
1540
- }
1541
-
1542
- private removeSvg(): void {
1543
- removeElement(this.element.id + '_Secondary_Element');
1544
- if (this.svgObject) {
1545
- while (this.svgObject.childNodes.length > 0) {
1546
- this.svgObject.removeChild(this.svgObject.firstChild);
1547
- }
1548
- if (!this.svgObject.hasChildNodes() && this.svgObject.parentNode) {
1549
- remove(this.svgObject);
1550
- }
1551
- }
1552
- }
1553
-
1554
- /**
1555
- * Get the properties to be maintained in the persisted state.
1556
- *
1557
- * @returns {string} - Returns the string value.
1558
- * @private
1559
- */
1560
- public getPersistData(): string {
1561
- return '';
1562
- }
1563
- }
1564
-
1565
- /**
1566
- * @private
1567
- */
1568
- export class LevelsData {
1569
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1570
- public static levelsData : any[];
1571
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1572
- public static defaultLevelsData : any[];
1573
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1574
- public static hierarchyData : any[];
1575
- }