From 89221c831217f0b17da5f88d6f3c2426ca64ee9a Mon Sep 17 00:00:00 2001 From: Ovilia Date: Thu, 12 Dec 2019 16:20:34 +0800 Subject: [PATCH] feat(markLine): provide new layouts for markLine labels #11569 --- src/chart/helper/Line.js | 103 +++++++++++++++++++------- src/component/marker/MarkLineModel.js | 3 +- 2 files changed, 79 insertions(+), 27 deletions(-) diff --git a/src/chart/helper/Line.js b/src/chart/helper/Line.js index 2b81a7a432..e52dcc22ec 100644 --- a/src/chart/helper/Line.js +++ b/src/chart/helper/Line.js @@ -141,39 +141,88 @@ function updateSymbolAndLabelBeforeLineUpdate() { var textPosition; var textAlign; var textVerticalAlign; - - var distance = 5 * invScale; - // End - if (label.__position === 'end') { - textPosition = [d[0] * distance + toPos[0], d[1] * distance + toPos[1]]; - textAlign = d[0] > 0.8 ? 'left' : (d[0] < -0.8 ? 'right' : 'center'); - textVerticalAlign = d[1] > 0.8 ? 'top' : (d[1] < -0.8 ? 'bottom' : 'middle'); + var textOrigin; + + var distance = label.__labelDistance * invScale; + var halfPercent = percent / 2; + var tangent = line.tangentAt(halfPercent); + var n = [tangent[1], -tangent[0]]; + var cp = line.pointAt(halfPercent); + if (n[1] > 0) { + n[0] = -n[0]; + n[1] = -n[1]; } - // Middle - else if (label.__position === 'middle') { - var halfPercent = percent / 2; - var tangent = line.tangentAt(halfPercent); - var n = [tangent[1], -tangent[0]]; - var cp = line.pointAt(halfPercent); - if (n[1] > 0) { - n[0] = -n[0]; - n[1] = -n[1]; - } - textPosition = [cp[0] + n[0] * distance, cp[1] + n[1] * distance]; - textAlign = 'center'; - textVerticalAlign = 'bottom'; + var dir = tangent[0] < 0 ? -1 : 1; + + if (label.__position !== 'start' && label.__position !== 'end') { var rotation = -Math.atan2(tangent[1], tangent[0]); if (toPos[0] < fromPos[0]) { rotation = Math.PI + rotation; } label.attr('rotation', rotation); } - // Start - else { - textPosition = [-d[0] * distance + fromPos[0], -d[1] * distance + fromPos[1]]; - textAlign = d[0] > 0.8 ? 'right' : (d[0] < -0.8 ? 'left' : 'center'); - textVerticalAlign = d[1] > 0.8 ? 'bottom' : (d[1] < -0.8 ? 'top' : 'middle'); + + var dy; + switch (label.__position) { + case 'insideStartTop': + case 'insideMiddleTop': + case 'insideEndTop': + case 'middle': + dy = -distance; + textVerticalAlign = 'bottom'; + break; + + case 'insideStartBottom': + case 'insideMiddleBottom': + case 'insideEndBottom': + dy = distance; + textVerticalAlign = 'top'; + break; + + default: + dy = 0; + textVerticalAlign = 'middle'; } + + switch (label.__position) { + case 'end': + textPosition = [d[0] * distance + toPos[0], d[1] * distance + toPos[1]]; + textAlign = d[0] > 0.8 ? 'left' : (d[0] < -0.8 ? 'right' : 'center'); + textVerticalAlign = d[1] > 0.8 ? 'top' : (d[1] < -0.8 ? 'bottom' : 'middle'); + break; + + case 'start': + textPosition = [-d[0] * distance + fromPos[0], -d[1] * distance + fromPos[1]]; + textAlign = d[0] > 0.8 ? 'right' : (d[0] < -0.8 ? 'left' : 'center'); + textVerticalAlign = d[1] > 0.8 ? 'bottom' : (d[1] < -0.8 ? 'top' : 'middle'); + break; + + case 'insideStartTop': + case 'insideStart': + case 'insideStartBottom': + textPosition = [distance * dir + fromPos[0], fromPos[1] + dy]; + textAlign = tangent[0] < 0 ? 'right' : 'left'; + textOrigin = [-distance * dir, -dy]; + break; + + case 'insideMiddleTop': + case 'insideMiddle': + case 'insideMiddleBottom': + case 'middle': + textPosition = [cp[0], cp[1] + dy]; + textAlign = 'center'; + textOrigin = [0, -dy]; + break; + + case 'insideEndTop': + case 'insideEnd': + case 'insideEndBottom': + textPosition = [-distance * dir + toPos[0], toPos[1] + dy]; + textAlign = tangent[0] >= 0 ? 'right' : 'left'; + textOrigin = [distance * dir, -dy]; + break; + } + label.attr({ style: { // Use the user specified text align and baseline first @@ -181,7 +230,8 @@ function updateSymbolAndLabelBeforeLineUpdate() { textAlign: label.__textAlign || textAlign }, position: textPosition, - scale: [invScale, invScale] + scale: [invScale, invScale], + origin: textOrigin }); } } @@ -357,6 +407,7 @@ lineProto._updateCommonStl = function (lineData, idx, seriesScope) { label.__verticalAlign = labelStyle.textVerticalAlign; // 'start', 'middle', 'end' label.__position = labelModel.get('position') || 'middle'; + label.__labelDistance = labelModel.get('distance'); } if (emphasisText != null) { diff --git a/src/component/marker/MarkLineModel.js b/src/component/marker/MarkLineModel.js index f241fce1d8..077e5b95a9 100644 --- a/src/component/marker/MarkLineModel.js +++ b/src/component/marker/MarkLineModel.js @@ -38,7 +38,8 @@ export default MarkerModel.extend({ }, label: { show: true, - position: 'end' + position: 'end', + distance: 5 }, lineStyle: { type: 'dashed'