@syncfusion/ej2-treemap 20.1.47 → 20.2.36
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.
- package/dist/ej2-treemap.umd.min.js +2 -2
- package/dist/ej2-treemap.umd.min.js.map +1 -1
- package/dist/es6/ej2-treemap.es2015.js +37 -31
- package/dist/es6/ej2-treemap.es2015.js.map +1 -1
- package/dist/es6/ej2-treemap.es5.js +37 -31
- package/dist/es6/ej2-treemap.es5.js.map +1 -1
- package/dist/global/ej2-treemap.min.js +2 -2
- package/dist/global/ej2-treemap.min.js.map +1 -1
- package/dist/global/index.d.ts +1 -1
- package/dist/ts/treemap/layout/legend.ts +991 -0
- package/dist/ts/treemap/layout/render-panel.ts +722 -0
- package/dist/ts/treemap/model/base.ts +800 -0
- package/dist/ts/treemap/model/constants.ts +118 -0
- package/dist/ts/treemap/model/image-export.ts +109 -0
- package/dist/ts/treemap/model/interface.ts +554 -0
- package/dist/ts/treemap/model/pdf-export.ts +103 -0
- package/dist/ts/treemap/model/print.ts +93 -0
- package/dist/ts/treemap/model/theme.ts +202 -0
- package/dist/ts/treemap/treemap.ts +1575 -0
- package/dist/ts/treemap/user-interaction/highlight-selection.ts +530 -0
- package/dist/ts/treemap/user-interaction/tooltip.ts +203 -0
- package/dist/ts/treemap/utils/enum.ts +222 -0
- package/dist/ts/treemap/utils/helper.ts +1181 -0
- package/package.json +11 -11
- package/src/treemap/layout/legend.js +1 -1
- package/src/treemap/layout/render-panel.js +17 -12
- package/src/treemap/treemap.js +5 -4
- package/src/treemap/user-interaction/highlight-selection.js +12 -12
- package/src/treemap/user-interaction/tooltip.js +1 -1
- package/src/treemap/utils/helper.js +1 -1
|
@@ -0,0 +1,991 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
|
2
|
+
/* eslint-disable @typescript-eslint/dot-notation */
|
|
3
|
+
/* eslint-disable max-len */
|
|
4
|
+
import { TreeMap, LevelsData } from '../treemap';
|
|
5
|
+
import { LegendSettingsModel, ColorMappingModel, LevelSettingsModel } from '../model/base-model';
|
|
6
|
+
import { LeafItemSettingsModel, FontModel, BorderModel } from '../model/base-model';
|
|
7
|
+
import {
|
|
8
|
+
findChildren, Location, Rect, Size, measureText,
|
|
9
|
+
TextOption, PathOption, RectOption, drawSymbol, orderByArea, legendMaintain
|
|
10
|
+
} from '../utils/helper';
|
|
11
|
+
import { Browser, isNullOrUndefined, EventHandler, extend } from '@syncfusion/ej2-base';
|
|
12
|
+
import { SvgRenderer, GradientColor, LinearGradient } from '@syncfusion/ej2-svg-base';
|
|
13
|
+
import { renderTextElement, textTrim } from '../utils/helper';
|
|
14
|
+
import { ILegendItemRenderingEventArgs, ILegendRenderingEventArgs } from '../model/interface';
|
|
15
|
+
import { LegendMode, LegendPosition, LegendOrientation, LabelPlacement, LabelIntersectAction } from '../utils/enum';
|
|
16
|
+
import { legendItemRendering, legendRendering } from '../model/constants';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Legend module class
|
|
20
|
+
*/
|
|
21
|
+
export class TreeMapLegend {
|
|
22
|
+
private treemap: TreeMap;
|
|
23
|
+
/** collection of rendering legends */
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
25
|
+
public legendRenderingCollections: any[];
|
|
26
|
+
/** collection of legends */
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
28
|
+
public legendCollections: any[];
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
30
|
+
public outOfRangeLegend: any;
|
|
31
|
+
private legendHeight: number;
|
|
32
|
+
private legendWidth: number;
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
34
|
+
private totalPages: any[];
|
|
35
|
+
private page: number = 0;
|
|
36
|
+
private translate: Location;
|
|
37
|
+
public legendBorderRect: Rect = new Rect(0, 0, 0, 0);
|
|
38
|
+
private currentPage: number = 0;
|
|
39
|
+
public heightIncrement: number = 0;
|
|
40
|
+
public widthIncrement: number = 0;
|
|
41
|
+
private textMaxWidth: number = 0;
|
|
42
|
+
/** group of legend */
|
|
43
|
+
public legendGroup: Element;
|
|
44
|
+
private legendNames: string[];
|
|
45
|
+
private defsElement: Element;
|
|
46
|
+
private gradientCount: number;
|
|
47
|
+
private legendLinearGradient: Element;
|
|
48
|
+
private legendInteractiveGradient: Element[] = [];
|
|
49
|
+
private clearTimeout: number;
|
|
50
|
+
private legendItemRect: Rect = new Rect(0, 0, 0, 0);
|
|
51
|
+
// eslint-disable-next-line @typescript-eslint/explicit-member-accessibility
|
|
52
|
+
constructor(treemap: TreeMap) {
|
|
53
|
+
this.treemap = treemap;
|
|
54
|
+
this.addEventListener();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// eslint-disable-next-line valid-jsdoc
|
|
58
|
+
/**
|
|
59
|
+
* method for legend
|
|
60
|
+
*/
|
|
61
|
+
public renderLegend(): void {
|
|
62
|
+
this.legendRenderingCollections = [];
|
|
63
|
+
this.legendCollections = [];
|
|
64
|
+
this.legendNames = [];
|
|
65
|
+
this.totalPages = [];
|
|
66
|
+
this.gradientCount = 1;
|
|
67
|
+
this.widthIncrement = 0;
|
|
68
|
+
this.heightIncrement = 0;
|
|
69
|
+
this.defsElement = this.treemap.renderer.createDefs();
|
|
70
|
+
this.treemap.svgObject.appendChild(this.defsElement);
|
|
71
|
+
let eventArgs: ILegendRenderingEventArgs;
|
|
72
|
+
eventArgs = {
|
|
73
|
+
cancel: false, name: legendRendering, treemap: this.treemap, _changePosition: this.treemap.legendSettings.position,
|
|
74
|
+
position: this.treemap.legendSettings.position
|
|
75
|
+
};
|
|
76
|
+
this.treemap.trigger(legendRendering, eventArgs, (observedArgs: ILegendRenderingEventArgs) => {
|
|
77
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
78
|
+
if (!observedArgs.cancel && observedArgs._changePosition !== this.treemap.legendSettings.position) {
|
|
79
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
80
|
+
this.treemap.legendSettings.position = observedArgs._changePosition;
|
|
81
|
+
}
|
|
82
|
+
this.calculateLegendBounds();
|
|
83
|
+
if (this.legendCollections.length > 0) {
|
|
84
|
+
this.drawLegend();
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
}
|
|
89
|
+
public calculateLegendBounds(): void {
|
|
90
|
+
const treemap: TreeMap = this.treemap;
|
|
91
|
+
const legend: LegendSettingsModel = treemap.legendSettings;
|
|
92
|
+
this.findColorMappingLegendItems(LevelsData.levelsData[0]);
|
|
93
|
+
if ((this.treemap.palette.length > 0 || !isNullOrUndefined(this.treemap.colorValuePath))
|
|
94
|
+
&& this.legendCollections.length === 0) {
|
|
95
|
+
this.findPaletteLegendItems(LevelsData.levelsData[0], 'Parent');
|
|
96
|
+
}
|
|
97
|
+
if (this.legendCollections.length > 0) {
|
|
98
|
+
const defaultSize: number = 25; const textPadding: number = 10; const position: LegendPosition = legend.position;
|
|
99
|
+
const legendTitle: string = legend.title.text; const titleTextStyle: FontModel = legend.titleStyle;
|
|
100
|
+
const legendMode: LegendMode = legend.mode; let shapeX: number = 0; let shapeY: number = 0;
|
|
101
|
+
let textX: number = 0; let textY: number = 0; const shapeHeight: number = legend.shapeHeight;
|
|
102
|
+
const shapeWidth: number = legend.shapeWidth; let shapeLocation: Location[] = []; let textLocation: Rect[] = [];
|
|
103
|
+
const orientation: LegendOrientation = (legend.orientation === 'None') ? ((position === 'Top' || position === 'Bottom'
|
|
104
|
+
|| (position === 'Auto' && treemap.availableSize.width <= treemap.availableSize.height))
|
|
105
|
+
? 'Horizontal' : 'Vertical') : legend.orientation;
|
|
106
|
+
const leftPadding: number = 10; const topPadding: number = 10; const spacing: number = 10;
|
|
107
|
+
let legendWidth: number = (legend.width.length > 1) ? (legend.width.indexOf('%') > -1) ? (treemap.availableSize.width / 100)
|
|
108
|
+
* parseFloat(legend.width) : parseFloat(legend.width) : null;
|
|
109
|
+
let legendHeight: number = (legend.height.length > 1) ? (legend.height.indexOf('%') > -1) ?
|
|
110
|
+
(treemap.availableSize.height / 100) * parseFloat(legend.height) : parseFloat(legend.height) : null;
|
|
111
|
+
titleTextStyle.fontFamily = treemap.themeStyle.fontFamily || titleTextStyle.fontFamily;
|
|
112
|
+
titleTextStyle.size = treemap.themeStyle.legendFontSize || titleTextStyle.size;
|
|
113
|
+
const legendTitleSize: Size = measureText(legendTitle, titleTextStyle);
|
|
114
|
+
let startX: number = 0; let startY: number = 0; const shapePadding: number = legend.shapePadding;
|
|
115
|
+
let rectWidth: number; let rectHeight: number; const itemTextStyle: FontModel = legend.textStyle;
|
|
116
|
+
const legendLength: number = this.legendCollections.length;
|
|
117
|
+
legend.textStyle.size = treemap.themeStyle.legendFontSize || legend.textStyle.size;
|
|
118
|
+
legend.textStyle.fontFamily = treemap.themeStyle.fontFamily || legend.textStyle.fontFamily;
|
|
119
|
+
if (legendMode === 'Default') {
|
|
120
|
+
legendWidth = (isNullOrUndefined(legendWidth)) ? treemap.areaRect.width : legendWidth;
|
|
121
|
+
legendHeight = (isNullOrUndefined(legendHeight)) ? treemap.areaRect.height : legendHeight;
|
|
122
|
+
let j: number = 0;
|
|
123
|
+
for (let i: number = 0; i < this.legendCollections.length; i++) {
|
|
124
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
125
|
+
const legendItem: any = this.legendCollections[i];
|
|
126
|
+
if (isNullOrUndefined(this.totalPages[this.page])) {
|
|
127
|
+
this.totalPages[this.page] = { Page: (this.page + 1), Collection: [] };
|
|
128
|
+
}
|
|
129
|
+
const legendTextSize: Size = measureText(legendItem['legendName'], legend.textStyle);
|
|
130
|
+
this.textMaxWidth = Math.max(this.textMaxWidth, legendTextSize.width);
|
|
131
|
+
if (i === 0) {
|
|
132
|
+
startX = shapeX = (leftPadding + (shapeWidth / 2));
|
|
133
|
+
startY = shapeY = topPadding + legendTitleSize.height + (shapeHeight > legendTextSize.height ? shapeHeight / 2
|
|
134
|
+
: (legendTextSize.height / 4));
|
|
135
|
+
} else {
|
|
136
|
+
const maxSize: number = (legendTextSize.height > shapeHeight) ? legendTextSize.height : shapeHeight;
|
|
137
|
+
if (orientation === 'Horizontal') {
|
|
138
|
+
const prvePositionX: number = (textLocation[j - 1].x + textLocation[j - 1].width) + textPadding + shapeWidth;
|
|
139
|
+
if ((prvePositionX + shapePadding + legendTextSize.width) > legendWidth) {
|
|
140
|
+
const nextPositionY: number = (textLocation[j - 1].y > (shapeLocation[j - 1].y + (shapeHeight / 2)) ?
|
|
141
|
+
textLocation[j - 1].y : (shapeLocation[j - 1].y + (shapeHeight / 2))) + topPadding;
|
|
142
|
+
if ((nextPositionY + maxSize) > legendHeight) {
|
|
143
|
+
this.getPageChanged();
|
|
144
|
+
j = 0;
|
|
145
|
+
shapeLocation = [];
|
|
146
|
+
textLocation = [];
|
|
147
|
+
shapeX = startX;
|
|
148
|
+
shapeY = startY;
|
|
149
|
+
} else {
|
|
150
|
+
shapeX = (shapeLocation[0].x);
|
|
151
|
+
shapeY = (nextPositionY + (maxSize / 2));
|
|
152
|
+
}
|
|
153
|
+
} else {
|
|
154
|
+
shapeX = (prvePositionX - (shapeWidth / 2));
|
|
155
|
+
shapeY = (shapeLocation[j - 1]).y;
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
const prevPositionY: number = textLocation[j - 1].y > shapeLocation[j - 1].y + (shapeHeight / 2) ?
|
|
159
|
+
textLocation[j - 1].y : shapeLocation[j - 1].y + (shapeHeight / 2);
|
|
160
|
+
if ((prevPositionY + topPadding + maxSize) > legendHeight) {
|
|
161
|
+
const nextPositionX: number = (textLocation[j - 1].x + this.textMaxWidth + textPadding);
|
|
162
|
+
if ((nextPositionX + shapePadding + legendTextSize.width) > legendWidth) {
|
|
163
|
+
shapeX = startX;
|
|
164
|
+
shapeY = startY;
|
|
165
|
+
textLocation = [];
|
|
166
|
+
shapeLocation = [];
|
|
167
|
+
this.getPageChanged();
|
|
168
|
+
j = 0;
|
|
169
|
+
} else {
|
|
170
|
+
shapeX = nextPositionX + (shapeWidth / 2);
|
|
171
|
+
shapeY = (shapeLocation[0].y);
|
|
172
|
+
}
|
|
173
|
+
} else {
|
|
174
|
+
shapeX = shapeLocation[j - 1].x;
|
|
175
|
+
shapeY = prevPositionY + topPadding + (shapeHeight / 2);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
textX = shapeX + (shapeWidth / 2) + shapePadding;
|
|
180
|
+
textY = shapeY + (legendTextSize.height / 4);
|
|
181
|
+
shapeLocation.push({ x: shapeX, y: shapeY });
|
|
182
|
+
textLocation.push({ x: textX, y: textY, width: legendTextSize.width, height: (legendTextSize.height / 2) });
|
|
183
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
184
|
+
(<any[]>this.totalPages[this.page]['Collection']).push({
|
|
185
|
+
DisplayText: legendItem['legendName'], element: legendItem['gradientElement'],
|
|
186
|
+
Shape: { x: shapeX, y: shapeY },
|
|
187
|
+
Text: { x: textX, y: textY },
|
|
188
|
+
Fill: legendItem['legendFill'],
|
|
189
|
+
Data: legendItem['legendData'],
|
|
190
|
+
Rect: {
|
|
191
|
+
x: shapeLocation[j].x - (shapeWidth / 2),
|
|
192
|
+
y: (shapeLocation[j].y - (shapeHeight / 2)) < (textY - legendTextSize.height) ?
|
|
193
|
+
(shapeLocation[j].y - (shapeHeight / 2)) : (textY - legendTextSize.height),
|
|
194
|
+
width: Math.abs((shapeLocation[j].x - (shapeWidth / 2)) - (textX + legendTextSize.width)),
|
|
195
|
+
height: ((shapeHeight > legendTextSize.height) ? shapeHeight : legendTextSize.height)
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
j++;
|
|
199
|
+
}
|
|
200
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
201
|
+
const collection: any[] = (<any[]>this.totalPages[0]['Collection']);
|
|
202
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
203
|
+
collection.forEach((legendObj: any, index: number) => {
|
|
204
|
+
const legendRect: Rect = new Rect(
|
|
205
|
+
legendObj['Rect']['x'], legendObj['Rect']['y'],
|
|
206
|
+
legendObj['Rect']['width'], legendObj['Rect']['height']
|
|
207
|
+
);
|
|
208
|
+
if (index === 0) {
|
|
209
|
+
startX = legendRect.x;
|
|
210
|
+
startY = legendRect.y;
|
|
211
|
+
}
|
|
212
|
+
this.widthIncrement = Math.max(this.widthIncrement, Math.abs(startX - (legendRect.x + legendRect.width)));
|
|
213
|
+
this.heightIncrement = Math.max(this.heightIncrement, Math.abs(startY - (legendRect.y + legendRect.height)));
|
|
214
|
+
});
|
|
215
|
+
legendWidth = ((this.widthIncrement < legendWidth) ? this.widthIncrement : legendWidth);
|
|
216
|
+
legendHeight = ((this.heightIncrement < legendHeight) ? this.heightIncrement : legendHeight);
|
|
217
|
+
this.legendItemRect = {
|
|
218
|
+
x: collection[0]['Rect']['x'], y: collection[0]['Rect']['y'],
|
|
219
|
+
width: legendWidth, height: legendHeight
|
|
220
|
+
};
|
|
221
|
+
} else {
|
|
222
|
+
const itemTextStyle: FontModel = legend.textStyle;
|
|
223
|
+
const legendLength: number = this.legendCollections.length;
|
|
224
|
+
const rectWidth: number = (orientation === 'Horizontal') ? (isNullOrUndefined(legendWidth)) ? (treemap.areaRect.width / legendLength) :
|
|
225
|
+
(legendWidth / legendLength) : (isNullOrUndefined(legendWidth)) ? defaultSize : legendWidth;
|
|
226
|
+
const rectHeight: number = (orientation === 'Horizontal') ? (isNullOrUndefined(legendHeight)) ? defaultSize : legendHeight :
|
|
227
|
+
(isNullOrUndefined(legendHeight)) ? (treemap.areaRect.height / legendLength) : (legendHeight / legendLength);
|
|
228
|
+
startX = 0; startY = legendTitleSize.height + spacing;
|
|
229
|
+
const textPadding: number = 10; const placement: LabelPlacement = legend.labelPosition;
|
|
230
|
+
let itemStartX: number = 0; let itemStartY: number = 0;
|
|
231
|
+
const labelAction: LabelIntersectAction = legend.labelDisplayMode;
|
|
232
|
+
let maxTextHeight: number = 0; let maxTextWidth: number = 0;
|
|
233
|
+
for (let i: number = 0; i < this.legendCollections.length; i++) {
|
|
234
|
+
startX = (orientation === 'Horizontal') ? (startX + rectWidth) : startX;
|
|
235
|
+
startY = (orientation === 'Horizontal') ? startY : (startY + rectHeight);
|
|
236
|
+
let legendText: string = this.legendCollections[i]['legendName'];
|
|
237
|
+
let itemTextSize: Size = new Size(0, 0);
|
|
238
|
+
if (labelAction === 'None') {
|
|
239
|
+
itemTextSize = measureText(legendText, itemTextStyle);
|
|
240
|
+
} else if (labelAction === 'Trim') {
|
|
241
|
+
legendText = textTrim((orientation === 'Horizontal' ? rectWidth : rectHeight), legendText, itemTextStyle);
|
|
242
|
+
itemTextSize = measureText(legendText, itemTextStyle);
|
|
243
|
+
} else {
|
|
244
|
+
legendText = '';
|
|
245
|
+
}
|
|
246
|
+
maxTextHeight = Math.max(maxTextHeight, itemTextSize.height);
|
|
247
|
+
maxTextWidth = Math.max(maxTextWidth, itemTextSize.width);
|
|
248
|
+
if (itemTextSize.width > 0 && itemTextSize.height > 0) {
|
|
249
|
+
if (orientation === 'Horizontal') {
|
|
250
|
+
textX = startX + (rectWidth / 2);
|
|
251
|
+
textY = (placement === 'After') ? (startY + rectHeight + (itemTextSize.height / 2)) + textPadding :
|
|
252
|
+
(startY - textPadding);
|
|
253
|
+
} else {
|
|
254
|
+
textX = (placement === 'After') ? startX - (itemTextSize.width / 2) - textPadding
|
|
255
|
+
: (startX + rectWidth + itemTextSize.width / 2) + textPadding;
|
|
256
|
+
textY = startY + (rectHeight / 2) + (itemTextSize.height / 4);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
if (i === 0) {
|
|
260
|
+
itemStartX = (orientation === 'Horizontal') ? startX : (placement === 'After') ?
|
|
261
|
+
textX - (itemTextSize.width / 2) : startX;
|
|
262
|
+
itemStartY = (orientation === 'Horizontal') ? (placement === 'After') ? startY :
|
|
263
|
+
textY - (itemTextSize.height / 2) : startY;
|
|
264
|
+
}
|
|
265
|
+
if (i === legendLength - 1) {
|
|
266
|
+
legendWidth = (orientation === 'Horizontal') ? Math.abs((startX + rectWidth) - itemStartX) :
|
|
267
|
+
(rectWidth + maxTextWidth + textPadding);
|
|
268
|
+
legendHeight = (orientation === 'Horizontal') ? (rectHeight + (maxTextHeight / 2) + textPadding) :
|
|
269
|
+
Math.abs((startY + rectHeight) - itemStartY);
|
|
270
|
+
}
|
|
271
|
+
this.legendRenderingCollections.push({
|
|
272
|
+
fill: this.legendCollections[i]['legendFill'], x: startX, y: startY,
|
|
273
|
+
width: rectWidth, height: rectHeight, element: this.legendCollections[i]['gradientElement'],
|
|
274
|
+
text: legendText, textX: textX, textY: textY,
|
|
275
|
+
textWidth: itemTextSize.width, textHeight: itemTextSize.height,
|
|
276
|
+
data: this.legendCollections[i]['legendData']
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
this.legendItemRect = { x: itemStartX, y: itemStartY, width: legendWidth, height: legendHeight };
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
private getPageChanged(): void {
|
|
285
|
+
this.page++;
|
|
286
|
+
if (isNullOrUndefined(this.totalPages[this.page])) {
|
|
287
|
+
this.totalPages[this.page] = { Page: (this.page + 1), Collection: [] };
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
292
|
+
private findColorMappingLegendItems(data: any): void {
|
|
293
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
294
|
+
const child: any[] = findChildren(data)['values'];
|
|
295
|
+
if (child && child.length > 0) {
|
|
296
|
+
this.calculateLegendItems(child);
|
|
297
|
+
if (this.treemap.levels.length > 0) {
|
|
298
|
+
for (let i: number = 0; i < child.length; i++) {
|
|
299
|
+
this.findColorMappingLegendItems(child[i]);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
306
|
+
private findPaletteLegendItems(data: any, type: string): void {
|
|
307
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
308
|
+
let child: any[]; let legendFillColor: string;
|
|
309
|
+
if (!isNullOrUndefined(this.treemap.drilledItems)) {
|
|
310
|
+
if (this.treemap.drilledItems.length === 0 && !isNullOrUndefined(this.treemap.initialDrillDown.groupName)
|
|
311
|
+
&& isNullOrUndefined(this.treemap.drilledLegendItems)) {
|
|
312
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
313
|
+
const items: any[] = findChildren(data)['values'];
|
|
314
|
+
for (let k: number = 0; k < items.length; k++) {
|
|
315
|
+
if (items[k]['Name'] === this.treemap.initialDrillDown.groupName) {
|
|
316
|
+
items[k]['isDrilled'] = !items[k]['isDrilled'];
|
|
317
|
+
data = items[k];
|
|
318
|
+
this.treemap.currentLevel = this.treemap.initialDrillDown.groupIndex;
|
|
319
|
+
legendFillColor = this.treemap.palette.length > 0 ? this.treemap.palette[k % this.treemap.palette.length] :
|
|
320
|
+
items[k]['data'][this.treemap.colorValuePath];
|
|
321
|
+
break;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
if (this.treemap.enableDrillDown && !isNullOrUndefined(this.treemap.drilledLegendItems)) {
|
|
327
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
328
|
+
const childElement: any = this.treemap.drilledLegendItems;
|
|
329
|
+
legendFillColor = childElement['data']['options']['fill'];
|
|
330
|
+
if (childElement['data']['isDrilled']) {
|
|
331
|
+
child = findChildren(childElement['data'])['values'];
|
|
332
|
+
} else {
|
|
333
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
334
|
+
const parentElement: any = childElement['data']['parent'];
|
|
335
|
+
child = findChildren(parentElement)['values'];
|
|
336
|
+
}
|
|
337
|
+
} else {
|
|
338
|
+
child = findChildren(data)['values'];
|
|
339
|
+
}
|
|
340
|
+
let isDuplicate: boolean;
|
|
341
|
+
let legendName: string;
|
|
342
|
+
if (child && child.length > 0) {
|
|
343
|
+
for (let i: number = 0; i < child.length; i++) {
|
|
344
|
+
if (isNullOrUndefined(child[i]['data'][this.treemap.legendSettings.showLegendPath]) ||
|
|
345
|
+
child[i]['data'][this.treemap.legendSettings.showLegendPath]) {
|
|
346
|
+
legendName = child[i]['data'][this.treemap.legendSettings.valuePath] ?
|
|
347
|
+
child[i]['data'][this.treemap.legendSettings.valuePath] : child[i]['name'];
|
|
348
|
+
isDuplicate = this.treemap.legendSettings.removeDuplicateLegend ?
|
|
349
|
+
this.removeDuplicates(this.legendCollections, legendName) : false;
|
|
350
|
+
if (!isDuplicate) {
|
|
351
|
+
this.legendCollections.push({
|
|
352
|
+
legendName: legendName,
|
|
353
|
+
legendFill: this.treemap.palette.length > 0 ? !isNullOrUndefined(this.treemap.currentLevel)
|
|
354
|
+
? legendFillColor : this.treemap.palette[i % this.treemap.palette.length] :
|
|
355
|
+
child[i]['data'][this.treemap.colorValuePath],
|
|
356
|
+
legendData: [],
|
|
357
|
+
itemArea: child[i]['weight']
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
this.legendCollections.sort(orderByArea);
|
|
363
|
+
if (this.treemap.palette.length > 0) {
|
|
364
|
+
for (let j: number = 0; j < this.legendCollections.length; j++) {
|
|
365
|
+
this.legendCollections[j]['legendFill'] = !isNullOrUndefined(this.treemap.currentLevel)
|
|
366
|
+
? legendFillColor : this.treemap.palette[j % this.treemap.palette.length];
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
373
|
+
private calculateLegendItems(data: any[]): void {
|
|
374
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
375
|
+
let isAddData: any; let fill: string; let rangeValue: number;
|
|
376
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
377
|
+
let currentData: any; let legendText: string; let itemValue: number;
|
|
378
|
+
let isLeafItem: boolean; let colorMapProcess: boolean = false;
|
|
379
|
+
let colorMapping: ColorMappingModel[]; let groupIndex: number;
|
|
380
|
+
const leaf: LeafItemSettingsModel = this.treemap.leafItemSettings;
|
|
381
|
+
const levels: LevelSettingsModel[] = this.treemap.levels; let equalValue: string;
|
|
382
|
+
const position: LegendPosition = this.treemap.legendSettings.position;
|
|
383
|
+
let gradientElement: Element; let x2: string; let y2: string; let actualValue: string;
|
|
384
|
+
let isDuplicate: boolean; let isEqualColor: boolean; let isRange: boolean; let isDesaturation: boolean = false;
|
|
385
|
+
let legendIndex: number = 0; let outfill: string; let labelLegend: string; let otherIndex: number;
|
|
386
|
+
this.outOfRangeLegend = null;
|
|
387
|
+
for (let i: number = 0; i < data.length; i++) {
|
|
388
|
+
fill = ''; isEqualColor = false; isRange = false; isDesaturation = false;
|
|
389
|
+
currentData = data[i]['data'];
|
|
390
|
+
groupIndex = data[i]['groupIndex'];
|
|
391
|
+
isLeafItem = (this.treemap.levels.length === 0 || groupIndex === this.treemap.levels.length);
|
|
392
|
+
colorMapping = isLeafItem ? leaf.colorMapping : levels[groupIndex].colorMapping;
|
|
393
|
+
for (const colorMap of colorMapping) {
|
|
394
|
+
gradientElement = null;
|
|
395
|
+
rangeValue = Number(currentData[this.treemap.rangeColorValuePath]);
|
|
396
|
+
equalValue = currentData[this.treemap.equalColorValuePath];
|
|
397
|
+
colorMap.value = !isNullOrUndefined(colorMap.value) ? colorMap.value.toString() : colorMap.value;
|
|
398
|
+
if (!isNullOrUndefined(colorMap.from) && !isNullOrUndefined(colorMap.to) &&
|
|
399
|
+
rangeValue >= colorMap.from && rangeValue <= colorMap.to && colorMap.showLegend) {
|
|
400
|
+
colorMapProcess = true; isRange = true;
|
|
401
|
+
actualValue = colorMap.from + ' - ' + colorMap.to;
|
|
402
|
+
legendText = !isNullOrUndefined(colorMap.label) ? colorMap.label : colorMap.from + ' - ' + colorMap.to;
|
|
403
|
+
fill = isNullOrUndefined(colorMap.color) ? fill : <string>colorMap.color;
|
|
404
|
+
isAddData = this.isAddNewLegendData(actualValue);
|
|
405
|
+
} else if (!isNullOrUndefined(colorMap.value) && equalValue === colorMap.value && colorMap.showLegend) {
|
|
406
|
+
colorMapProcess = true; isEqualColor = true;
|
|
407
|
+
actualValue = colorMap.value.toString();
|
|
408
|
+
legendText = !isNullOrUndefined(colorMap.label) ? colorMap.label : colorMap.value.toString();
|
|
409
|
+
fill = isNullOrUndefined(colorMap.color) ? fill :
|
|
410
|
+
Object.prototype.toString.call(colorMap.color) === '[object Array]' ? colorMap.color[0] : <string>colorMap.color;
|
|
411
|
+
isAddData = this.isAddNewLegendData(actualValue);
|
|
412
|
+
}
|
|
413
|
+
if (colorMapProcess && isNullOrUndefined(colorMap.value) && colorMap.maxOpacity && colorMap.minOpacity
|
|
414
|
+
&& this.treemap.legendSettings.mode === 'Interactive') {
|
|
415
|
+
const colors: GradientColor[] = []; isDesaturation = true;
|
|
416
|
+
if (Object.prototype.toString.call(colorMap.color) === '[object Array]') {
|
|
417
|
+
for (let q: number = 0; q < colorMap.color.length; q++) {
|
|
418
|
+
const offsetColor: number = 100 / (colorMap.color.length - 1);
|
|
419
|
+
const offsetValue: string = q * offsetColor + '%';
|
|
420
|
+
const stop1Color: GradientColor = { colorStop: offsetValue.toString(), color: colorMap.color[q] };
|
|
421
|
+
colors.push(stop1Color);
|
|
422
|
+
}
|
|
423
|
+
} else {
|
|
424
|
+
const stop1Color: GradientColor = { colorStop: '0%', color: fill };
|
|
425
|
+
const stop2Color: GradientColor = { colorStop: '100%', color: fill };
|
|
426
|
+
colors.push(stop1Color);
|
|
427
|
+
colors.push(stop2Color);
|
|
428
|
+
}
|
|
429
|
+
x2 = position === 'Top' || position === 'Bottom' ? '100%' : '0%';
|
|
430
|
+
y2 = position === 'Top' || position === 'Bottom' ? '0%' : '100%';
|
|
431
|
+
const gradient: LinearGradient = {
|
|
432
|
+
id: 'groupIndex_' + groupIndex + '_colorIndex_' + this.gradientCount, x1: '0%', y1: '0%', x2: x2, y2: y2
|
|
433
|
+
};
|
|
434
|
+
gradientElement = this.treemap.renderer.drawGradient('linearGradient', gradient, colors).childNodes[0] as Element;
|
|
435
|
+
if (Object.prototype.toString.call(colorMap.color) !== '[object Array]') {
|
|
436
|
+
(gradientElement.childNodes[0] as Element).setAttribute('stop-opacity', colorMap.minOpacity.toString());
|
|
437
|
+
(gradientElement.childNodes[1] as Element).setAttribute('stop-opacity', colorMap.maxOpacity.toString());
|
|
438
|
+
}
|
|
439
|
+
this.defsElement.appendChild(gradientElement);
|
|
440
|
+
this.gradientCount++;
|
|
441
|
+
}
|
|
442
|
+
isDuplicate = this.treemap.legendSettings.removeDuplicateLegend ?
|
|
443
|
+
this.removeDuplicates(this.legendCollections, legendText) : false;
|
|
444
|
+
if (isAddData && isAddData['process'] && colorMapProcess && !isDuplicate) {
|
|
445
|
+
colorMapProcess = false;
|
|
446
|
+
fill = ((Object.prototype.toString.call(colorMap.color) === '[object Array]')) && isNullOrUndefined(gradientElement)
|
|
447
|
+
&& isNullOrUndefined(colorMap.value) ? this.legendGradientColor(colorMap, legendIndex) : fill;
|
|
448
|
+
this.legendCollections.push({
|
|
449
|
+
actualValue: actualValue,
|
|
450
|
+
legendName: legendText, legendFill: fill, legendData: [],
|
|
451
|
+
gradientElement: !isNullOrUndefined(gradientElement) ? gradientElement : isNullOrUndefined(colorMap.value)
|
|
452
|
+
? this.legendLinearGradient : null, name: data[i]['name'],
|
|
453
|
+
opacity: this.treemap.legendSettings.opacity, borderColor: this.treemap.legendSettings.border.color,
|
|
454
|
+
borderWidth: this.treemap.legendSettings.border.width
|
|
455
|
+
});
|
|
456
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
457
|
+
(<any[]>this.legendCollections[this.legendCollections.length - 1]['legendData']).push(data[i]);
|
|
458
|
+
legendIndex++;
|
|
459
|
+
} else if (colorMapProcess && !isDuplicate) {
|
|
460
|
+
colorMapProcess = false;
|
|
461
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
462
|
+
(<any[]>this.legendCollections[isAddData['value']]['legendData']).push(data[i]);
|
|
463
|
+
}
|
|
464
|
+
if (!isRange && !isDesaturation && !isEqualColor) {
|
|
465
|
+
if (isNullOrUndefined(colorMap.from) && isNullOrUndefined(colorMap.to)
|
|
466
|
+
&& isNullOrUndefined(colorMap.minOpacity) &&
|
|
467
|
+
isNullOrUndefined(colorMap.maxOpacity) && isNullOrUndefined(colorMap.value) &&
|
|
468
|
+
!isNullOrUndefined(colorMap.color)) {
|
|
469
|
+
outfill = ((Object.prototype.toString.call(colorMap.color) === '[object Array]'))
|
|
470
|
+
? colorMap.color[0] : <string>colorMap.color;
|
|
471
|
+
labelLegend = !isNullOrUndefined(colorMap.label) ? colorMap.label : 'Others';
|
|
472
|
+
if (isNullOrUndefined(this.outOfRangeLegend)) {
|
|
473
|
+
this.legendCollections.push({
|
|
474
|
+
actualValue: labelLegend, legendData: [],
|
|
475
|
+
legendName: labelLegend, legendFill: outfill
|
|
476
|
+
});
|
|
477
|
+
otherIndex = this.legendCollections.length;
|
|
478
|
+
this.outOfRangeLegend = this.legendCollections[otherIndex - 1];
|
|
479
|
+
legendIndex++;
|
|
480
|
+
|
|
481
|
+
}
|
|
482
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
483
|
+
(<any[]>this.legendCollections[otherIndex - 1]['legendData']).push(data[i]);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
491
|
+
private removeDuplicates(legendCollection: any[], text: string): boolean {
|
|
492
|
+
let isDuplicate: boolean = false;
|
|
493
|
+
for (let i: number = 0; i < legendCollection.length; i++) {
|
|
494
|
+
if (legendCollection[i]['legendName'] === text) {
|
|
495
|
+
isDuplicate = true;
|
|
496
|
+
break;
|
|
497
|
+
} else {
|
|
498
|
+
continue;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
return isDuplicate;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
506
|
+
private isAddNewLegendData(legendText: string): any {
|
|
507
|
+
let newDataProcess: boolean; let itemValue: number;
|
|
508
|
+
if (this.legendCollections.length === 0) {
|
|
509
|
+
newDataProcess = true;
|
|
510
|
+
} else {
|
|
511
|
+
for (let j: number = 0; j < this.legendCollections.length; j++) {
|
|
512
|
+
if (legendText === this.legendCollections[j]['actualValue']) {
|
|
513
|
+
newDataProcess = false;
|
|
514
|
+
itemValue = j;
|
|
515
|
+
break;
|
|
516
|
+
} else if (j === this.legendCollections.length - 1) {
|
|
517
|
+
newDataProcess = true;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
return { process: newDataProcess, value: itemValue };
|
|
522
|
+
}
|
|
523
|
+
// eslint-disable-next-line valid-jsdoc
|
|
524
|
+
/**
|
|
525
|
+
* To draw the legend
|
|
526
|
+
*/
|
|
527
|
+
public drawLegend(): void {
|
|
528
|
+
const treemap: TreeMap = this.treemap;
|
|
529
|
+
const legend: LegendSettingsModel = <LegendSettingsModel>treemap.legendSettings;
|
|
530
|
+
const render: SvgRenderer = treemap.renderer; let fill: string;
|
|
531
|
+
let textOptions: TextOption; let gradientElement: Element;
|
|
532
|
+
const textFont: FontModel = legend.textStyle;
|
|
533
|
+
this.legendGroup = render.createGroup({ id: treemap.element.id + '_Legend_Group' });
|
|
534
|
+
this.renderLegendBorder();
|
|
535
|
+
this.renderLegendTitle();
|
|
536
|
+
if (legend.mode === 'Default') {
|
|
537
|
+
this.drawLegendItem(this.currentPage);
|
|
538
|
+
} else {
|
|
539
|
+
for (let i: number = 0; i < this.legendRenderingCollections.length; i++) {
|
|
540
|
+
const itemId: string = treemap.element.id + '_Legend_Index_' + i;
|
|
541
|
+
const textId: string = treemap.element.id + '_Legend_Index_' + i + '_Text';
|
|
542
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
543
|
+
const item: any = this.legendRenderingCollections[i];
|
|
544
|
+
gradientElement = item['element'];
|
|
545
|
+
fill = gradientElement ? 'url(#' + gradientElement.id + ')' : item['fill'];
|
|
546
|
+
const bounds: Rect = new Rect(item['x'], item['y'], item['width'], item['height']);
|
|
547
|
+
const textLocation: Location = new Location(item['textX'], item['textY']);
|
|
548
|
+
|
|
549
|
+
const rectOptions: RectOption = new RectOption(itemId, fill, legend.shapeBorder, legend.opacity, bounds);
|
|
550
|
+
if (this.treemap.enableRtl) {
|
|
551
|
+
if (treemap.legendSettings.position === 'Left' || treemap.legendSettings.position === 'Right'
|
|
552
|
+
|| (treemap.legendSettings.position === 'Auto'
|
|
553
|
+
&& this.treemap.availableSize.width >= this.treemap.availableSize.height)) {
|
|
554
|
+
rectOptions.y = (this.translate.y + this.legendBorderRect.y + this.legendBorderRect.height)
|
|
555
|
+
- (this.translate.y + rectOptions.height) - Math.abs(this.legendBorderRect.y - rectOptions.y);
|
|
556
|
+
textLocation.y = (this.translate.y + this.legendBorderRect.y + this.legendBorderRect.height)
|
|
557
|
+
- (this.translate.y) + (item['textHeight'] / 2)
|
|
558
|
+
- Math.abs(this.legendBorderRect.y - textLocation.y);
|
|
559
|
+
} else {
|
|
560
|
+
rectOptions.x = (this.translate.x + this.legendBorderRect.x + this.legendBorderRect.width)
|
|
561
|
+
- (this.translate.x + rectOptions.width)
|
|
562
|
+
- Math.abs(this.legendBorderRect.x - rectOptions.x);
|
|
563
|
+
textLocation.x = (this.translate.x + this.legendBorderRect.x + this.legendBorderRect.width)
|
|
564
|
+
- this.translate.x - Math.abs(this.legendBorderRect.x - textLocation.x);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
textOptions = new TextOption(textId, textLocation.x, textLocation.y, 'middle', item['text'], '', '');
|
|
568
|
+
renderTextElement(textOptions, textFont, textFont.color || this.treemap.themeStyle.legendTextColor, this.legendGroup);
|
|
569
|
+
this.legendGroup.appendChild(render.drawRectangle(rectOptions));
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
legendMaintain(this.treemap, this.legendGroup);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
576
|
+
private defaultLegendRtlLocation(collection: any, spacing: number, treemap: TreeMap, legend: LegendSettingsModel): any {
|
|
577
|
+
const shapeLocation: Location = collection['Shape'];
|
|
578
|
+
const textLocation: Location = collection['Text'];
|
|
579
|
+
const legendText: string = collection['DisplayText'];
|
|
580
|
+
const textSize: Size = measureText(legendText, legend.textStyle);
|
|
581
|
+
shapeLocation.x = (this.translate.x + this.legendBorderRect.x + this.legendBorderRect.width)
|
|
582
|
+
- (this.translate.x + spacing) - Math.abs(this.legendBorderRect.x - shapeLocation.x);
|
|
583
|
+
textLocation.x = (this.translate.x + this.legendBorderRect.x + this.legendBorderRect.width)
|
|
584
|
+
- (this.translate.x + textSize.width + spacing) - Math.abs(this.legendBorderRect.x - textLocation.x);
|
|
585
|
+
if (treemap.legendSettings.position === 'Left' || treemap.legendSettings.position === 'Right'
|
|
586
|
+
|| (treemap.legendSettings.position === 'Auto'
|
|
587
|
+
&& this.treemap.availableSize.width >= this.treemap.availableSize.height)) {
|
|
588
|
+
shapeLocation.y = (this.translate.y + this.legendBorderRect.y + this.legendBorderRect.height)
|
|
589
|
+
- this.translate.y - Math.abs(Math.abs(this.legendBorderRect.y) - shapeLocation.y) - (legend.shapeHeight / 2);
|
|
590
|
+
textLocation.y = (this.translate.y + this.legendBorderRect.y + this.legendBorderRect.height)
|
|
591
|
+
- this.translate.y - Math.abs(Math.abs(this.legendBorderRect.y) - textLocation.y);
|
|
592
|
+
}
|
|
593
|
+
return { shapeLocation: shapeLocation, textLocation: textLocation };
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
private drawLegendItem(page: number): void {
|
|
598
|
+
const treemap: TreeMap = this.treemap; const spacing: number = 10;
|
|
599
|
+
const legend: LegendSettingsModel = <LegendSettingsModel>treemap.legendSettings;
|
|
600
|
+
const shapeSize: Size = new Size(legend.shapeWidth, legend.shapeHeight);
|
|
601
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
602
|
+
let textOptions: TextOption; let legendRtlLocation: any;
|
|
603
|
+
let renderOptions: PathOption | RectOption; const render: SvgRenderer = treemap.renderer;
|
|
604
|
+
const shapeBorder: BorderModel = legend.shapeBorder; let eventArgs: ILegendItemRenderingEventArgs;
|
|
605
|
+
if (page >= 0 && page < this.totalPages.length) {
|
|
606
|
+
if (document.getElementById(this.legendGroup.id)) {
|
|
607
|
+
document.getElementById(this.legendGroup.id).remove();
|
|
608
|
+
}
|
|
609
|
+
const isLineShape: boolean = (legend.shape === 'HorizontalLine' || legend.shape === 'VerticalLine' || legend.shape === 'Cross');
|
|
610
|
+
const strokeColor: string = isLineShape ? isNullOrUndefined(legend.fill) ? '#000000' : legend.fill : shapeBorder.color;
|
|
611
|
+
const strokeWidth: number = isLineShape ? (shapeBorder.width === 0) ? 1 : shapeBorder.width : shapeBorder.width;
|
|
612
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
613
|
+
for (let i: number = 0; i < (<any[]>this.totalPages[page]['Collection']).length; i++) {
|
|
614
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
615
|
+
const collection: any = <any[]>this.totalPages[page]['Collection'][i];
|
|
616
|
+
const legendElement: Element = render.createGroup({ id: treemap.element.id + '_Legend_Index_' + i });
|
|
617
|
+
const legendText: string = collection['DisplayText'];
|
|
618
|
+
const shapeId: string = treemap.element.id + '_Legend_Shape_Index_' + i;
|
|
619
|
+
const textId: string = treemap.element.id + '_Legend_Text_Index_' + i;
|
|
620
|
+
let shapeLocation: Location = collection['Shape'];
|
|
621
|
+
let textLocation: Location = collection['Text'];
|
|
622
|
+
if (treemap.enableRtl) {
|
|
623
|
+
legendRtlLocation = this.defaultLegendRtlLocation(collection, spacing, treemap, legend);
|
|
624
|
+
shapeLocation = legendRtlLocation['shapeLocation'];
|
|
625
|
+
textLocation = legendRtlLocation['textLocation'];
|
|
626
|
+
}
|
|
627
|
+
eventArgs = {
|
|
628
|
+
cancel: false, name: legendItemRendering, treemap: treemap, fill: collection['Fill'],
|
|
629
|
+
shape: legend.shape, imageUrl: legend.imageUrl
|
|
630
|
+
};
|
|
631
|
+
this.treemap.trigger(legendItemRendering, eventArgs, (observedArgs: ILegendItemRenderingEventArgs) => {
|
|
632
|
+
const renderOptions: PathOption = new PathOption(
|
|
633
|
+
shapeId, observedArgs.fill, strokeWidth, isLineShape ? collection['Fill'] : strokeColor, legend.opacity, ''
|
|
634
|
+
);
|
|
635
|
+
legendElement.appendChild(
|
|
636
|
+
drawSymbol(shapeLocation, observedArgs.shape, shapeSize, observedArgs.imageUrl, renderOptions, legendText)
|
|
637
|
+
);
|
|
638
|
+
textOptions = new TextOption(textId, textLocation.x, textLocation.y, 'start', legendText, '', '');
|
|
639
|
+
renderTextElement(
|
|
640
|
+
textOptions, legend.textStyle, legend.textStyle.color || this.treemap.themeStyle.legendTextColor, legendElement
|
|
641
|
+
);
|
|
642
|
+
this.legendGroup.appendChild(legendElement);
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
let pagingGroup: Element; const width: number = spacing; const height: number = (spacing / 2);
|
|
646
|
+
if (this.page !== 0) {
|
|
647
|
+
const pagingText: string = (page + 1) + '/' + this.totalPages.length;
|
|
648
|
+
const pagingFont: FontModel = legend.textStyle; const pagingTextSize: Size = measureText(pagingText, pagingFont);
|
|
649
|
+
const leftPageX: number = (this.legendItemRect.x + this.legendItemRect.width) - pagingTextSize.width -
|
|
650
|
+
(width * 2) - spacing;
|
|
651
|
+
const rightPageX: number = (this.legendItemRect.x + this.legendItemRect.width);
|
|
652
|
+
const locY: number = (this.legendItemRect.y + this.legendItemRect.height) + (height / 2) + spacing;
|
|
653
|
+
const pageTextX: number = rightPageX - width - (pagingTextSize.width / 2) - (spacing / 2);
|
|
654
|
+
pagingGroup = render.createGroup({ id: treemap.element.id + '_Legend_Paging_Group' });
|
|
655
|
+
const leftPageElement: Element = render.createGroup({ id: treemap.element.id + '_Legend_Left_Paging_Group' });
|
|
656
|
+
const rightPageElement: Element = render.createGroup({ id: treemap.element.id + '_Legend_Right_Paging_Group' });
|
|
657
|
+
const rightPath: string = ' M ' + rightPageX + ' ' + locY + ' L ' + (rightPageX - width) + ' ' + (locY - height) +
|
|
658
|
+
' L ' + (rightPageX - width) + ' ' + (locY + height) + ' z ';
|
|
659
|
+
const leftPath: string = ' M ' + leftPageX + ' ' + locY + ' L ' + (leftPageX + width) + ' ' + (locY - height) +
|
|
660
|
+
' L ' + (leftPageX + width) + ' ' + (locY + height) + ' z ';
|
|
661
|
+
const leftPageOptions: PathOption = new PathOption(
|
|
662
|
+
treemap.element.id + '_Left_Page', '#a6a6a6', 0, '#a6a6a6', 1, '', leftPath
|
|
663
|
+
);
|
|
664
|
+
leftPageElement.appendChild(render.drawPath(leftPageOptions));
|
|
665
|
+
const leftRectPageOptions: RectOption = new RectOption(
|
|
666
|
+
treemap.element.id + '_Left_Page_Rect', 'transparent', {}, 1,
|
|
667
|
+
new Rect(leftPageX - (width / 2), (locY - (height * 2)), width * 2, spacing * 2), ''
|
|
668
|
+
);
|
|
669
|
+
leftPageElement.appendChild(render.drawRectangle(leftRectPageOptions));
|
|
670
|
+
this.wireEvents(leftPageElement);
|
|
671
|
+
const rightPageOptions: PathOption = new PathOption(
|
|
672
|
+
treemap.element.id + '_Right_Page', '#a6a6a6', 0, '#a6a6a6', 1, '', rightPath
|
|
673
|
+
);
|
|
674
|
+
rightPageElement.appendChild(render.drawPath(rightPageOptions));
|
|
675
|
+
const rightRectPageOptions: RectOption = new RectOption(
|
|
676
|
+
treemap.element.id + '_Right_Page_Rect', 'transparent', {}, 1,
|
|
677
|
+
new Rect((rightPageX - width), (locY - height), width, spacing), ''
|
|
678
|
+
);
|
|
679
|
+
rightPageElement.appendChild(render.drawRectangle(rightRectPageOptions));
|
|
680
|
+
this.wireEvents(rightPageElement);
|
|
681
|
+
pagingGroup.appendChild(leftPageElement);
|
|
682
|
+
pagingGroup.appendChild(rightPageElement);
|
|
683
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
684
|
+
const pageTextOptions: any = {
|
|
685
|
+
'id': treemap.element.id + '_Paging_Text',
|
|
686
|
+
'x': pageTextX,
|
|
687
|
+
'y': locY + (pagingTextSize.height / 4),
|
|
688
|
+
'fill': '#a6a6a6',
|
|
689
|
+
'font-size': '14px',
|
|
690
|
+
'font-style': pagingFont.fontStyle,
|
|
691
|
+
'font-family': pagingFont.fontFamily,
|
|
692
|
+
'font-weight': pagingFont.fontWeight,
|
|
693
|
+
'text-anchor': 'middle',
|
|
694
|
+
'transform': '',
|
|
695
|
+
'opacity': 1,
|
|
696
|
+
'dominant-baseline': ''
|
|
697
|
+
};
|
|
698
|
+
pagingGroup.appendChild(render.createText(pageTextOptions, pagingText));
|
|
699
|
+
this.legendGroup.appendChild(pagingGroup);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
private renderLegendBorder(): void {
|
|
704
|
+
const treemap: TreeMap = this.treemap;
|
|
705
|
+
const legend: LegendSettingsModel = <LegendSettingsModel>treemap.legendSettings;
|
|
706
|
+
const legendTitle: string = legend.title.text;
|
|
707
|
+
const spacing: number = 10;
|
|
708
|
+
const textStyle: FontModel = legend.titleStyle;
|
|
709
|
+
let textOptions: TextOption;
|
|
710
|
+
const title: string = textTrim((this.legendItemRect.width + (spacing * 2)), legendTitle, textStyle);
|
|
711
|
+
const textSize: Size = measureText(title, textStyle);
|
|
712
|
+
this.legendBorderRect = new Rect(
|
|
713
|
+
(this.legendItemRect.x - spacing),
|
|
714
|
+
(this.legendItemRect.y - spacing - textSize.height),
|
|
715
|
+
(this.legendItemRect.width) + (spacing * 2),
|
|
716
|
+
(this.legendItemRect.height) + (spacing * 2) + textSize.height +
|
|
717
|
+
(legend.mode === 'Interactive' ? 0 : (this.page !== 0) ? spacing : 0)
|
|
718
|
+
);
|
|
719
|
+
const renderOptions: RectOption = new RectOption(
|
|
720
|
+
treemap.element.id + '_Legend_Border', legend.background, legend.border, 1, this.legendBorderRect, ''
|
|
721
|
+
);
|
|
722
|
+
const legendBorder: Element = treemap.renderer.drawRectangle(renderOptions);
|
|
723
|
+
(legendBorder as HTMLElement).style.pointerEvents = 'none';
|
|
724
|
+
this.legendGroup.appendChild(legendBorder);
|
|
725
|
+
this.getLegendAlignment(treemap, this.legendBorderRect.width, this.legendBorderRect.height, legend);
|
|
726
|
+
this.legendGroup.setAttribute('transform', 'translate( ' + (this.translate.x + (-(this.legendBorderRect.x))) + ' ' +
|
|
727
|
+
(this.translate.y + (-(this.legendBorderRect.y))) + ' )');
|
|
728
|
+
treemap.svgObject.appendChild(this.legendGroup);
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
private renderLegendTitle(): void {
|
|
732
|
+
const treemap: TreeMap = this.treemap;
|
|
733
|
+
const legend: LegendSettingsModel = <LegendSettingsModel>treemap.legendSettings;
|
|
734
|
+
const textStyle: FontModel = legend.titleStyle; const legendTitle: string = legend.title.text;
|
|
735
|
+
let textOptions: TextOption; const spacing: number = 10;
|
|
736
|
+
const trimTitle: string = textTrim((this.legendItemRect.width + (spacing * 2)), legendTitle, textStyle);
|
|
737
|
+
const textSize: Size = measureText(trimTitle, textStyle);
|
|
738
|
+
if (legendTitle) {
|
|
739
|
+
textOptions = new TextOption(
|
|
740
|
+
treemap.element.id + '_LegendTitle',
|
|
741
|
+
(this.legendItemRect.x) + (this.legendItemRect.width / 2),
|
|
742
|
+
this.legendItemRect.y - (textSize.height / 2) - (spacing / 2),
|
|
743
|
+
'middle', trimTitle, '');
|
|
744
|
+
renderTextElement(textOptions, textStyle, textStyle.color || this.treemap.themeStyle.legendTitleColor, this.legendGroup);
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
// eslint-disable-next-line valid-jsdoc
|
|
748
|
+
/**
|
|
749
|
+
* To rendered the interactive pointer
|
|
750
|
+
*/
|
|
751
|
+
public renderInteractivePointer(e: PointerEvent | TouchEvent): void {
|
|
752
|
+
const treemap: TreeMap = this.treemap; let target: Element = <Element>e.target;
|
|
753
|
+
const interactiveId: string = treemap.element.id + '_Interactive_Legend';
|
|
754
|
+
target = !(e.type.indexOf('touch') > -1) ? target :
|
|
755
|
+
document.elementFromPoint((<TouchEvent>e).changedTouches[0].clientX, (<TouchEvent>e).changedTouches[0].clientY);
|
|
756
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
757
|
+
let targetItem: any; const legend: LegendSettingsModel = <LegendSettingsModel>treemap.legendSettings;
|
|
758
|
+
if (target.id.indexOf('_Item_Index') > -1 && legend.visible && this.legendRenderingCollections.length > 0) {
|
|
759
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
760
|
+
let currentData: any; let legendRect: ClientRect;
|
|
761
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
762
|
+
let rect: Rect; let data: any[]; let fill: string; let stroke: string; let strokeWidth: number; let legendElement: Element;
|
|
763
|
+
targetItem = treemap.layout.renderItems[parseFloat(target.id.split('_Item_Index_')[1])];
|
|
764
|
+
const svgRect: ClientRect = treemap.svgObject.getBoundingClientRect();
|
|
765
|
+
for (let i: number = 0; i < this.legendCollections.length; i++) {
|
|
766
|
+
currentData = this.legendCollections[i];
|
|
767
|
+
legendElement = document.getElementById(treemap.element.id + '_Legend_Index_' + i);
|
|
768
|
+
legendRect = <ClientRect>legendElement.getBoundingClientRect();
|
|
769
|
+
const rect: Rect = new Rect(
|
|
770
|
+
Math.abs(legendRect.left - svgRect.left), Math.abs(legendRect.top - svgRect.top),
|
|
771
|
+
legendRect.width, legendRect.height
|
|
772
|
+
);
|
|
773
|
+
fill = legendElement.getAttribute('fill');
|
|
774
|
+
stroke = legend.shapeBorder.color;
|
|
775
|
+
strokeWidth = legend.shapeBorder.width;
|
|
776
|
+
if (!isNullOrUndefined(currentData['legendData'])) {
|
|
777
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
778
|
+
data = <any[]>currentData['legendData'];
|
|
779
|
+
for (let j: number = 0; j < data.length; j++) {
|
|
780
|
+
if (data[j]['levelOrderName'] === targetItem['levelOrderName']) {
|
|
781
|
+
this.drawInteractivePointer(legend, fill, stroke, interactiveId, strokeWidth, rect);
|
|
782
|
+
break;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
} else {
|
|
788
|
+
this.removeInteractivePointer();
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
private drawInteractivePointer(
|
|
793
|
+
legend: LegendSettingsModel, fill: string, stroke: string, id: string, strokeWidth: number, rect: Rect
|
|
794
|
+
): void {
|
|
795
|
+
let path: string;
|
|
796
|
+
let locX: number; let locY: number;
|
|
797
|
+
const height: number = 10; const width: number = 10;
|
|
798
|
+
const direction: LegendOrientation = (legend.orientation === 'None') ? (legend.position === 'Top' || legend.position === 'Bottom')
|
|
799
|
+
? 'Horizontal' : 'Vertical' : legend.orientation;
|
|
800
|
+
if (direction === 'Horizontal') {
|
|
801
|
+
if (!legend.invertedPointer) {
|
|
802
|
+
locX = rect.x + (rect.width / 2);
|
|
803
|
+
locY = rect.y;
|
|
804
|
+
path = ' M ' + locX + ' ' + locY + ' L ' + (locX - width) + ' ' + (locY - height) +
|
|
805
|
+
' L ' + (locX + width) + ' ' + (locY - height) + ' Z ';
|
|
806
|
+
} else {
|
|
807
|
+
locX = rect.x + (rect.width / 2);
|
|
808
|
+
locY = rect.y + (rect.height);
|
|
809
|
+
path = ' M ' + locX + ' ' + locY + ' L ' + (locX - width) + ' ' + (locY + height) +
|
|
810
|
+
' L ' + (locX + width) + ' ' + (locY + height) + ' Z ';
|
|
811
|
+
}
|
|
812
|
+
} else {
|
|
813
|
+
if (!legend.invertedPointer) {
|
|
814
|
+
locX = rect.x + (rect.width);
|
|
815
|
+
locY = rect.y + (rect.height / 2);
|
|
816
|
+
path = ' M ' + locX + ' ' + locY + ' L ' + (locX + width) + ' ' + (locY - height) +
|
|
817
|
+
' L ' + (locX + width) + ' ' + (locY + height) + ' z ';
|
|
818
|
+
} else {
|
|
819
|
+
locX = rect.x;
|
|
820
|
+
locY = rect.y + (rect.height / 2);
|
|
821
|
+
path = ' M ' + locX + ' ' + locY + ' L ' + (locX - width) + ' ' + (locY - height) +
|
|
822
|
+
' L ' + (locX - width) + ' ' + (locY + height) + ' z ';
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
const pathOptions: PathOption = new PathOption(id, fill, strokeWidth, stroke, 1, '', path);
|
|
826
|
+
this.treemap.svgObject.appendChild(this.treemap.renderer.drawPath(pathOptions) as SVGPathElement);
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
|
|
830
|
+
private getLegendAlignment(treemap: TreeMap, width: number, height: number, legend: LegendSettingsModel): void {
|
|
831
|
+
let x: number; let y: number;
|
|
832
|
+
const spacing: number = 10; let totalRect: Rect;
|
|
833
|
+
// eslint-disable-next-line prefer-const
|
|
834
|
+
totalRect = extend({}, treemap.areaRect, totalRect, true) as Rect;
|
|
835
|
+
const areaX: number = totalRect.x;
|
|
836
|
+
const areaY: number = totalRect.y;
|
|
837
|
+
const areaHeight: number = totalRect.height;
|
|
838
|
+
const areaWidth: number = totalRect.width;
|
|
839
|
+
const totalWidth: number = treemap.availableSize.width;
|
|
840
|
+
const totalHeight: number = treemap.availableSize.height;
|
|
841
|
+
const position: string = legend.position === 'Auto' ? (totalWidth > totalHeight) ? 'Right' : 'Bottom' : legend.position;
|
|
842
|
+
if (legend.position === 'Float') {
|
|
843
|
+
this.translate = legend.location;
|
|
844
|
+
} else {
|
|
845
|
+
switch (position) {
|
|
846
|
+
case 'Top':
|
|
847
|
+
case 'Bottom':
|
|
848
|
+
totalRect.height = (areaHeight - height);
|
|
849
|
+
x = (totalWidth / 2) - (width / 2);
|
|
850
|
+
y = (position === 'Top') ? areaY : (areaY + totalRect.height) + spacing;
|
|
851
|
+
totalRect.y = (position === 'Top') ? areaY + height + spacing : areaY;
|
|
852
|
+
break;
|
|
853
|
+
case 'Left':
|
|
854
|
+
case 'Right':
|
|
855
|
+
totalRect.width = (areaWidth - width);
|
|
856
|
+
x = (position === 'Left') ? areaX : areaX + totalRect.width;
|
|
857
|
+
y = (totalHeight / 2) - (height / 2);
|
|
858
|
+
totalRect.x = (position === 'Left') ? areaX + width : areaX;
|
|
859
|
+
break;
|
|
860
|
+
}
|
|
861
|
+
switch (legend.alignment) {
|
|
862
|
+
case 'Near':
|
|
863
|
+
if (position === 'Top' || position === 'Bottom') {
|
|
864
|
+
x = totalRect.x;
|
|
865
|
+
} else {
|
|
866
|
+
y = totalRect.y;
|
|
867
|
+
}
|
|
868
|
+
break;
|
|
869
|
+
case 'Far':
|
|
870
|
+
if (position === 'Top' || position === 'Bottom') {
|
|
871
|
+
x = totalWidth - width;
|
|
872
|
+
} else {
|
|
873
|
+
y = totalHeight - height;
|
|
874
|
+
}
|
|
875
|
+
break;
|
|
876
|
+
}
|
|
877
|
+
this.treemap.totalRect = totalRect;
|
|
878
|
+
this.translate = new Location(x, y);
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
public mouseUpHandler(e: PointerEvent): void {
|
|
882
|
+
this.renderInteractivePointer(e);
|
|
883
|
+
clearTimeout(this.clearTimeout);
|
|
884
|
+
this.clearTimeout = setTimeout(this.removeInteractivePointer.bind(this), 3000);
|
|
885
|
+
}
|
|
886
|
+
// eslint-disable-next-line valid-jsdoc
|
|
887
|
+
/**
|
|
888
|
+
* To remove the interactive pointer
|
|
889
|
+
*/
|
|
890
|
+
public removeInteractivePointer(): void {
|
|
891
|
+
if (document.getElementById(this.treemap.element.id + '_Interactive_Legend')) {
|
|
892
|
+
const legendElementId: HTMLElement = document.getElementById(this.treemap.element.id + '_Interactive_Legend');
|
|
893
|
+
legendElementId.parentNode.removeChild(legendElementId);
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
// eslint-disable-next-line valid-jsdoc
|
|
897
|
+
/**
|
|
898
|
+
* To change the next page
|
|
899
|
+
*/
|
|
900
|
+
public changeNextPage(e: PointerEvent): void {
|
|
901
|
+
this.currentPage = ((<Element>e.target).id.indexOf('_Left_Page_') > -1) ? (this.currentPage - 1) :
|
|
902
|
+
(this.currentPage + 1);
|
|
903
|
+
this.drawLegend();
|
|
904
|
+
}
|
|
905
|
+
// eslint-disable-next-line valid-jsdoc
|
|
906
|
+
/**
|
|
907
|
+
* Wire events for event handler
|
|
908
|
+
*/
|
|
909
|
+
public wireEvents(element: Element): void {
|
|
910
|
+
EventHandler.add(element, Browser.touchStartEvent, this.changeNextPage, this);
|
|
911
|
+
}
|
|
912
|
+
// eslint-disable-next-line valid-jsdoc
|
|
913
|
+
/**
|
|
914
|
+
* To add the event listener
|
|
915
|
+
*/
|
|
916
|
+
public addEventListener(): void {
|
|
917
|
+
if (this.treemap.isDestroyed) {
|
|
918
|
+
return;
|
|
919
|
+
}
|
|
920
|
+
this.treemap.on(Browser.touchMoveEvent, this.renderInteractivePointer, this);
|
|
921
|
+
this.treemap.on(Browser.touchEndEvent, this.mouseUpHandler, this);
|
|
922
|
+
}
|
|
923
|
+
// eslint-disable-next-line valid-jsdoc
|
|
924
|
+
/**
|
|
925
|
+
* To remove the event listener
|
|
926
|
+
*/
|
|
927
|
+
public removeEventListener(): void {
|
|
928
|
+
if (this.treemap.isDestroyed) {
|
|
929
|
+
return;
|
|
930
|
+
}
|
|
931
|
+
this.treemap.off(Browser.touchMoveEvent, this.renderInteractivePointer);
|
|
932
|
+
this.treemap.off(Browser.touchEndEvent, this.mouseUpHandler);
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
// eslint-disable-next-line valid-jsdoc
|
|
936
|
+
/**
|
|
937
|
+
* Get module name.
|
|
938
|
+
*/
|
|
939
|
+
protected getModuleName(): string {
|
|
940
|
+
return 'treeMapLegend';
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
/**
|
|
944
|
+
* To destroy the legend.
|
|
945
|
+
*
|
|
946
|
+
* @param {TreeMap} treemap - Specifies treemap instance
|
|
947
|
+
* @returns {void}
|
|
948
|
+
* @private
|
|
949
|
+
*/
|
|
950
|
+
public destroy(treemap: TreeMap): void {
|
|
951
|
+
/**
|
|
952
|
+
* Destroy method performed here
|
|
953
|
+
*/
|
|
954
|
+
this.removeEventListener();
|
|
955
|
+
}
|
|
956
|
+
// eslint-disable-next-line valid-jsdoc
|
|
957
|
+
/**
|
|
958
|
+
* Get the gradient color for interactive legend.
|
|
959
|
+
*/
|
|
960
|
+
public legendGradientColor(colorMap: ColorMappingModel, legendIndex: number): string {
|
|
961
|
+
let legendFillColor: string;
|
|
962
|
+
const xmlns: string = 'http://www.w3.org/2000/svg';
|
|
963
|
+
if (!isNullOrUndefined(colorMap.color) && Object.prototype.toString.call(colorMap.color) === '[object Array]') {
|
|
964
|
+
const defElement: Element = this.treemap.renderer.createDefs();
|
|
965
|
+
const linerGradientEle: Element = document.createElementNS(xmlns, 'linearGradient');
|
|
966
|
+
const opacity: number = 1; const position: LegendPosition = this.treemap.legendSettings.position;
|
|
967
|
+
const x2: string = position === 'Top' || position === 'Bottom' ? '100' : '0';
|
|
968
|
+
const y2: string = position === 'Top' || position === 'Bottom' ? '0' : '100';
|
|
969
|
+
linerGradientEle.setAttribute('id', 'linear_' + legendIndex);
|
|
970
|
+
linerGradientEle.setAttribute('x1', 0 + '%');
|
|
971
|
+
linerGradientEle.setAttribute('y1', 0 + '%');
|
|
972
|
+
linerGradientEle.setAttribute('x2', x2 + '%');
|
|
973
|
+
linerGradientEle.setAttribute('y2', y2 + '%');
|
|
974
|
+
for (let b: number = 0; b < colorMap.color.length; b++) {
|
|
975
|
+
const offsetColor: number = 100 / (colorMap.color.length - 1);
|
|
976
|
+
const stopEle: Element = document.createElementNS(xmlns, 'stop');
|
|
977
|
+
stopEle.setAttribute('offset', b * offsetColor + '%');
|
|
978
|
+
stopEle.setAttribute('stop-color', colorMap.color[b]);
|
|
979
|
+
stopEle.setAttribute('stop-opacity', opacity.toString());
|
|
980
|
+
linerGradientEle.appendChild(stopEle);
|
|
981
|
+
}
|
|
982
|
+
defElement.appendChild(linerGradientEle);
|
|
983
|
+
this.legendLinearGradient = linerGradientEle;
|
|
984
|
+
const color: string = 'url(' + '#linear_' + legendIndex + ')';
|
|
985
|
+
this.defsElement.appendChild(linerGradientEle);
|
|
986
|
+
legendFillColor = color;
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
return legendFillColor;
|
|
990
|
+
}
|
|
991
|
+
}
|