UNPKG

@antv/f2

Version:

Charts for mobile visualization.

294 lines (293 loc) 9.76 kB
import { __assign, __extends } from "tslib"; import { jsx, Component } from '@antv/f-engine'; import { deepMix, isFunction } from '@antv/util'; var DEFAULT_CONFIG = { anchorOffset: '10px', inflectionOffset: '30px', sidePadding: '15px', height: '64px', adjustOffset: '30', triggerOn: 'click', // activeShape: false, // 当有图形被选中的时候,是否激活图形 // activeStyle: { // offset: '1px', // appendRadius: '8px', // fillOpacity: 0.5, // }, label1OffsetY: '-4px', label2OffsetY: '4px' }; function getEndPoint(center, angle, r) { return { x: center.x + r * Math.cos(angle), y: center.y + r * Math.sin(angle) }; } // 计算中间角度 function getMiddleAngle(startAngle, endAngle) { if (endAngle < startAngle) { endAngle += Math.PI * 2; } return (endAngle + startAngle) / 2; } function move(from, to, count, center) { var x = center.x; var sort = from.sort(function (a, b) { var aDistance = Math.abs(a.x - x); var bDistance = Math.abs(b.x - x); return bDistance - aDistance; }); return [sort.slice(0, sort.length - count), sort.slice(sort.length - count).concat(to)]; } // 第一象限 function isFirstQuadrant(angle) { return angle >= -Math.PI / 2 && angle < 0; } // 第二象限 function isSecondQuadrant(angle) { return angle >= 0 && angle < Math.PI / 2; } function isThirdQuadrant(angle) { return angle >= Math.PI / 2 && angle < Math.PI; } function isFourthQuadrant(angle) { return angle >= Math.PI && angle < Math.PI * 3 / 2; } export default (function (View) { return /** @class */function (_super) { __extends(PieLabel, _super); function PieLabel(props) { return _super.call(this, props) || this; } PieLabel.prototype.willMount = function () {}; /** * 绑定事件 */ PieLabel.prototype.didMount = function () {}; PieLabel.prototype.getLabels = function (props) { var chart = props.chart, coord = props.coord, anchorOffset = props.anchorOffset, inflectionOffset = props.inflectionOffset, label1 = props.label1, label2 = props.label2, itemHeight = props.height, sidePadding = props.sidePadding; var center = coord.center, radius = coord.radius, coordWidth = coord.width, coordHeight = coord.height, coordLeft = coord.left, coordRight = coord.right, coordTop = coord.top; var maxCountForOneSide = Math.floor(coordHeight / itemHeight); var maxCount = maxCountForOneSide * 2; var geometry = chart.getGeometrys()[0]; var records = geometry.flatRecords() // 按角度大到小排序 .sort(function (a, b) { var angle1 = a.xMax - a.xMin; var angle2 = b.xMax - b.xMin; return angle2 - angle1; }) // 只取前 maxCount 个显示 .slice(0, maxCount); // 存储左右 labels var halves = [[], [] // right ]; records.forEach(function (record) { var xMin = record.xMin, xMax = record.xMax, color = record.color, origin = record.origin; // 锚点角度 var anchorAngle = getMiddleAngle(xMin, xMax); // 锚点坐标 var anchorPoint = getEndPoint(center, anchorAngle, radius + anchorOffset); // 拐点坐标 var inflectionPoint = getEndPoint(center, anchorAngle, radius + inflectionOffset); // 锚点方向 var side = anchorPoint.x < center.x ? 'left' : 'right'; var label = { origin: origin, angle: anchorAngle, anchor: anchorPoint, inflection: inflectionPoint, side: side, x: inflectionPoint.x, y: inflectionPoint.y, r: radius + inflectionOffset, color: color, label1: isFunction(label1) ? label1(origin, record) : label1, label2: isFunction(label2) ? label2(origin, record) : label2 }; // 判断文本的方向 if (side === 'left') { halves[0].push(label); } else { halves[1].push(label); } }); // 判断是有一边超过了显示的最大 if (halves[0].length > maxCountForOneSide) { halves = move(halves[0], halves[1], halves[0].length - maxCountForOneSide, center); } else if (halves[1].length > maxCountForOneSide) { var _a = move(halves[1], halves[0], halves[1].length - maxCountForOneSide, center), right = _a[0], left = _a[1]; halves = [left, right]; } // label 的最大宽度 var labelWidth = coordWidth / 2 - radius - anchorOffset - inflectionOffset - 2 * sidePadding; var labels = []; halves.forEach(function (half, index) { var showSide = index === 0 ? 'left' : 'right'; // 顺时针方向排序 half.sort(function (a, b) { var aAngle = a.angle; var bAngle = b.angle; if (showSide === 'left') { // 是否在第一象限 aAngle = isFirstQuadrant(aAngle) ? aAngle + Math.PI * 2 : aAngle; bAngle = isFirstQuadrant(bAngle) ? bAngle + Math.PI * 2 : bAngle; return bAngle - aAngle; } else { // 是否在第四象限 aAngle = isFourthQuadrant(aAngle) ? aAngle - Math.PI * 2 : aAngle; bAngle = isFourthQuadrant(bAngle) ? bAngle - Math.PI * 2 : bAngle; return aAngle - bAngle; } }); var pointsY = half.map(function (label) { return label.y; }); var maxY = Math.max.apply(null, pointsY); var minY = Math.min.apply(null, pointsY); // 每个 label 占用的高度 var labelCount = half.length; var labelHeight = coordHeight / labelCount; var halfLabelHeight = labelHeight / 2; // 线之间的间隔 var lineInterval = 2; if (showSide === 'left') { half.forEach(function (label, index) { var anchor = label.anchor, inflection = label.inflection, angle = label.angle, x = label.x, y = label.y; var points = [anchor, inflection]; var endX = coordLeft + sidePadding; var endY = coordTop + halfLabelHeight + labelHeight * index; // 文本开始点 var labelStart = { x: endX + labelWidth + lineInterval * index, y: endY }; // 文本结束点 var labelEnd = { x: endX, y: endY }; // 第四象限 if (isFirstQuadrant(angle)) { var pointY = minY - lineInterval * (labelCount - index); points.push({ x: x, y: pointY }); points.push({ x: labelStart.x, y: pointY }); } else if (isThirdQuadrant(angle) || isFourthQuadrant(angle)) { points.push({ x: labelStart.x, y: y }); } else if (isSecondQuadrant(angle)) { var pointY = maxY + lineInterval * index; points.push({ x: x, y: pointY }); points.push({ x: labelStart.x, y: pointY }); } points.push(labelStart); points.push(labelEnd); label.points = points; label.side = showSide; labels.push(label); }); } else { half.forEach(function (label, index) { var anchor = label.anchor, inflection = label.inflection, angle = label.angle, x = label.x, y = label.y; // 折线的点 var points = [anchor, inflection]; var endX = coordRight - sidePadding; var endY = coordTop + halfLabelHeight + labelHeight * index; // 文本开始点 var labelStart = { x: endX - labelWidth - lineInterval * index, y: endY }; // 文本结束点 var labelEnd = { x: endX, y: endY }; // 第四象限 if (isFourthQuadrant(angle)) { var pointY = minY - lineInterval * (labelCount - index); points.push({ x: x, y: pointY }); points.push({ x: labelStart.x, y: pointY }); } else if (isFirstQuadrant(angle) || isSecondQuadrant(angle)) { points.push({ x: labelStart.x, y: y }); } else if (isThirdQuadrant(angle)) { var pointY = maxY + lineInterval * index; points.push({ x: x, y: pointY }); points.push({ x: labelStart.x, y: pointY }); } points.push(labelStart); points.push(labelEnd); label.points = points; label.side = showSide; labels.push(label); }); } }); return labels; }; PieLabel.prototype.render = function () { var context = this.context; var props = context.px2hd(deepMix({}, DEFAULT_CONFIG, this.props)); var labels = this.getLabels(props); return jsx(View, __assign({ labels: labels }, props)); }; return PieLabel; }(Component); });