This is an automated email from the ASF dual-hosted git repository. ovilia pushed a commit to branch fix-11381 in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git
commit 96d88a890ce21d90fb00a5572bfd7b47db055bd1 Author: Ovilia <zwl.s...@gmail.com> AuthorDate: Tue Nov 12 19:07:08 2019 +0800 WIP(pie): support align to edge and labelLine mode --- src/chart/pie/PieSeries.js | 10 +++- src/chart/pie/PieView.js | 2 +- src/chart/pie/labelLayout.js | 138 +++++++++++++++++++++++++++++++++++++------ 3 files changed, 130 insertions(+), 20 deletions(-) diff --git a/src/chart/pie/PieSeries.js b/src/chart/pie/PieSeries.js index 42a44e6..c8d8506 100644 --- a/src/chart/pie/PieSeries.js +++ b/src/chart/pie/PieSeries.js @@ -147,7 +147,13 @@ var PieSeries = echarts.extendSeriesModel({ rotate: false, show: true, // 'outer', 'inside', 'center' - position: 'outer' + position: 'outer', + // 'none', 'labelLine', 'edge'. Works only when position is 'outer' + alignTo: 'none', + // Closest distance between label and chart edge. + // Works only position is 'outer' and alignTo is 'labelLine' or 'edge'. + edgeMargin: 50, + padding: 5, // formatter: 标签文本格式器,同Tooltip.formatter,不支持异步回调 // 默认使用全局文本样式,详见TEXTSTYLE // distance: 当position为inner时有效,为label位置到圆心的距离与圆半径(环状图为内外半径和)的比例系数 @@ -159,6 +165,8 @@ var PieSeries = echarts.extendSeriesModel({ length: 15, // 引导线两段中的第二段长度 length2: 15, + maxLength2: 100, + minLength2: 15, smooth: false, lineStyle: { // color: 各异, diff --git a/src/chart/pie/PieView.js b/src/chart/pie/PieView.js index 69e6903..7d17246 100644 --- a/src/chart/pie/PieView.js +++ b/src/chart/pie/PieView.js @@ -273,7 +273,7 @@ piePieceProto._updateLabel = function (data, idx, withAnimation) { { labelFetcher: data.hostModel, labelDataIndex: idx, - defaultText: data.getName(idx), + defaultText: labelLayout.truncatedText, autoColor: visualColor, useInsideStyle: !!labelLayout.inside }, diff --git a/src/chart/pie/labelLayout.js b/src/chart/pie/labelLayout.js index f2492fe..d31f58a 100644 --- a/src/chart/pie/labelLayout.js +++ b/src/chart/pie/labelLayout.js @@ -20,10 +20,11 @@ // FIXME emphasis label position is not same with normal label position import * as textContain from 'zrender/src/contain/text'; +import {parsePercent} from '../../util/number'; var RADIAN = Math.PI / 180; -function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) { +function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight, labelLine) { list.sort(function (a, b) { return a.y - b.y; }); @@ -54,7 +55,7 @@ function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) { } } - function changeX(list, isDownList, cx, cy, r, dir) { + function changeX(list, isDownList, cx, cy, r, dir, maxTextWidth) { var lastDeltaX = dir > 0 ? isDownList // right-side ? Number.MAX_VALUE // down @@ -64,6 +65,35 @@ function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) { : 0; // up for (var i = 0, l = list.length; i < l; i++) { + if (list[i].labelAlignTo !== 'none') { + var dx = labelLine.dx * dir; + var x2 = list[i].linePoints[1][0]; + var x3 = list[i].linePoints[2][0] + dx; + var len2 = (x3 - x2) * dir; + + list[i].x = x3 + dir * list[i].labelPadding; + if (len2 < labelLine.restrainMinLen2) { + var x3Updated = x2 + labelLine.restrainMinLen2 * dir; + var padding = list[i].labelPadding; + + var textWidth = list[i].width + (x3 - x3Updated + padding) * dir; + list[i].truncatedText = textContain.truncateText( + list[i].truncatedText, + textWidth, + list[i].font + ); + var realTextWidth = textContain.getWidth( + list[i].truncatedText, + list[i].font + ); + list[i].x += dir * (list[i].width - realTextWidth); + + x3 = x3Updated; + } + list[i].linePoints[2][0] = x3; + continue; + } + var deltaY = Math.abs(list[i].y - cy); var length = list[i].len; var length2 = list[i].len2; @@ -92,12 +122,14 @@ function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) { var len = list.length; var upList = []; var downList = []; + var maxTextWidth = -1; for (var i = 0; i < len; i++) { delta = list[i].y - lastY; if (delta < 0) { shiftDown(i, len, -delta, dir); } lastY = list[i].y + list[i].height; + maxTextWidth = Math.max(maxTextWidth, list[i].width); } if (viewHeight - lastY < 0) { shiftUp(len - 1, lastY - viewHeight); @@ -110,11 +142,11 @@ function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) { upList.push(list[i]); } } - changeX(upList, false, cx, cy, r, dir); - changeX(downList, true, cx, cy, r, dir); + changeX(upList, false, cx, cy, r, dir, maxTextWidth); + changeX(downList, true, cx, cy, r, dir, maxTextWidth); } -function avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight) { +function avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight, labelLine) { var leftList = []; var rightList = []; for (var i = 0; i < labelLayoutList.length; i++) { @@ -129,11 +161,13 @@ function avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight) { } } - adjustSingleSide(rightList, cx, cy, r, 1, viewWidth, viewHeight); - adjustSingleSide(leftList, cx, cy, r, -1, viewWidth, viewHeight); + adjustSingleSide(rightList, cx, cy, r, 1, viewWidth, viewHeight, labelLine); + adjustSingleSide(leftList, cx, cy, r, -1, viewWidth, viewHeight, labelLine); for (var i = 0; i < labelLayoutList.length; i++) { - if (isPositionCenter(labelLayoutList[i])) { + if (isPositionCenter(labelLayoutList[i]) + || labelLayoutList[i].labelAlignTo !== 'none' + ) { continue; } var linePoints = labelLayoutList[i].linePoints; @@ -164,6 +198,12 @@ export default function (seriesModel, r, viewWidth, viewHeight, sum) { var hasLabelRotate = false; var minShowLabelRadian = (seriesModel.get('minShowLabelAngle') || 0) * RADIAN; + var seriesLabelModel = seriesModel.getModel('label'); + var edgeMargin = seriesLabelModel.get('edgeMargin'); + edgeMargin = parsePercent(edgeMargin, viewWidth); + var maxLen2 = -1; + var minLen2 = Number.MAX_VALUE; + data.each(function (idx) { var layout = data.getItemLayout(idx); @@ -171,11 +211,17 @@ export default function (seriesModel, r, viewWidth, viewHeight, sum) { var labelModel = itemModel.getModel('label'); // Use position in normal or emphasis var labelPosition = labelModel.get('position') || itemModel.get('emphasis.label.position'); + var labelAlignTo = labelModel.get('alignTo'); + var labelPadding = labelModel.get('padding'); + var font = labelModel.getFont(); var labelLineModel = itemModel.getModel('labelLine'); var labelLineLen = labelLineModel.get('length'); var labelLineLen2 = labelLineModel.get('length2'); + var edgeMargin = labelModel.get('edgeMargin'); + edgeMargin = parsePercent(edgeMargin, viewWidth); + if (layout.angle < minShowLabelRadian) { return; } @@ -192,6 +238,12 @@ export default function (seriesModel, r, viewWidth, viewHeight, sum) { cx = layout.cx; cy = layout.cy; + var text = seriesModel.getFormattedLabel(idx, 'normal') + || data.getName(idx); + var textRect = textContain.getBoundingRect( + text, font, textAlign, 'top' + ); + var isLabelInside = labelPosition === 'inside' || labelPosition === 'inner'; if (labelPosition === 'center') { textX = layout.cx; @@ -205,21 +257,43 @@ export default function (seriesModel, r, viewWidth, viewHeight, sum) { textX = x1 + dx * 3; textY = y1 + dy * 3; + var dir = dx < 0 ? -1 : 1; + if (!isLabelInside) { // For roseType var x2 = x1 + dx * (labelLineLen + r - layout.r); var y2 = y1 + dy * (labelLineLen + r - layout.r); - var x3 = x2 + ((dx < 0 ? -1 : 1) * labelLineLen2); + + var x3; + if (labelAlignTo === 'labelLine') { + x3 = dx < 0 + ? edgeMargin + labelPadding + : viewWidth - edgeMargin - labelPadding; + } + else if (labelAlignTo === 'edge') { + x3 = dx < 0 + ? edgeMargin + labelPadding + textRect.width + : viewWidth - edgeMargin - labelPadding - textRect.width; + } + else { + x3 = x2 + dir * labelLineLen2; + } + + if (labelAlignTo === 'edge' || labelAlignTo === 'labelLine') { + var len2 = (x3 - x2) * dir; + minLen2 = Math.min(minLen2, len2); + maxLen2 = Math.max(maxLen2, len2); + } + var y3 = y2; - textX = x3 + (dx < 0 ? -5 : 5); + textX = x3 + dir * labelPadding; textY = y3; linePoints = [[x1, y1], [x2, y2], [x3, y3]]; } textAlign = isLabelInside ? 'center' : (dx > 0 ? 'left' : 'right'); } - var font = labelModel.getFont(); var labelRotate; var rotate = labelModel.get('rotate'); @@ -231,16 +305,15 @@ export default function (seriesModel, r, viewWidth, viewHeight, sum) { ? (dx < 0 ? -midAngle + Math.PI : -midAngle) : 0; } - var text = seriesModel.getFormattedLabel(idx, 'normal') - || data.getName(idx); - var textRect = textContain.getBoundingRect( - text, font, textAlign, 'top' - ); + hasLabelRotate = !!labelRotate; layout.label = { x: textX, y: textY, position: labelPosition, + labelAlignTo: labelAlignTo, + edgeMargin: edgeMargin, + width: textRect.width, height: textRect.height, len: labelLineLen, len2: labelLineLen2, @@ -248,7 +321,10 @@ export default function (seriesModel, r, viewWidth, viewHeight, sum) { textAlign: textAlign, verticalAlign: 'middle', rotation: labelRotate, - inside: isLabelInside + inside: isLabelInside, + truncatedText: text, + font: font, + labelPadding: labelPadding }; // Not layout the inside label @@ -256,7 +332,33 @@ export default function (seriesModel, r, viewWidth, viewHeight, sum) { labelLayoutList.push(layout.label); } }); + if (!hasLabelRotate && seriesModel.get('avoidLabelOverlap')) { - avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight); + var seriesLabelLineModel = seriesModel.getModel('labelLine'); + var restrainMinLen2 = parsePercent(seriesLabelLineModel.get('minLength2'), viewWidth); + var restrainMaxLen2 = parsePercent(seriesLabelLineModel.get('maxLength2'), viewWidth); + if (restrainMaxLen2 < restrainMinLen2) { + restrainMaxLen2 = restrainMinLen2; + } + + var targetMinLen2 = Math.min(Math.max(minLen2, restrainMinLen2), restrainMaxLen2); + var targetMaxLen2 = Math.max(Math.min(maxLen2, restrainMaxLen2), restrainMinLen2); + + var dx = 0; + if (minLen2 < targetMinLen2) { + dx = targetMinLen2 - minLen2; + } + else if (maxLen2 > targetMaxLen2) { + dx = targetMaxLen2 - maxLen2; + } + + var labelLine = { + restrainMinLen2: restrainMinLen2, + restrainMaxLen2: restrainMaxLen2, + dx: dx + }; + + // console.log(labelLine); + avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight, labelLine); } } \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@echarts.apache.org For additional commands, e-mail: commits-h...@echarts.apache.org