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

Reply via email to