You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by sh...@apache.org on 2020/05/28 11:07:02 UTC

[incubator-echarts] branch label-enhancement updated: refact: layout label after render in pie.

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

shenyi pushed a commit to branch label-enhancement
in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git


The following commit(s) were added to refs/heads/label-enhancement by this push:
     new c11498d  refact: layout label after render in pie.
c11498d is described below

commit c11498d89e53949a1f62b0fc7d0ae0697e4d0146
Author: pissang <bm...@gmail.com>
AuthorDate: Thu May 28 19:06:23 2020 +0800

    refact: layout label after render in pie.
---
 src/chart/pie/PieView.ts     |  53 ++++----------
 src/chart/pie/labelLayout.ts | 160 +++++++++++++++++++++++++++----------------
 src/chart/pie/pieLayout.ts   |  11 ++-
 3 files changed, 117 insertions(+), 107 deletions(-)

diff --git a/src/chart/pie/PieView.ts b/src/chart/pie/PieView.ts
index 8187c6a..f52c6f7 100644
--- a/src/chart/pie/PieView.ts
+++ b/src/chart/pie/PieView.ts
@@ -27,6 +27,7 @@ import ExtensionAPI from '../../ExtensionAPI';
 import { Payload, ColorString, ECElement } from '../../util/types';
 import List from '../../data/List';
 import PieSeriesModel, {PieDataItemOption} from './PieSeries';
