Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
x649585723
incubator-echarts
提交
2b8da727
I
incubator-echarts
项目概览
x649585723
/
incubator-echarts
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
I
incubator-echarts
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
2b8da727
编写于
4月 23, 2020
作者:
P
pissang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: improve label layouting. displayed by priority(default to be size of area).
上级
58097208
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
128 addition
and
97 deletion
+128
-97
src/util/LabelManager.ts
src/util/LabelManager.ts
+128
-97
未找到文件。
src/util/LabelManager.ts
浏览文件 @
2b8da727
...
...
@@ -28,8 +28,10 @@ import {
LabelLayoutOptionCallbackParams
}
from
'
./types
'
;
import
{
parsePercent
}
from
'
./number
'
;
import
SeriesModel
from
'
../model/Series
'
;
import
ChartView
from
'
../view/Chart
'
;
import
{
ElementTextConfig
}
from
'
zrender/src/Element
'
;
import
{
RectLike
}
from
'
zrender/src/core/BoundingRect
'
;
import
Transformable
from
'
zrender/src/core/Transformable
'
;
interface
DisplayedLabelItem
{
label
:
ZRText
...
...
@@ -40,58 +42,49 @@ interface DisplayedLabelItem {
transform
:
MatrixArray
}
interface
Label
Item
{
interface
Label
LayoutDesc
{
label
:
ZRText
seriesIndex
:
number
dataIndex
:
number
layoutOption
:
LabelLayoutOptionCallback
|
LabelLayoutOption
}
interface
LabelLayoutInnerConfig
{
overlap
:
LabelLayoutOption
[
'
overlap
'
]
overlapMargin
:
LabelLayoutOption
[
'
overlapMargin
'
]
hostRect
:
RectLike
priority
:
number
defaultAttr
:
SavedLabelAttr
}
interface
SavedLabelAttr
{
x
?:
number
y
?:
number
rotation
?:
number
align
?:
ZRTextAlign
verticalAlign
?:
ZRTextVerticalAlign
width
?:
number
height
?:
number
}
x
:
number
y
:
number
rotation
:
number
function
prepareLayoutCallbackParams
(
label
:
ZRText
,
dataIndex
:
number
,
seriesIndex
:
number
):
LabelLayoutOptionCallbackParams
{
const
host
=
label
.
__hostTarget
;
const
labelTransform
=
label
.
getComputedTransform
();
const
labelRect
=
label
.
getBoundingRect
().
plain
();
BoundingRect
.
applyTransform
(
labelRect
,
labelRect
,
labelTransform
);
let
x
=
0
;
let
y
=
0
;
if
(
labelTransform
)
{
x
=
labelTransform
[
4
];
y
=
labelTransform
[
5
];
}
align
:
ZRTextAlign
verticalAlign
:
ZRTextVerticalAlign
width
:
number
height
:
number
let
hostRect
;
if
(
host
)
{
hostRect
=
host
.
getBoundingRect
().
plain
();
const
transform
=
host
.
getComputedTransform
();
BoundingRect
.
applyTransform
(
hostRect
,
hostRect
,
transform
);
}
// Configuration in attached element
attachedPos
:
ElementTextConfig
[
'
position
'
]
attachedRot
:
ElementTextConfig
[
'
rotation
'
]
rect
:
RectLike
}
function
prepareLayoutCallbackParams
(
labelItem
:
LabelLayoutDesc
):
LabelLayoutOptionCallbackParams
{
const
labelAttr
=
labelItem
.
defaultAttr
;
const
label
=
labelItem
.
label
;
return
{
dataIndex
,
seriesIndex
,
text
:
label
.
style
.
text
,
rect
:
hostRect
,
labelRect
:
labelRect
,
x
,
y
,
dataIndex
:
labelItem
.
dataIndex
,
seriesIndex
:
labelItem
.
seriesIndex
,
text
:
labelItem
.
label
.
style
.
text
,
rect
:
labelItem
.
hostRect
,
labelRect
:
labelAttr
.
rect
,
x
:
labelAttr
.
x
,
y
:
labelAttr
.
y
,
align
:
label
.
style
.
align
,
verticalAlign
:
label
.
style
.
verticalAlign
};
...
...
@@ -99,20 +92,16 @@ function prepareLayoutCallbackParams(
const
LABEL_OPTION_TO_STYLE_KEYS
=
[
'
align
'
,
'
verticalAlign
'
,
'
width
'
,
'
height
'
]
as
const
;
c
lass
LabelManager
{
c
onst
dummyTransformable
=
new
Transformable
();
private
_labelList
:
LabelItem
[]
=
[];
private
_labelLayoutConfig
:
LabelLayoutInnerConfig
[]
=
[];
class
LabelManager
{
// Save default label attributes.
// For restore if developers want get back to default value in callback.
private
_defaultLabelAttr
:
SavedLabelAttr
[]
=
[];
private
_labelList
:
LabelLayoutDesc
[]
=
[];
constructor
()
{}
clearLabels
()
{
this
.
_labelList
=
[];
this
.
_labelLayoutConfig
=
[];
}
/**
...
...
@@ -122,26 +111,59 @@ class LabelManager {
* @param label
* @param layoutOption
*/
addLabel
(
dataIndex
:
number
,
seriesIndex
:
number
,
label
:
ZRText
,
layoutOption
:
LabelItem
[
'
layoutOption
'
])
{
addLabel
(
dataIndex
:
number
,
seriesIndex
:
number
,
label
:
ZRText
,
layoutOption
:
LabelLayoutDesc
[
'
layoutOption
'
])
{
const
labelStyle
=
label
.
style
;
const
hostEl
=
label
.
__hostTarget
;
const
textConfig
=
hostEl
.
textConfig
||
{};
const
labelTransform
=
label
.
getComputedTransform
();
const
labelRect
=
label
.
getBoundingRect
().
plain
();
BoundingRect
.
applyTransform
(
labelRect
,
labelRect
,
labelTransform
);
dummyTransformable
.
setLocalTransform
(
labelTransform
);
const
host
=
label
.
__hostTarget
;
let
hostRect
;
if
(
host
)
{
hostRect
=
host
.
getBoundingRect
().
plain
();
const
transform
=
host
.
getComputedTransform
();
BoundingRect
.
applyTransform
(
hostRect
,
hostRect
,
transform
);
}
this
.
_labelList
.
push
({
seriesIndex
,
dataIndex
,
label
,
layoutOption
});
// Push an empty config. Will be updated in updateLayoutConfig
this
.
_labelLayoutConfig
.
push
({}
as
LabelLayoutInnerConfig
);
layoutOption
,
const
labelStyle
=
label
.
style
;
this
.
_defaultLabelAttr
.
push
({
x
:
label
.
x
,
y
:
label
.
y
,
rotation
:
label
.
rotation
,
align
:
labelStyle
.
align
,
verticalAlign
:
labelStyle
.
verticalAlign
,
width
:
labelStyle
.
width
,
height
:
labelStyle
.
height
hostRect
,
overlap
:
'
hidden
'
,
overlapMargin
:
0
,
// Label with lower priority will be hidden when overlapped
// Use rect size as default priority
priority
:
hostRect
?
hostRect
.
width
*
hostRect
.
height
:
0
,
// Save default label attributes.
// For restore if developers want get back to default value in callback.
defaultAttr
:
{
x
:
dummyTransformable
.
x
,
y
:
dummyTransformable
.
y
,
rotation
:
dummyTransformable
.
rotation
,
rect
:
labelRect
,
align
:
labelStyle
.
align
,
verticalAlign
:
labelStyle
.
verticalAlign
,
width
:
labelStyle
.
width
,
height
:
labelStyle
.
height
,
attachedPos
:
textConfig
.
position
,
attachedRot
:
textConfig
.
rotation
}
});
}
addLabelsOfSeries
(
chartView
:
ChartView
)
{
...
...
@@ -168,12 +190,11 @@ class LabelManager {
const
labelItem
=
this
.
_labelList
[
i
];
const
label
=
labelItem
.
label
;
const
hostEl
=
label
.
__hostTarget
;
const
layoutConfig
=
this
.
_labelLayoutConfig
[
i
];
const
defaultLabelAttr
=
this
.
_defaultLabelAttr
[
i
];
const
defaultLabelAttr
=
labelItem
.
defaultAttr
;
let
layoutOption
;
if
(
typeof
labelItem
.
layoutOption
===
'
function
'
)
{
layoutOption
=
labelItem
.
layoutOption
(
prepareLayoutCallbackParams
(
label
,
labelItem
.
dataIndex
,
labelItem
.
seriesIndex
)
prepareLayoutCallbackParams
(
label
Item
)
);
}
else
{
...
...
@@ -181,48 +202,51 @@ class LabelManager {
}
layoutOption
=
layoutOption
||
{};
//
if (hostEl) {
// // Ignore position and rotation config on the host el.
// hostEl.setTextConfig({
// position: null,
// rotation: null
// });
// }
// label.x = layoutOption.x != null
// ? parsePercent(layoutOption.x, width)
// // Restore to default value if developers don't given a value.
// : defaultLabelAttr.x;
// label.y = layoutOption.y != null
// ? parsePercent(layoutOption.y, height)
// : defaultLabelAttr.y;
// label.rotation = layoutOption.rotation != null
// ? layoutOption.rotation : defaultLabelAttr.rotation
;
// label.x += layoutOption.dx || 0;
// label.y += layoutOption.dy || 0
;
//
for (let k = 0; k < LABEL_OPTION_TO_STYLE_KEYS.length; k++) {
//
const key = LABEL_OPTION_TO_STYLE_KEYS[k];
//
label.setStyle(key, layoutOption[key] != null ? layoutOption[key] : defaultLabelAttr[key]);
//
}
la
youtConfig
.
overlap
=
layoutOption
.
overlap
;
la
youtConfig
.
overlapMargin
=
layoutOption
.
overlapMargin
;
if
(
hostEl
)
{
hostEl
.
setTextConfig
({
// Ignore position and rotation config on the host el if x or y is changed.
position
:
(
layoutOption
.
x
!=
null
||
layoutOption
.
y
!=
null
)
?
null
:
defaultLabelAttr
.
attachedPos
,
// Ignore rotation config on the host el if rotation is changed.
rotation
:
layoutOption
.
rotation
!=
null
?
null
:
defaultLabelAttr
.
attachedRot
,
offset
:
[
layoutOption
.
dx
||
0
,
layoutOption
.
dy
||
0
]
});
}
label
.
x
=
layoutOption
.
x
!=
null
?
parsePercent
(
layoutOption
.
x
,
width
)
// Restore to default value if developers don't given a value.
:
defaultLabelAttr
.
x
;
label
.
y
=
layoutOption
.
y
!=
null
?
parsePercent
(
layoutOption
.
y
,
height
)
:
defaultLabelAttr
.
y
;
label
.
rotation
=
layoutOption
.
rotation
!=
null
?
layoutOption
.
rotation
:
defaultLabelAttr
.
rotation
;
for
(
let
k
=
0
;
k
<
LABEL_OPTION_TO_STYLE_KEYS
.
length
;
k
++
)
{
const
key
=
LABEL_OPTION_TO_STYLE_KEYS
[
k
];
label
.
setStyle
(
key
,
layoutOption
[
key
]
!=
null
?
layoutOption
[
key
]
:
defaultLabelAttr
[
key
]);
}
la
belItem
.
overlap
=
layoutOption
.
overlap
;
la
belItem
.
overlapMargin
=
layoutOption
.
overlapMargin
;
}
}
layout
()
{
// TODO: sort by priority
// TODO: sort by priority
(area)
const
labelList
=
this
.
_labelList
;
const
displayedLabels
:
DisplayedLabelItem
[]
=
[];
const
mvt
=
new
Point
();
labelList
.
sort
(
function
(
a
,
b
)
{
return
b
.
priority
-
a
.
priority
;
});
for
(
let
i
=
0
;
i
<
labelList
.
length
;
i
++
)
{
const
labelItem
=
labelList
[
i
];
const
layoutConfig
=
this
.
_labelLayoutConfig
[
i
];
const
label
=
labelItem
.
label
;
const
transform
=
label
.
getComputedTransform
();
// NOTE: Get bounding rect after getComputedTransform, or label may not been updated by the host el.
...
...
@@ -234,7 +258,7 @@ class LabelManager {
let
obb
=
isAxisAligned
?
new
OrientedBoundingRect
(
localRect
,
transform
)
:
null
;
let
overlapped
=
false
;
const
overlapMargin
=
la
youtConfig
.
overlapMargin
||
0
;
const
overlapMargin
=
la
belItem
.
overlapMargin
||
0
;
const
marginSqr
=
overlapMargin
*
overlapMargin
;
for
(
let
j
=
0
;
j
<
displayedLabels
.
length
;
j
++
)
{
const
existsTextCfg
=
displayedLabels
[
j
];
...
...
@@ -262,11 +286,18 @@ class LabelManager {
}
}
// TODO Callback to determine if this overlap should be handled?
if
(
overlapped
)
{
label
.
hide
();
// label.setStyle({ opacity: 0.1 });
// label.z = 0;
// Use invisible instead of ignore because ignored label won't be updated in the host.
label
.
attr
(
'
invisible
'
,
true
);
}
else
{
label
.
show
();
// TODO Restore z
// label.setStyle({ opacity: 1 });
label
.
attr
(
'
invisible
'
,
false
);
displayedLabels
.
push
({
label
,
rect
:
globalRect
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录