From 9c84da7e79bbc0b871e50e614c09ea16deebc209 Mon Sep 17 00:00:00 2001 From: Ovilia Date: Thu, 12 Dec 2019 16:20:34 +0800 Subject: [PATCH 1/3] 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' From 8828be184b578f9f2bf2a912310ab550b9101554 Mon Sep 17 00:00:00 2001 From: Ovilia Date: Thu, 12 Dec 2019 16:24:13 +0800 Subject: [PATCH 2/3] test(markLine): add test cases for #11569 --- test/markLine.html | 93 +++++++++++++++++++++++++++++----------------- 1 file changed, 58 insertions(+), 35 deletions(-) diff --git a/test/markLine.html b/test/markLine.html index e0b343d0bb..38dde252f5 100644 --- a/test/markLine.html +++ b/test/markLine.html @@ -55,7 +55,61 @@ data2.push(+Math.random().toFixed(2)); } + var markLine1 = []; + var markLine2 = []; + var positions = [ + 'start', 'middle', 'end', + 'insideStart', 'insideStartTop', 'insideStartBottom', + 'insideMiddle', 'insideMiddleTop', 'insideMiddleBottom', + 'insideEnd', 'insideEndTop', 'insideEndBottom' + ]; + for (var i = 0; i < positions.length; ++i) { + markLine1.push({ + name: positions[i], + yAxis: 1.8 - 0.2 * Math.floor(i / 3), + label: { + formatter: '{b}', + position: positions[i] + } + }); + markLine1.push([{ + name: 'start: ' + positions[i], + type: 'min', + label: { + formatter: positions[i], + position: positions[i] + } + }, { + name: 'end: ' + positions[i], + type: 'max' + }]); + + markLine2.push({ + name: positions[i], + xAxis: Math.floor(i / 3), + label: { + formatter: '{b}', + position: positions[i] + } + }); + markLine2.push([{ + name: 'start: ' + positions[i], + type: 'min', + valueIndex: 0, + label: { + formatter: positions[i], + position: positions[i] + } + }, { + name: 'end: ' + positions[i], + valueIndex: 0, + type: 'max' + }]); + } + chart.setOption({ + animation: false, + color: ['#f60', '#0c6'], legend: { data: ['line', 'line2'] }, @@ -77,7 +131,8 @@ yAxis: { splitLine: { // show: false - } + }, + max: 2 }, series: [{ name: 'line', @@ -87,26 +142,7 @@ data: data1, markLine: { - data: [{ - name: '平均值', - type: 'average', - valueIndex: 1 - }, { - name: '指定值', - yAxis: 1 - }, [{ - name: '标签位置为中间', - type: 'min', - label: { - normal: { - formatter: '{b}', - position: 'middle' - } - } - }, { - name: '标签位置为中间', - type: 'max' - }]] + data: markLine1 } }, { name: 'line2', @@ -116,20 +152,7 @@ data: data2, markLine: { - data: [{ - name: '平均值', - type: 'average', - valueIndex: 0 - }, { - name: '指定值', - xAxis: 3 - }, [{ - name: '最大点', - type: 'max' - }, { - x: '90%', - yAxis: 'max' - }]] + data: markLine2 } }] }); From 6a604274a8d4ea639ec386af2534a1ff4fc2535b Mon Sep 17 00:00:00 2001 From: Ovilia Date: Thu, 19 Dec 2019 14:52:42 +0800 Subject: [PATCH 3/3] feat(markLine): support distance array. close #11569 --- src/chart/helper/Line.js | 27 +++++++++++++++++---------- test/markLine.html | 5 ++++- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/chart/helper/Line.js b/src/chart/helper/Line.js index e52dcc22ec..f2b2d8eed4 100644 --- a/src/chart/helper/Line.js +++ b/src/chart/helper/Line.js @@ -143,7 +143,9 @@ function updateSymbolAndLabelBeforeLineUpdate() { var textVerticalAlign; var textOrigin; - var distance = label.__labelDistance * invScale; + var distance = label.__labelDistance; + var distanceX = distance[0] * invScale; + var distanceY = distance[1] * invScale; var halfPercent = percent / 2; var tangent = line.tangentAt(halfPercent); var n = [tangent[1], -tangent[0]]; @@ -168,14 +170,14 @@ function updateSymbolAndLabelBeforeLineUpdate() { case 'insideMiddleTop': case 'insideEndTop': case 'middle': - dy = -distance; + dy = -distanceY; textVerticalAlign = 'bottom'; break; case 'insideStartBottom': case 'insideMiddleBottom': case 'insideEndBottom': - dy = distance; + dy = distanceY; textVerticalAlign = 'top'; break; @@ -186,13 +188,13 @@ function updateSymbolAndLabelBeforeLineUpdate() { switch (label.__position) { case 'end': - textPosition = [d[0] * distance + toPos[0], d[1] * distance + toPos[1]]; + textPosition = [d[0] * distanceX + toPos[0], d[1] * distanceY + 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]]; + textPosition = [-d[0] * distanceX + fromPos[0], -d[1] * distanceY + 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; @@ -200,9 +202,9 @@ function updateSymbolAndLabelBeforeLineUpdate() { case 'insideStartTop': case 'insideStart': case 'insideStartBottom': - textPosition = [distance * dir + fromPos[0], fromPos[1] + dy]; + textPosition = [distanceX * dir + fromPos[0], fromPos[1] + dy]; textAlign = tangent[0] < 0 ? 'right' : 'left'; - textOrigin = [-distance * dir, -dy]; + textOrigin = [-distanceX * dir, -dy]; break; case 'insideMiddleTop': @@ -217,9 +219,9 @@ function updateSymbolAndLabelBeforeLineUpdate() { case 'insideEndTop': case 'insideEnd': case 'insideEndBottom': - textPosition = [-distance * dir + toPos[0], toPos[1] + dy]; + textPosition = [-distanceX * dir + toPos[0], toPos[1] + dy]; textAlign = tangent[0] >= 0 ? 'right' : 'left'; - textOrigin = [distance * dir, -dy]; + textOrigin = [distanceX * dir, -dy]; break; } @@ -407,7 +409,12 @@ lineProto._updateCommonStl = function (lineData, idx, seriesScope) { label.__verticalAlign = labelStyle.textVerticalAlign; // 'start', 'middle', 'end' label.__position = labelModel.get('position') || 'middle'; - label.__labelDistance = labelModel.get('distance'); + + var distance = labelModel.get('distance'); + if (!zrUtil.isArray(distance)) { + distance = [distance, distance]; + } + label.__labelDistance = distance; } if (emphasisText != null) { diff --git a/test/markLine.html b/test/markLine.html index 38dde252f5..f887ceb3bb 100644 --- a/test/markLine.html +++ b/test/markLine.html @@ -152,7 +152,10 @@ data: data2, markLine: { - data: markLine2 + data: markLine2, + label: { + distance: [20, 5] + } } }] });