+import labelLayout from './labelLayout';
 
 function updateDataSelected(
     this: PiePiece,
@@ -74,11 +75,6 @@ class PiePiece extends graphic.Sector {
         const itemModel = data.getItemModel<PieDataItemOption>(idx);
         const layout = data.getItemLayout(idx);
         const sectorShape = zrUtil.extend({}, layout);
-        // Not animate label
-        sectorShape.label = null;
-        sectorShape.viewRect = null;
-
-        const animationTypeUpdate = seriesModel.getShallow('animationTypeUpdate');
 
         if (firstCreate) {
             sector.setShape(sectorShape);
@@ -136,7 +132,7 @@ class PiePiece extends graphic.Sector {
         const cursorStyle = itemModel.getShallow('cursor');
         cursorStyle && sector.attr('cursor', cursorStyle);
 
-        this._updateLabel(data, idx);
+        this._updateLabel(seriesModel, data, idx);
 
         const emphasisState = sector.ensureState('emphasis');
         emphasisState.shape = {
@@ -150,12 +146,11 @@ class PiePiece extends graphic.Sector {
         labelLine.states.select = {
             x: dx, y: dy
         };
-        if (layout.label) {
-            labelText.states.select = {
-                x: layout.label.x + dx,
-                y: layout.label.y + dy
-            };
-        }
+        // TODO: needs dx, dy in zrender?
+        labelText.states.select = {
+            x: dx,
+            y: dy
+        };
 
         graphic.enableHoverEmphasis(this);
 
@@ -163,32 +158,16 @@ class PiePiece extends graphic.Sector {
         (sector as ECElement).selected = seriesModel.isSelected(data.getName(idx));
     }
 
-    private _updateLabel(data: List, idx: number): void {
+    private _updateLabel(seriesModel: PieSeriesModel, data: List, idx: number): void {
         const sector = this;
         const labelLine = sector.getTextGuideLine();
         const labelText = sector.getTextContent();
 
         const itemModel = data.getItemModel<PieDataItemOption>(idx);
-        const layout = data.getItemLayout(idx);
-        const labelLayout = layout.label;
-        // let visualColor = data.getItemVisual(idx, 'color');
 
         const labelTextEmphasisState = labelText.ensureState('emphasis');
         const labelLineEmphasisState = labelLine.ensureState('emphasis');
 
-        if (!labelLayout || isNaN(labelLayout.x) || isNaN(labelLayout.y)) {
-            labelText.ignore = labelTextEmphasisState.ignore = true;
-            labelLine.ignore = labelLineEmphasisState.ignore = true;
-            return;
-        }
-
-        const targetLineShape: {
-            points: number[][]
-        } = {
-            points: labelLayout.linePoints || [
-                [labelLayout.x, labelLayout.y], [labelLayout.x, labelLayout.y], [labelLayout.x, labelLayout.y]
-            ]
-        };
         const labelModel = itemModel.getModel('label');
         const labelHoverModel = itemModel.getModel(['emphasis', 'label']);
         const labelLineModel = itemModel.getModel('labelLine');
@@ -204,11 +183,10 @@ class PiePiece extends graphic.Sector {
             {
                 labelFetcher: data.hostModel as PieSeriesModel,
                 labelDataIndex: idx,
-                defaultText: labelLayout.text
+                defaultText: seriesModel.getFormattedLabel(idx, 'normal')
+                    || data.getName(idx)
             },
             {
-                align: labelLayout.textAlign,
-                verticalAlign: labelLayout.verticalAlign,
                 opacity: style && style.opacity
             }
         );
@@ -216,24 +194,15 @@ class PiePiece extends graphic.Sector {
         // Set textConfig on sector.
         sector.setTextConfig({
             local: true,
-            inside: !!labelLayout.inside,
             insideStroke: visualColor,
             // insideFill: 'auto',
             outsideFill: visualColor
         });
 
-        labelLine.attr({
-            shape: targetLineShape
-        });
         // Make sure update style on labelText after setLabelStyle.
         // Because setLabelStyle will replace a new style on it.
-        labelText.attr({
-            x: labelLayout.x,
-            y: labelLayout.y
-        });
 
         labelText.attr({
-            rotation: labelLayout.rotation,
             z2: 10
         });
 
@@ -338,6 +307,8 @@ class PieView extends ChartView {
             })
             .execute();
 
+        labelLayout(seriesModel);
+
         // Always use initial animation.
         if (seriesModel.get('animationTypeUpdate') !== 'expansion') {
             this._data = data;
diff --git a/src/chart/pie/labelLayout.ts b/src/chart/pie/labelLayout.ts
index d1da84d..90c53e5 100644
--- a/src/chart/pie/labelLayout.ts
+++ b/src/chart/pie/labelLayout.ts
@@ -18,34 +18,35 @@
 */
 
 // FIXME emphasis label position is not same with normal label position
-
-import * as textContain from 'zrender/src/contain/text';
 import {parsePercent} from '../../util/number';
 import PieSeriesModel, { PieSeriesOption, PieDataItemOption } from './PieSeries';
 import { VectorArray } from 'zrender/src/core/vector';
-import { HorizontalAlign, VerticalAlign, ZRRectLike } from '../../util/types';
+import { HorizontalAlign, VerticalAlign, ZRRectLike, ZRTextAlign } from '../../util/types';
+import { Sector, Polyline } from '../../util/graphic';
+import ZRText from 'zrender/src/graphic/Text';
+import { RectLike } from 'zrender/src/core/BoundingRect';
+import Displayable from 'zrender/src/graphic/Displayable';
+import { each } from 'zrender/src/core/util';
 
 const RADIAN = Math.PI / 180;
 
 interface LabelLayout {
     x: number
     y: number
+    label: ZRText,
+    labelLine: Polyline,
     position: PieSeriesOption['label']['position'],
-    height: number
     len: number
     len2: number
     linePoints: VectorArray[]
     textAlign: HorizontalAlign
     verticalAlign: VerticalAlign,
     rotation: number,
-    inside: boolean,
     labelDistance: number,
     labelAlignTo: PieSeriesOption['label']['alignTo'],
     labelMargin: number,
     bleedMargin: PieSeriesOption['label']['bleedMargin'],
-    textRect: ZRRectLike,
-    text: string,
-    font: string
+    textRect: ZRRectLike
 }
 
 function adjustSingleSide(
@@ -73,7 +74,7 @@ function adjustSingleSide(
             list[j].y += delta;
             if (j > start
                 && j + 1 < end
-                && list[j + 1].y > list[j].y + list[j].height
+                && list[j + 1].y > list[j].y + list[j].textRect.height
             ) {
                 shiftUp(j, delta / 2);
                 return;
@@ -91,7 +92,7 @@ function adjustSingleSide(
 
             list[j].y -= delta;
             if (j > 0
-                && list[j].y > list[j - 1].y + list[j - 1].height
+                && list[j].y > list[j - 1].y + list[j - 1].textRect.height
             ) {
                 break;
             }
@@ -155,7 +156,7 @@ function adjustSingleSide(
         if (delta < 0) {
             shiftDown(i, len, -delta, dir);
         }
-        lastY = list[i].y + list[i].height;
+        lastY = list[i].y + list[i].textRect.height;
     }
     if (viewHeight - lastY < 0) {
         shiftUp(len - 1, lastY - viewHeight);
@@ -236,8 +237,11 @@ function avoidOverlap(
             if (targetTextWidth < layout.textRect.width) {
                 // TODOTODO
                 // layout.text = textContain.truncateText(layout.text, targetTextWidth, layout.font);
+                layout.label.style.width = targetTextWidth;
+                layout.label.style.overflow = 'truncate';
                 if (layout.labelAlignTo === 'edge') {
-                    realTextWidth = textContain.getWidth(layout.text, layout.font);
+                    realTextWidth = targetTextWidth;
+                    // realTextWidth = textContain.getWidth(layout.text, layout.font);
                 }
             }
 
@@ -265,18 +269,13 @@ function avoidOverlap(
     }
 }
 
-function isPositionCenter(layout: LabelLayout) {
+function isPositionCenter(sectorShape: LabelLayout) {
     // Not change x for center label
-    return layout.position === 'center';
+    return sectorShape.position === 'center';
 }
 
 export default function (
-    seriesModel: PieSeriesModel,
-    r: number,
-    viewWidth: number,
-    viewHeight: number,
-    viewLeft: number,
-    viewTop: number
+    seriesModel: PieSeriesModel
 ) {
     const data = seriesModel.getData();
     const labelLayoutList: LabelLayout[] = [];
@@ -285,8 +284,18 @@ export default function (
     let hasLabelRotate = false;
     const minShowLabelRadian = (seriesModel.get('minShowLabelAngle') || 0) * RADIAN;
 
+    const viewRect = data.getLayout('viewRect') as RectLike;
+    const r = data.getLayout('r') as number;
+    const viewWidth = viewRect.width;
+    const viewLeft = viewRect.x;
+    const viewTop = viewRect.y;
+    const viewHeight = viewRect.height;
+
     data.each(function (idx) {
-        const layout = data.getItemLayout(idx);
+        const sector = data.getItemGraphicEl(idx) as Sector;
+        const sectorShape = sector.shape;
+        const label = sector.getTextContent();
+        const labelLine = sector.getTextGuideLine();
 
         const itemModel = data.getItemModel<PieDataItemOption>(idx);
         const labelModel = itemModel.getModel('label');
@@ -296,7 +305,6 @@ export default function (
         const labelAlignTo = labelModel.get('alignTo');
         const labelMargin = parsePercent(labelModel.get('margin'), viewWidth);
         const bleedMargin = labelModel.get('bleedMargin');
-        const font = labelModel.getFont();
 
         const labelLineModel = itemModel.getModel('labelLine');
         let labelLineLen = labelLineModel.get('length');
@@ -304,25 +312,23 @@ export default function (
         let labelLineLen2 = labelLineModel.get('length2');
         labelLineLen2 = parsePercent(labelLineLen2, viewWidth);
 
-        if (layout.angle < minShowLabelRadian) {
+        if (Math.abs(sectorShape.endAngle - sectorShape.startAngle) < minShowLabelRadian) {
             return;
         }
 
-        const midAngle = (layout.startAngle + layout.endAngle) / 2;
+        const midAngle = (sectorShape.startAngle + sectorShape.endAngle) / 2;
         const dx = Math.cos(midAngle);
         const dy = Math.sin(midAngle);
 
         let textX;
         let textY;
         let linePoints;
-        let textAlign;
+        let textAlign: ZRTextAlign;
 
-        cx = layout.cx;
-        cy = layout.cy;
+        cx = sectorShape.cx;
+        cy = sectorShape.cy;
 
-        const text = seriesModel.getFormattedLabel(idx, 'normal')
-                || data.getName(idx);
-        const textRect = textContain.getBoundingRect(text, font, textAlign, 'top');
+        const textRect = label.getBoundingRect().clone();
         // Text has a default 1px stroke. Exclude this.
         textRect.x -= 1;
         textRect.y -= 1;
@@ -331,21 +337,21 @@ export default function (
 
         const isLabelInside = labelPosition === 'inside' || labelPosition === 'inner';
         if (labelPosition === 'center') {
-            textX = layout.cx;
-            textY = layout.cy;
+            textX = sectorShape.cx;
+            textY = sectorShape.cy;
             textAlign = 'center';
         }
         else {
-            const x1 = (isLabelInside ? (layout.r + layout.r0) / 2 * dx : layout.r * dx) + cx;
-            const y1 = (isLabelInside ? (layout.r + layout.r0) / 2 * dy : layout.r * dy) + cy;
+            const x1 = (isLabelInside ? (sectorShape.r + sectorShape.r0) / 2 * dx : sectorShape.r * dx) + cx;
+            const y1 = (isLabelInside ? (sectorShape.r + sectorShape.r0) / 2 * dy : sectorShape.r * dy) + cy;
 
             textX = x1 + dx * 3;
             textY = y1 + dy * 3;
 
             if (!isLabelInside) {
                 // For roseType
-                const x2 = x1 + dx * (labelLineLen + r - layout.r);
-                const y2 = y1 + dy * (labelLineLen + r - layout.r);
+                const x2 = x1 + dx * (labelLineLen + r - sectorShape.r);
+                const y2 = y1 + dy * (labelLineLen + r - sectorShape.r);
                 const x3 = x2 + ((dx < 0 ? -1 : 1) * labelLineLen2);
                 const y3 = y2;
 
@@ -381,33 +387,69 @@ export default function (
         }
 
         hasLabelRotate = !!labelRotate;
-        layout.label = {
-            x: textX,
-            y: textY,
-            position: labelPosition,
-            height: textRect.height,
-            len: labelLineLen,
-            len2: labelLineLen2,
-            linePoints: linePoints,
-            textAlign: textAlign,
-            verticalAlign: 'middle',
-            rotation: labelRotate,
-            inside: isLabelInside,
-            labelDistance: labelDistance,
-            labelAlignTo: labelAlignTo,
-            labelMargin: labelMargin,
-            bleedMargin: bleedMargin,
-            textRect: textRect,
-            text: text,
-            font: font
-        };
-
-        // Not layout the inside label
+
+        // Not sectorShape the inside label
         if (!isLabelInside) {
-            labelLayoutList.push(layout.label);
+            labelLayoutList.push({
+                label,
+                labelLine,
+                x: textX,
+                y: textY,
+                position: labelPosition,
+                len: labelLineLen,
+                len2: labelLineLen2,
+                linePoints: linePoints,
+                textAlign: textAlign,
+                verticalAlign: 'middle',
+                rotation: labelRotate,
+                labelDistance: labelDistance,
+                labelAlignTo: labelAlignTo,
+                labelMargin: labelMargin,
+                bleedMargin: bleedMargin,
+                textRect: textRect
+            });
         }
+        sector.setTextConfig({
+            inside: isLabelInside
+        });
     });
+
     if (!hasLabelRotate && seriesModel.get('avoidLabelOverlap')) {
         avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight, viewLeft, viewTop);
     }
+
+    function setNotShow(el: {ignore: boolean}) {
+        el.ignore = true;
+    }
+
+    for (let i = 0; i < labelLayoutList.length; i++) {
+        const layout = labelLayoutList[i];
+        const label = layout.label;
+        const labelLine = layout.labelLine;
+        const notShowLabel = isNaN(layout.x) || isNaN(layout.y);
+        if (label) {
+            label.x = layout.x;
+            label.y = layout.y;
+            label.setStyle({
+                align: layout.textAlign,
+                verticalAlign: layout.verticalAlign
+            });
+            if (notShowLabel) {
+                each(label.states, setNotShow);
+                label.ignore = true;
+            }
+            const selectState = label.states.select;
+            if (selectState) {
+                selectState.x += layout.x;
+                selectState.y += layout.y;
+            }
+        }
+        if (labelLine) {
+            labelLine.setShape({ points: layout.linePoints });
+            if (notShowLabel) {
+                each(labelLine.states, setNotShow);
+                labelLine.ignore = true;
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/chart/pie/pieLayout.ts b/src/chart/pie/pieLayout.ts
index 5925c17..5a83f80 100644
--- a/src/chart/pie/pieLayout.ts
+++ b/src/chart/pie/pieLayout.ts
@@ -19,7 +19,6 @@
 
 import {parsePercent, linearMap} from '../../util/number';
 import * as layout from '../../util/layout';
-import labelLayout from './labelLayout';
 import * as zrUtil from 'zrender/src/core/util';
 import GlobalModel from '../../model/Global';
 import ExtensionAPI from '../../ExtensionAPI';
@@ -94,6 +93,8 @@ export default function (
         let currentAngle = startAngle;
         const dir = clockwise ? 1 : -1;
 
+        data.setLayout({ viewRect, r });
+
         data.each(valueDim, function (value: number, idx: number) {
             let angle;
             if (isNaN(value)) {
@@ -107,8 +108,7 @@ export default function (
                     r0: r0,
                     r: roseType
                         ? NaN
-                        : r,
-                    viewRect: viewRect
+                        : r
                 });
                 return;
             }
@@ -141,8 +141,7 @@ export default function (
                 r0: r0,
                 r: roseType
                     ? linearMap(value, extent, [r0, r])
-                    : r,
-                viewRect: viewRect
+                    : r
             });
 
             currentAngle = endAngle;
@@ -179,7 +178,5 @@ export default function (
                 });
             }
         }
-
-        labelLayout(seriesModel, r, viewRect.width, viewRect.height, viewRect.x, viewRect.y);
     });
 }
\ 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