1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | var tslib_1 = require("tslib");
|
4 | var util_1 = require("@antv/util");
|
5 | var constant_1 = require("../../constant");
|
6 | var dependents_1 = require("../../dependents");
|
7 | var animate_1 = require("../../animate");
|
8 | var bbox_1 = require("../../util/bbox");
|
9 | var direction_1 = require("../../util/direction");
|
10 | var helper_1 = require("../../util/helper");
|
11 | var legend_1 = require("../../util/legend");
|
12 | var scale_1 = require("../../util/scale");
|
13 | var base_1 = require("./base");
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 | function getLegendOption(legends, field) {
|
21 | if ((0, util_1.isBoolean)(legends)) {
|
22 | return legends === false ? false : {};
|
23 | }
|
24 | return (0, util_1.get)(legends, [field], legends);
|
25 | }
|
26 | function getDirection(legendOption) {
|
27 | return (0, util_1.get)(legendOption, 'position', constant_1.DIRECTION.BOTTOM);
|
28 | }
|
29 |
|
30 |
|
31 |
|
32 |
|
33 | var Legend = (function (_super) {
|
34 | tslib_1.__extends(Legend, _super);
|
35 | function Legend(view) {
|
36 | var _this = _super.call(this, view) || this;
|
37 | _this.container = _this.view.getLayer(constant_1.LAYER.FORE).addGroup();
|
38 | return _this;
|
39 | }
|
40 | Object.defineProperty(Legend.prototype, "name", {
|
41 | get: function () {
|
42 | return 'legend';
|
43 | },
|
44 | enumerable: false,
|
45 | configurable: true
|
46 | });
|
47 | Legend.prototype.init = function () { };
|
48 | |
49 |
|
50 |
|
51 | Legend.prototype.render = function () {
|
52 |
|
53 | this.update();
|
54 | };
|
55 | |
56 |
|
57 |
|
58 |
|
59 | Legend.prototype.layout = function () {
|
60 | var _this = this;
|
61 | this.layoutBBox = this.view.viewBBox;
|
62 | (0, util_1.each)(this.components, function (co) {
|
63 | var component = co.component, direction = co.direction;
|
64 | var layout = (0, legend_1.getLegendLayout)(direction);
|
65 | var maxWidthRatio = component.get('maxWidthRatio');
|
66 | var maxHeightRatio = component.get('maxHeightRatio');
|
67 | var maxSize = _this.getCategoryLegendSizeCfg(layout, maxWidthRatio, maxHeightRatio);
|
68 | var maxWidth = component.get('maxWidth');
|
69 | var maxHeight = component.get('maxHeight');
|
70 |
|
71 | component.update({
|
72 | maxWidth: Math.min(maxSize.maxWidth, maxWidth || 0),
|
73 | maxHeight: Math.min(maxSize.maxHeight, maxHeight || 0),
|
74 | });
|
75 | var padding = component.get('padding');
|
76 | var bboxObject = component.getLayoutBBox();
|
77 | var bbox = new bbox_1.BBox(bboxObject.x, bboxObject.y, bboxObject.width, bboxObject.height).expand(padding);
|
78 | var _a = tslib_1.__read((0, direction_1.directionToPosition)(_this.view.viewBBox, bbox, direction), 2), x1 = _a[0], y1 = _a[1];
|
79 | var _b = tslib_1.__read((0, direction_1.directionToPosition)(_this.layoutBBox, bbox, direction), 2), x2 = _b[0], y2 = _b[1];
|
80 | var x = 0;
|
81 | var y = 0;
|
82 |
|
83 | if (direction.startsWith('top') || direction.startsWith('bottom')) {
|
84 | x = x1;
|
85 | y = y2;
|
86 | }
|
87 | else {
|
88 | x = x2;
|
89 | y = y1;
|
90 | }
|
91 |
|
92 | component.setLocation({ x: x + padding[3], y: y + padding[0] });
|
93 | _this.layoutBBox = _this.layoutBBox.cut(bbox, direction);
|
94 | });
|
95 | };
|
96 | |
97 |
|
98 |
|
99 | Legend.prototype.update = function () {
|
100 | var _this = this;
|
101 | this.option = this.view.getOptions().legends;
|
102 |
|
103 | var updated = {};
|
104 | var eachLegend = function (geometry, attr, scale) {
|
105 | var id = _this.getId(scale.field);
|
106 | var existCo = _this.getComponentById(id);
|
107 |
|
108 | if (existCo) {
|
109 | var cfg = void 0;
|
110 | var legendOption = getLegendOption(_this.option, scale.field);
|
111 |
|
112 | if (legendOption !== false) {
|
113 | if ((0, util_1.get)(legendOption, 'custom')) {
|
114 | cfg = _this.getCategoryCfg(geometry, attr, scale, legendOption, true);
|
115 | }
|
116 | else {
|
117 | if (scale.isLinear) {
|
118 |
|
119 | cfg = _this.getContinuousCfg(geometry, attr, scale, legendOption);
|
120 | }
|
121 | else if (scale.isCategory) {
|
122 |
|
123 | cfg = _this.getCategoryCfg(geometry, attr, scale, legendOption);
|
124 | }
|
125 | }
|
126 | }
|
127 |
|
128 | if (cfg) {
|
129 |
|
130 | (0, helper_1.omit)(cfg, ['container']);
|
131 | existCo.direction = getDirection(legendOption);
|
132 | existCo.component.update(cfg);
|
133 |
|
134 | updated[id] = true;
|
135 | }
|
136 | }
|
137 | else {
|
138 |
|
139 | var legend = _this.createFieldLegend(geometry, attr, scale);
|
140 | if (legend) {
|
141 | legend.component.init();
|
142 | _this.components.push(legend);
|
143 |
|
144 | updated[id] = true;
|
145 | }
|
146 | }
|
147 | };
|
148 |
|
149 | if ((0, util_1.get)(this.option, 'custom')) {
|
150 | var id = 'global-custom';
|
151 | var existCo = this.getComponentById(id);
|
152 | if (existCo) {
|
153 | var customCfg = this.getCategoryCfg(undefined, undefined, undefined, this.option, true);
|
154 | (0, helper_1.omit)(customCfg, ['container']);
|
155 | existCo.component.update(customCfg);
|
156 | updated[id] = true;
|
157 | }
|
158 | else {
|
159 | var component = this.createCustomLegend(undefined, undefined, undefined, this.option);
|
160 | if (component) {
|
161 | component.init();
|
162 | var layer = constant_1.LAYER.FORE;
|
163 | var direction = getDirection(this.option);
|
164 | this.components.push({
|
165 | id: id,
|
166 | component: component,
|
167 | layer: layer,
|
168 | direction: direction,
|
169 | type: constant_1.COMPONENT_TYPE.LEGEND,
|
170 | extra: undefined,
|
171 | });
|
172 |
|
173 | updated[id] = true;
|
174 | }
|
175 | }
|
176 | }
|
177 | else {
|
178 |
|
179 | this.loopLegends(eachLegend);
|
180 | }
|
181 |
|
182 |
|
183 | var components = [];
|
184 | (0, util_1.each)(this.getComponents(), function (co) {
|
185 | if (updated[co.id]) {
|
186 | components.push(co);
|
187 | }
|
188 | else {
|
189 | co.component.destroy();
|
190 | }
|
191 | });
|
192 |
|
193 | this.components = components;
|
194 | };
|
195 | Legend.prototype.clear = function () {
|
196 | _super.prototype.clear.call(this);
|
197 | this.container.clear();
|
198 | };
|
199 | Legend.prototype.destroy = function () {
|
200 | _super.prototype.destroy.call(this);
|
201 | this.container.remove(true);
|
202 | };
|
203 | |
204 |
|
205 |
|
206 | Legend.prototype.getGeometries = function (view) {
|
207 | var _this = this;
|
208 | var geometries = view.geometries;
|
209 | (0, util_1.each)(view.views, function (v) {
|
210 | geometries = geometries.concat(_this.getGeometries(v));
|
211 | });
|
212 | return geometries;
|
213 | };
|
214 | |
215 |
|
216 |
|
217 |
|
218 | Legend.prototype.loopLegends = function (doEach) {
|
219 | var isRootView = this.view.getRootView() === this.view;
|
220 |
|
221 | if (!isRootView) {
|
222 | return;
|
223 | }
|
224 |
|
225 | var geometries = this.getGeometries(this.view);
|
226 | var looped = {};
|
227 | (0, util_1.each)(geometries, function (geometry) {
|
228 | var attributes = geometry.getGroupAttributes();
|
229 | (0, util_1.each)(attributes, function (attr) {
|
230 | var scale = attr.getScale(attr.type);
|
231 |
|
232 | if (!scale || scale.type === 'identity' || looped[scale.field]) {
|
233 | return;
|
234 | }
|
235 | doEach(geometry, attr, scale);
|
236 | looped[scale.field] = true;
|
237 | });
|
238 | });
|
239 | };
|
240 | |
241 |
|
242 |
|
243 |
|
244 |
|
245 |
|
246 | Legend.prototype.createFieldLegend = function (geometry, attr, scale) {
|
247 | var component;
|
248 | var legendOption = getLegendOption(this.option, scale.field);
|
249 | var layer = constant_1.LAYER.FORE;
|
250 | var direction = getDirection(legendOption);
|
251 |
|
252 | if (legendOption !== false) {
|
253 | if ((0, util_1.get)(legendOption, 'custom')) {
|
254 | component = this.createCustomLegend(geometry, attr, scale, legendOption);
|
255 | }
|
256 | else {
|
257 | if (scale.isLinear) {
|
258 |
|
259 | component = this.createContinuousLegend(geometry, attr, scale, legendOption);
|
260 | }
|
261 | else if (scale.isCategory) {
|
262 |
|
263 | component = this.createCategoryLegend(geometry, attr, scale, legendOption);
|
264 | }
|
265 | }
|
266 | }
|
267 | if (component) {
|
268 | component.set('field', scale.field);
|
269 | return {
|
270 | id: this.getId(scale.field),
|
271 | component: component,
|
272 | layer: layer,
|
273 | direction: direction,
|
274 | type: constant_1.COMPONENT_TYPE.LEGEND,
|
275 | extra: { scale: scale },
|
276 | };
|
277 | }
|
278 | };
|
279 | |
280 |
|
281 |
|
282 |
|
283 |
|
284 |
|
285 |
|
286 | Legend.prototype.createCustomLegend = function (geometry, attr, scale, legendOption) {
|
287 |
|
288 | var cfg = this.getCategoryCfg(geometry, attr, scale, legendOption, true);
|
289 | return new dependents_1.CategoryLegend(cfg);
|
290 | };
|
291 | |
292 |
|
293 |
|
294 |
|
295 |
|
296 |
|
297 |
|
298 | Legend.prototype.createContinuousLegend = function (geometry, attr, scale, legendOption) {
|
299 | var cfg = this.getContinuousCfg(geometry, attr, scale, (0, helper_1.omit)(legendOption, ['value']));
|
300 | return new dependents_1.ContinuousLegend(cfg);
|
301 | };
|
302 | |
303 |
|
304 |
|
305 |
|
306 |
|
307 |
|
308 |
|
309 | Legend.prototype.createCategoryLegend = function (geometry, attr, scale, legendOption) {
|
310 | var cfg = this.getCategoryCfg(geometry, attr, scale, legendOption);
|
311 | return new dependents_1.CategoryLegend(cfg);
|
312 | };
|
313 | |
314 |
|
315 |
|
316 |
|
317 |
|
318 |
|
319 |
|
320 | Legend.prototype.getContinuousCfg = function (geometry, attr, scale, legendOption) {
|
321 | var ticks = scale.getTicks();
|
322 | var containMin = (0, util_1.find)(ticks, function (tick) { return tick.value === 0; });
|
323 | var containMax = (0, util_1.find)(ticks, function (tick) { return tick.value === 1; });
|
324 | var items = ticks.map(function (tick) {
|
325 | var value = tick.value, tickValue = tick.tickValue;
|
326 | var attrValue = attr.mapping(scale.invert(value)).join('');
|
327 | return {
|
328 | value: tickValue,
|
329 | attrValue: attrValue,
|
330 | color: attrValue,
|
331 | scaleValue: value,
|
332 | };
|
333 | });
|
334 | if (!containMin) {
|
335 | items.push({
|
336 | value: scale.min,
|
337 | attrValue: attr.mapping(scale.invert(0)).join(''),
|
338 | color: attr.mapping(scale.invert(0)).join(''),
|
339 | scaleValue: 0,
|
340 | });
|
341 | }
|
342 | if (!containMax) {
|
343 | items.push({
|
344 | value: scale.max,
|
345 | attrValue: attr.mapping(scale.invert(1)).join(''),
|
346 | color: attr.mapping(scale.invert(1)).join(''),
|
347 | scaleValue: 1,
|
348 | });
|
349 | }
|
350 |
|
351 | items.sort(function (a, b) { return a.value - b.value; });
|
352 |
|
353 |
|
354 | var attrLegendCfg = {
|
355 | min: (0, util_1.head)(items).value,
|
356 | max: (0, util_1.last)(items).value,
|
357 | colors: [],
|
358 | rail: {
|
359 | type: attr.type,
|
360 | },
|
361 | track: {},
|
362 | };
|
363 | if (attr.type === 'size') {
|
364 | attrLegendCfg.track = {
|
365 | style: {
|
366 |
|
367 |
|
368 | fill: attr.type === 'size' ? this.view.getTheme().defaultColor : undefined,
|
369 | },
|
370 | };
|
371 | }
|
372 | if (attr.type === 'color') {
|
373 | attrLegendCfg.colors = items.map(function (item) { return item.attrValue; });
|
374 | }
|
375 | var container = this.container;
|
376 |
|
377 | var direction = getDirection(legendOption);
|
378 | var layout = (0, legend_1.getLegendLayout)(direction);
|
379 | var title = (0, util_1.get)(legendOption, 'title');
|
380 | if (title) {
|
381 | title = (0, util_1.deepMix)({
|
382 | text: (0, scale_1.getName)(scale),
|
383 | }, title);
|
384 | }
|
385 |
|
386 | attrLegendCfg.container = container;
|
387 | attrLegendCfg.layout = layout;
|
388 | attrLegendCfg.title = title;
|
389 | attrLegendCfg.animateOption = animate_1.DEFAULT_ANIMATE_CFG;
|
390 |
|
391 | return this.mergeLegendCfg(attrLegendCfg, legendOption, 'continuous');
|
392 | };
|
393 | |
394 |
|
395 |
|
396 |
|
397 |
|
398 |
|
399 |
|
400 |
|
401 | Legend.prototype.getCategoryCfg = function (geometry, attr, scale, legendOption, custom) {
|
402 | var container = this.container;
|
403 |
|
404 | var direction = (0, util_1.get)(legendOption, 'position', constant_1.DIRECTION.BOTTOM);
|
405 | var legendTheme = (0, legend_1.getLegendThemeCfg)(this.view.getTheme(), direction);
|
406 |
|
407 | var themeMarker = (0, util_1.get)(legendTheme, ['marker']);
|
408 | var userMarker = (0, util_1.get)(legendOption, 'marker');
|
409 | var layout = (0, legend_1.getLegendLayout)(direction);
|
410 | var themePageNavigator = (0, util_1.get)(legendTheme, ['pageNavigator']);
|
411 | var userPageNavigator = (0, util_1.get)(legendOption, 'pageNavigator');
|
412 | var items = custom
|
413 | ? (0, legend_1.getCustomLegendItems)(themeMarker, userMarker, legendOption.items)
|
414 | : (0, legend_1.getLegendItems)(this.view, geometry, attr, themeMarker, userMarker);
|
415 | var title = (0, util_1.get)(legendOption, 'title');
|
416 | if (title) {
|
417 | title = (0, util_1.deepMix)({
|
418 | text: scale ? (0, scale_1.getName)(scale) : '',
|
419 | }, title);
|
420 | }
|
421 | var maxWidthRatio = (0, util_1.get)(legendOption, 'maxWidthRatio');
|
422 | var maxHeightRatio = (0, util_1.get)(legendOption, 'maxHeightRatio');
|
423 | var baseCfg = this.getCategoryLegendSizeCfg(layout, maxWidthRatio, maxHeightRatio);
|
424 | baseCfg.container = container;
|
425 | baseCfg.layout = layout;
|
426 | baseCfg.items = items;
|
427 | baseCfg.title = title;
|
428 | baseCfg.animateOption = animate_1.DEFAULT_ANIMATE_CFG;
|
429 | baseCfg.pageNavigator = (0, util_1.deepMix)({}, themePageNavigator, userPageNavigator);
|
430 | var categoryCfg = this.mergeLegendCfg(baseCfg, legendOption, direction);
|
431 | if (categoryCfg.reversed) {
|
432 |
|
433 | categoryCfg.items.reverse();
|
434 | }
|
435 | var maxItemWidth = (0, util_1.get)(categoryCfg, 'maxItemWidth');
|
436 | if (maxItemWidth && maxItemWidth <= 1) {
|
437 |
|
438 | categoryCfg.maxItemWidth = this.view.viewBBox.width * maxItemWidth;
|
439 | }
|
440 | return categoryCfg;
|
441 | };
|
442 | |
443 |
|
444 |
|
445 |
|
446 |
|
447 |
|
448 | Legend.prototype.mergeLegendCfg = function (baseCfg, legendOption, direction) {
|
449 | var position = direction.split('-')[0];
|
450 | var themeObject = (0, legend_1.getLegendThemeCfg)(this.view.getTheme(), position);
|
451 | return (0, util_1.deepMix)({}, themeObject, baseCfg, legendOption);
|
452 | };
|
453 | |
454 |
|
455 |
|
456 |
|
457 | Legend.prototype.getId = function (key) {
|
458 | return "".concat(this.name, "-").concat(key);
|
459 | };
|
460 | |
461 |
|
462 |
|
463 |
|
464 | Legend.prototype.getComponentById = function (id) {
|
465 | return (0, util_1.find)(this.components, function (co) { return co.id === id; });
|
466 | };
|
467 | Legend.prototype.getCategoryLegendSizeCfg = function (layout, maxWidthRatio, maxHeightRatio) {
|
468 | if (maxWidthRatio === void 0) { maxWidthRatio = constant_1.COMPONENT_MAX_VIEW_PERCENTAGE; }
|
469 | if (maxHeightRatio === void 0) { maxHeightRatio = constant_1.COMPONENT_MAX_VIEW_PERCENTAGE; }
|
470 | var _a = this.view.viewBBox, vw = _a.width, vh = _a.height;
|
471 |
|
472 |
|
473 | return layout === 'vertical'
|
474 | ? {
|
475 | maxWidth: vw * maxWidthRatio,
|
476 | maxHeight: vh,
|
477 | }
|
478 | : {
|
479 | maxWidth: vw,
|
480 | maxHeight: vh * maxHeightRatio,
|
481 | };
|
482 | };
|
483 | return Legend;
|
484 | }(base_1.Controller));
|
485 | exports.default = Legend;
|
486 |
|
\ | No newline at end of file |