UNPKG

@antv/g2

Version:

the Grammar of Graphics in Javascript

200 lines 7.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.distribute = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var graphics_1 = require("../../../../util/graphics"); /** label text和line距离 4px */ var MARGIN = 4; function antiCollision(labelShapes, labels, lineHeight, plotRange, center, isRight) { var e_1, _a; // adjust y position of labels to avoid overlapping var overlapping = true; var start = plotRange.start; var end = plotRange.end; var startY = Math.min(start.y, end.y); var totalHeight = Math.abs(start.y - end.y); var i; var maxY = 0; var minY = Number.MIN_VALUE; var boxes = labels.map(function (label) { if (label.y > maxY) { maxY = label.y; } if (label.y < minY) { minY = label.y; } return { size: lineHeight, targets: [label.y - startY], }; }); minY -= startY; if (maxY - startY > totalHeight) { totalHeight = maxY - startY; } while (overlapping) { /* eslint no-loop-func: 0 */ boxes.forEach(function (box) { var target = (Math.min.apply(minY, box.targets) + Math.max.apply(minY, box.targets)) / 2; box.pos = Math.min(Math.max(minY, target - box.size / 2), totalHeight - box.size); // box.pos = Math.max(0, target - box.size / 2); }); // detect overlapping and join boxes overlapping = false; i = boxes.length; while (i--) { if (i > 0) { var previousBox = boxes[i - 1]; var box = boxes[i]; if (previousBox.pos + previousBox.size > box.pos) { // overlapping previousBox.size += box.size; previousBox.targets = previousBox.targets.concat(box.targets); // overflow, shift up if (previousBox.pos + previousBox.size > totalHeight) { previousBox.pos = totalHeight - previousBox.size; } boxes.splice(i, 1); // removing box overlapping = true; } } } } i = 0; // step 4: normalize y and adjust x boxes.forEach(function (b) { var posInCompositeBox = startY + lineHeight / 2; // middle of the label b.targets.forEach(function () { labels[i].y = b.pos + posInCompositeBox; posInCompositeBox += lineHeight; i++; }); }); var labelsMap = {}; try { for (var labelShapes_1 = tslib_1.__values(labelShapes), labelShapes_1_1 = labelShapes_1.next(); !labelShapes_1_1.done; labelShapes_1_1 = labelShapes_1.next()) { var labelShape = labelShapes_1_1.value; labelsMap[labelShape.get('id')] = labelShape; } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (labelShapes_1_1 && !labelShapes_1_1.done && (_a = labelShapes_1.return)) _a.call(labelShapes_1); } finally { if (e_1) throw e_1.error; } } // (x - cx)^2 + (y - cy)^2 = totalR^2 labels.forEach(function (label) { var rPow2 = label.r * label.r; var dyPow2 = Math.pow(Math.abs(label.y - center.y), 2); if (rPow2 < dyPow2) { label.x = center.x; } else { var dx = Math.sqrt(rPow2 - dyPow2); if (!isRight) { // left label.x = center.x - dx; } else { // right label.x = center.x + dx; } } // adjust labelShape var labelShape = labelsMap[label.id]; labelShape.attr('x', label.x); labelShape.attr('y', label.y); // because group could not effect text-shape, should set text-shape position manually var textShape = (0, util_1.find)(labelShape.getChildren(), function (ele) { return ele.get('type') === 'text'; }); // @ts-ignore if (textShape) { textShape.attr('y', label.y); textShape.attr('x', label.x); } }); } function distribute(items, labels, shapes, region) { if (!items.length || !labels.length) { return; } var offset = items[0] ? items[0].offset : 0; var coordinate = labels[0].get('coordinate'); var radius = coordinate.getRadius(); var center = coordinate.getCenter(); if (offset > 0) { // const lineHeight = get(this.geometry.theme, ['pieLabels', 'labelHeight'], 14); var lineHeight_1 = 14; // TODO var totalR = radius + offset; var totalHeight_1 = totalR * 2 + lineHeight_1 * 2; var plotRange_1 = { start: coordinate.start, end: coordinate.end, }; // step 1: separate labels var halves_1 = [ [], [], // right ]; items.forEach(function (labelItem) { if (!labelItem) { return; } if (labelItem.textAlign === 'right') { // left halves_1[0].push(labelItem); } else { // right or center will be put on the right side halves_1[1].push(labelItem); } }); halves_1.forEach(function (half, index) { // step 2: reduce labels var maxLabelsCountForOneSide = totalHeight_1 / lineHeight_1; if (half.length > maxLabelsCountForOneSide) { half.sort(function (a, b) { // sort by percentage DESC return b['..percent'] - a['..percent']; }); half.splice(maxLabelsCountForOneSide, half.length - maxLabelsCountForOneSide); } // step 3: distribute position (x and y) half.sort(function (a, b) { // sort by y ASC return a.y - b.y; }); antiCollision(labels, half, lineHeight_1, plotRange_1, center, index); }); } // 配置 labelLine (0, util_1.each)(items, function (item) { if (item && item.labelLine) { var distance = item.offset; var angle = item.angle; // 贴近圆周 var startPoint = (0, graphics_1.polarToCartesian)(center.x, center.y, radius, angle); var innerPoint = (0, graphics_1.polarToCartesian)(center.x, center.y, radius + distance / 2, angle); var itemX = item.x + (0, util_1.get)(item, 'offsetX', 0); var itemY = item.y + (0, util_1.get)(item, 'offsetY', 0); var endPoint = { x: itemX - Math.cos(angle) * MARGIN, y: itemY - Math.sin(angle) * MARGIN, }; if (!(0, util_1.isObject)(item.labelLine)) { // labelLine: true item.labelLine = {}; } item.labelLine.path = [ "M ".concat(startPoint.x), "".concat(startPoint.y, " Q").concat(innerPoint.x), "".concat(innerPoint.y, " ").concat(endPoint.x), endPoint.y, ].join(','); } }); } exports.distribute = distribute; //# sourceMappingURL=distribute.js.map