You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by ov...@apache.org on 2019/11/12 11:08:34 UTC

[incubator-echarts] branch fix-11381 created (now 96d88a8)

This is an automated email from the ASF dual-hosted git repository.

ovilia pushed a change to branch fix-11381
in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git.


      at 96d88a8  WIP(pie): support align to edge and labelLine mode

This branch includes the following new commits:

     new 96d88a8  WIP(pie): support align to edge and labelLine mode

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org


[incubator-echarts] 01/01: WIP(pie): support align to edge and labelLine mode

Posted by ov...@apache.org.
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 <zw...@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-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org