mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[maps] fix size legend does not indicate when min or max clamped by std range (#156927)
Fixes https://github.com/elastic/kibana/issues/156907 and https://github.com/elastic/kibana/issues/133810 Display `>` when max is clamped by standard deviation <img width="200" alt="Screen Shot 2023-05-05 at 3 33 11 PM" src="https://user-images.githubusercontent.com/373691/236572440-a0395094-5a70-45f8-b64a-dd4ecdc1412a.png"> Bottom label is not cut off when pixel size is 1 <img width="200" alt="Screen Shot 2023-05-05 at 3 33 18 PM" src="https://user-images.githubusercontent.com/373691/236572444-51b5af9e-fa31-4033-a671-0a9642d10e3e.png"> --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
094b62a6d6
commit
ff8cebb407
12 changed files with 1485 additions and 347 deletions
|
@ -0,0 +1,958 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Should invert legend 1`] = `
|
||||
<div>
|
||||
<EuiFlexGroup
|
||||
gutterSize="xs"
|
||||
justifyContent="spaceBetween"
|
||||
>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<EuiToolTip
|
||||
content="bytes"
|
||||
delay="regular"
|
||||
display="inlineBlock"
|
||||
position="top"
|
||||
title="Symbol size"
|
||||
>
|
||||
<EuiText
|
||||
className="eui-textTruncate"
|
||||
size="xs"
|
||||
style={
|
||||
Object {
|
||||
"maxWidth": "180px",
|
||||
}
|
||||
}
|
||||
>
|
||||
<small>
|
||||
<strong>
|
||||
bytes
|
||||
</strong>
|
||||
</small>
|
||||
</EuiText>
|
||||
</EuiToolTip>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<svg
|
||||
height={55}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g
|
||||
key="7"
|
||||
>
|
||||
<line
|
||||
style={
|
||||
Object {
|
||||
"stroke": "#d3dae6",
|
||||
}
|
||||
}
|
||||
x1={25}
|
||||
x2={56.25}
|
||||
y1={40}
|
||||
y2={40}
|
||||
/>
|
||||
<RightAlignedText
|
||||
setWidth={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fill": "#343741",
|
||||
"fontSize": 10,
|
||||
}
|
||||
}
|
||||
value="19KB"
|
||||
x={61.25}
|
||||
y={45}
|
||||
/>
|
||||
<circle
|
||||
cx={25}
|
||||
cy={47}
|
||||
r={7}
|
||||
style={
|
||||
Object {
|
||||
"fillOpacity": 0,
|
||||
"stroke": "#343741",
|
||||
"strokeWidth": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</g>
|
||||
<g
|
||||
key="15.5"
|
||||
>
|
||||
<line
|
||||
style={
|
||||
Object {
|
||||
"stroke": "#d3dae6",
|
||||
}
|
||||
}
|
||||
x1={25}
|
||||
x2={56.25}
|
||||
y1={23}
|
||||
y2={23}
|
||||
/>
|
||||
<RightAlignedText
|
||||
setWidth={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fill": "#343741",
|
||||
"fontSize": 10,
|
||||
}
|
||||
}
|
||||
value="14.25KB"
|
||||
x={61.25}
|
||||
y={28}
|
||||
/>
|
||||
<circle
|
||||
cx={25}
|
||||
cy={38.5}
|
||||
r={15.5}
|
||||
style={
|
||||
Object {
|
||||
"fillOpacity": 0,
|
||||
"stroke": "#343741",
|
||||
"strokeWidth": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</g>
|
||||
<g
|
||||
key="24"
|
||||
>
|
||||
<line
|
||||
style={
|
||||
Object {
|
||||
"stroke": "#d3dae6",
|
||||
}
|
||||
}
|
||||
x1={25}
|
||||
x2={56.25}
|
||||
y1={6}
|
||||
y2={6}
|
||||
/>
|
||||
<RightAlignedText
|
||||
setWidth={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fill": "#343741",
|
||||
"fontSize": 10,
|
||||
}
|
||||
}
|
||||
value="0KB"
|
||||
x={61.25}
|
||||
y={11}
|
||||
/>
|
||||
<circle
|
||||
cx={25}
|
||||
cy={30}
|
||||
r={24}
|
||||
style={
|
||||
Object {
|
||||
"fillOpacity": 0,
|
||||
"stroke": "#343741",
|
||||
"strokeWidth": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Should render legend 1`] = `
|
||||
<div>
|
||||
<EuiFlexGroup
|
||||
gutterSize="xs"
|
||||
justifyContent="spaceBetween"
|
||||
>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<EuiToolTip
|
||||
content="bytes"
|
||||
delay="regular"
|
||||
display="inlineBlock"
|
||||
position="top"
|
||||
title="Symbol size"
|
||||
>
|
||||
<EuiText
|
||||
className="eui-textTruncate"
|
||||
size="xs"
|
||||
style={
|
||||
Object {
|
||||
"maxWidth": "180px",
|
||||
}
|
||||
}
|
||||
>
|
||||
<small>
|
||||
<strong>
|
||||
bytes
|
||||
</strong>
|
||||
</small>
|
||||
</EuiText>
|
||||
</EuiToolTip>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<svg
|
||||
height={71}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g
|
||||
key="7"
|
||||
>
|
||||
<line
|
||||
style={
|
||||
Object {
|
||||
"stroke": "#d3dae6",
|
||||
}
|
||||
}
|
||||
x1={33}
|
||||
x2={74.25}
|
||||
y1={56}
|
||||
y2={56}
|
||||
/>
|
||||
<RightAlignedText
|
||||
setWidth={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fill": "#343741",
|
||||
"fontSize": 10,
|
||||
}
|
||||
}
|
||||
value="0KB"
|
||||
x={79.25}
|
||||
y={61}
|
||||
/>
|
||||
<circle
|
||||
cx={33}
|
||||
cy={63}
|
||||
r={7}
|
||||
style={
|
||||
Object {
|
||||
"fillOpacity": 0,
|
||||
"stroke": "#343741",
|
||||
"strokeWidth": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</g>
|
||||
<g
|
||||
key="13.25"
|
||||
>
|
||||
<line
|
||||
style={
|
||||
Object {
|
||||
"stroke": "#d3dae6",
|
||||
}
|
||||
}
|
||||
x1={33}
|
||||
x2={74.25}
|
||||
y1={43.5}
|
||||
y2={43.5}
|
||||
/>
|
||||
<RightAlignedText
|
||||
setWidth={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fill": "#343741",
|
||||
"fontSize": 10,
|
||||
}
|
||||
}
|
||||
value="1.188KB"
|
||||
x={79.25}
|
||||
y={48.5}
|
||||
/>
|
||||
<circle
|
||||
cx={33}
|
||||
cy={56.75}
|
||||
r={13.25}
|
||||
style={
|
||||
Object {
|
||||
"fillOpacity": 0,
|
||||
"stroke": "#343741",
|
||||
"strokeWidth": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</g>
|
||||
<g
|
||||
key="19.5"
|
||||
>
|
||||
<line
|
||||
style={
|
||||
Object {
|
||||
"stroke": "#d3dae6",
|
||||
}
|
||||
}
|
||||
x1={33}
|
||||
x2={74.25}
|
||||
y1={31}
|
||||
y2={31}
|
||||
/>
|
||||
<RightAlignedText
|
||||
setWidth={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fill": "#343741",
|
||||
"fontSize": 10,
|
||||
}
|
||||
}
|
||||
value="4.75KB"
|
||||
x={79.25}
|
||||
y={36}
|
||||
/>
|
||||
<circle
|
||||
cx={33}
|
||||
cy={50.5}
|
||||
r={19.5}
|
||||
style={
|
||||
Object {
|
||||
"fillOpacity": 0,
|
||||
"stroke": "#343741",
|
||||
"strokeWidth": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</g>
|
||||
<g
|
||||
key="25.75"
|
||||
>
|
||||
<line
|
||||
style={
|
||||
Object {
|
||||
"stroke": "#d3dae6",
|
||||
}
|
||||
}
|
||||
x1={33}
|
||||
x2={74.25}
|
||||
y1={18.5}
|
||||
y2={18.5}
|
||||
/>
|
||||
<RightAlignedText
|
||||
setWidth={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fill": "#343741",
|
||||
"fontSize": 10,
|
||||
}
|
||||
}
|
||||
value="10.688KB"
|
||||
x={79.25}
|
||||
y={23.5}
|
||||
/>
|
||||
<circle
|
||||
cx={33}
|
||||
cy={44.25}
|
||||
r={25.75}
|
||||
style={
|
||||
Object {
|
||||
"fillOpacity": 0,
|
||||
"stroke": "#343741",
|
||||
"strokeWidth": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</g>
|
||||
<g
|
||||
key="32"
|
||||
>
|
||||
<line
|
||||
style={
|
||||
Object {
|
||||
"stroke": "#d3dae6",
|
||||
}
|
||||
}
|
||||
x1={33}
|
||||
x2={74.25}
|
||||
y1={6}
|
||||
y2={6}
|
||||
/>
|
||||
<RightAlignedText
|
||||
setWidth={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fill": "#343741",
|
||||
"fontSize": 10,
|
||||
}
|
||||
}
|
||||
value="19KB"
|
||||
x={79.25}
|
||||
y={11}
|
||||
/>
|
||||
<circle
|
||||
cx={33}
|
||||
cy={38}
|
||||
r={32}
|
||||
style={
|
||||
Object {
|
||||
"fillOpacity": 0,
|
||||
"stroke": "#343741",
|
||||
"strokeWidth": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Should render legend with 2 markers when size difference does not provide enough vertical space for more labels 1`] = `
|
||||
<div>
|
||||
<EuiFlexGroup
|
||||
gutterSize="xs"
|
||||
justifyContent="spaceBetween"
|
||||
>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<EuiToolTip
|
||||
content="bytes"
|
||||
delay="regular"
|
||||
display="inlineBlock"
|
||||
position="top"
|
||||
title="Symbol size"
|
||||
>
|
||||
<EuiText
|
||||
className="eui-textTruncate"
|
||||
size="xs"
|
||||
style={
|
||||
Object {
|
||||
"maxWidth": "180px",
|
||||
}
|
||||
}
|
||||
>
|
||||
<small>
|
||||
<strong>
|
||||
bytes
|
||||
</strong>
|
||||
</small>
|
||||
</EuiText>
|
||||
</EuiToolTip>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<svg
|
||||
height={37}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g
|
||||
key="7"
|
||||
>
|
||||
<line
|
||||
style={
|
||||
Object {
|
||||
"stroke": "#d3dae6",
|
||||
}
|
||||
}
|
||||
x1={16}
|
||||
x2={36}
|
||||
y1={22}
|
||||
y2={22}
|
||||
/>
|
||||
<RightAlignedText
|
||||
setWidth={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fill": "#343741",
|
||||
"fontSize": 10,
|
||||
}
|
||||
}
|
||||
value="0KB"
|
||||
x={41}
|
||||
y={27}
|
||||
/>
|
||||
<circle
|
||||
cx={16}
|
||||
cy={29}
|
||||
r={7}
|
||||
style={
|
||||
Object {
|
||||
"fillOpacity": 0,
|
||||
"stroke": "#343741",
|
||||
"strokeWidth": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</g>
|
||||
<g
|
||||
key="15"
|
||||
>
|
||||
<line
|
||||
style={
|
||||
Object {
|
||||
"stroke": "#d3dae6",
|
||||
}
|
||||
}
|
||||
x1={16}
|
||||
x2={36}
|
||||
y1={6}
|
||||
y2={6}
|
||||
/>
|
||||
<RightAlignedText
|
||||
setWidth={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fill": "#343741",
|
||||
"fontSize": 10,
|
||||
}
|
||||
}
|
||||
value="19KB"
|
||||
x={41}
|
||||
y={11}
|
||||
/>
|
||||
<circle
|
||||
cx={16}
|
||||
cy={21}
|
||||
r={15}
|
||||
style={
|
||||
Object {
|
||||
"fillOpacity": 0,
|
||||
"stroke": "#343741",
|
||||
"strokeWidth": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Should render legend with 3 markers when size difference does not provide enough vertical space for more labels 1`] = `
|
||||
<div>
|
||||
<EuiFlexGroup
|
||||
gutterSize="xs"
|
||||
justifyContent="spaceBetween"
|
||||
>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<EuiToolTip
|
||||
content="bytes"
|
||||
delay="regular"
|
||||
display="inlineBlock"
|
||||
position="top"
|
||||
title="Symbol size"
|
||||
>
|
||||
<EuiText
|
||||
className="eui-textTruncate"
|
||||
size="xs"
|
||||
style={
|
||||
Object {
|
||||
"maxWidth": "180px",
|
||||
}
|
||||
}
|
||||
>
|
||||
<small>
|
||||
<strong>
|
||||
bytes
|
||||
</strong>
|
||||
</small>
|
||||
</EuiText>
|
||||
</EuiToolTip>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<svg
|
||||
height={55}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g
|
||||
key="7"
|
||||
>
|
||||
<line
|
||||
style={
|
||||
Object {
|
||||
"stroke": "#d3dae6",
|
||||
}
|
||||
}
|
||||
x1={25}
|
||||
x2={56.25}
|
||||
y1={40}
|
||||
y2={40}
|
||||
/>
|
||||
<RightAlignedText
|
||||
setWidth={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fill": "#343741",
|
||||
"fontSize": 10,
|
||||
}
|
||||
}
|
||||
value="0KB"
|
||||
x={61.25}
|
||||
y={45}
|
||||
/>
|
||||
<circle
|
||||
cx={25}
|
||||
cy={47}
|
||||
r={7}
|
||||
style={
|
||||
Object {
|
||||
"fillOpacity": 0,
|
||||
"stroke": "#343741",
|
||||
"strokeWidth": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</g>
|
||||
<g
|
||||
key="15.5"
|
||||
>
|
||||
<line
|
||||
style={
|
||||
Object {
|
||||
"stroke": "#d3dae6",
|
||||
}
|
||||
}
|
||||
x1={25}
|
||||
x2={56.25}
|
||||
y1={23}
|
||||
y2={23}
|
||||
/>
|
||||
<RightAlignedText
|
||||
setWidth={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fill": "#343741",
|
||||
"fontSize": 10,
|
||||
}
|
||||
}
|
||||
value="4.75KB"
|
||||
x={61.25}
|
||||
y={28}
|
||||
/>
|
||||
<circle
|
||||
cx={25}
|
||||
cy={38.5}
|
||||
r={15.5}
|
||||
style={
|
||||
Object {
|
||||
"fillOpacity": 0,
|
||||
"stroke": "#343741",
|
||||
"strokeWidth": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</g>
|
||||
<g
|
||||
key="24"
|
||||
>
|
||||
<line
|
||||
style={
|
||||
Object {
|
||||
"stroke": "#d3dae6",
|
||||
}
|
||||
}
|
||||
x1={25}
|
||||
x2={56.25}
|
||||
y1={6}
|
||||
y2={6}
|
||||
/>
|
||||
<RightAlignedText
|
||||
setWidth={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fill": "#343741",
|
||||
"fontSize": 10,
|
||||
}
|
||||
}
|
||||
value="19KB"
|
||||
x={61.25}
|
||||
y={11}
|
||||
/>
|
||||
<circle
|
||||
cx={25}
|
||||
cy={30}
|
||||
r={24}
|
||||
style={
|
||||
Object {
|
||||
"fillOpacity": 0,
|
||||
"stroke": "#343741",
|
||||
"strokeWidth": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Should render legend with only max marker when size difference does not provide enough vertical space for more labels 1`] = `
|
||||
<div>
|
||||
<EuiFlexGroup
|
||||
gutterSize="xs"
|
||||
justifyContent="spaceBetween"
|
||||
>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<EuiToolTip
|
||||
content="bytes"
|
||||
delay="regular"
|
||||
display="inlineBlock"
|
||||
position="top"
|
||||
title="Symbol size"
|
||||
>
|
||||
<EuiText
|
||||
className="eui-textTruncate"
|
||||
size="xs"
|
||||
style={
|
||||
Object {
|
||||
"maxWidth": "180px",
|
||||
}
|
||||
}
|
||||
>
|
||||
<small>
|
||||
<strong>
|
||||
bytes
|
||||
</strong>
|
||||
</small>
|
||||
</EuiText>
|
||||
</EuiToolTip>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<svg
|
||||
height={29}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g
|
||||
key="11"
|
||||
>
|
||||
<line
|
||||
style={
|
||||
Object {
|
||||
"stroke": "#d3dae6",
|
||||
}
|
||||
}
|
||||
x1={12}
|
||||
x2={27}
|
||||
y1={6}
|
||||
y2={6}
|
||||
/>
|
||||
<RightAlignedText
|
||||
setWidth={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fill": "#343741",
|
||||
"fontSize": 10,
|
||||
}
|
||||
}
|
||||
value="19KB"
|
||||
x={32}
|
||||
y={11}
|
||||
/>
|
||||
<circle
|
||||
cx={12}
|
||||
cy={17}
|
||||
r={11}
|
||||
style={
|
||||
Object {
|
||||
"fillOpacity": 0,
|
||||
"stroke": "#343741",
|
||||
"strokeWidth": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Should render legend without label cutoff when min size is 1 1`] = `
|
||||
<div>
|
||||
<EuiFlexGroup
|
||||
gutterSize="xs"
|
||||
justifyContent="spaceBetween"
|
||||
>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<EuiToolTip
|
||||
content="bytes"
|
||||
delay="regular"
|
||||
display="inlineBlock"
|
||||
position="top"
|
||||
title="Symbol size"
|
||||
>
|
||||
<EuiText
|
||||
className="eui-textTruncate"
|
||||
size="xs"
|
||||
style={
|
||||
Object {
|
||||
"maxWidth": "180px",
|
||||
}
|
||||
}
|
||||
>
|
||||
<small>
|
||||
<strong>
|
||||
bytes
|
||||
</strong>
|
||||
</small>
|
||||
</EuiText>
|
||||
</EuiToolTip>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<svg
|
||||
height={21}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g
|
||||
key="1"
|
||||
>
|
||||
<line
|
||||
style={
|
||||
Object {
|
||||
"stroke": "#d3dae6",
|
||||
}
|
||||
}
|
||||
x1={8}
|
||||
x2={18}
|
||||
y1={18}
|
||||
y2={18}
|
||||
/>
|
||||
<RightAlignedText
|
||||
setWidth={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fill": "#343741",
|
||||
"fontSize": 10,
|
||||
}
|
||||
}
|
||||
value="0KB"
|
||||
x={23}
|
||||
y={21}
|
||||
/>
|
||||
<circle
|
||||
cx={8}
|
||||
cy={19}
|
||||
r={1}
|
||||
style={
|
||||
Object {
|
||||
"fillOpacity": 0,
|
||||
"stroke": "#343741",
|
||||
"strokeWidth": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</g>
|
||||
<g
|
||||
key="7"
|
||||
>
|
||||
<line
|
||||
style={
|
||||
Object {
|
||||
"stroke": "#d3dae6",
|
||||
}
|
||||
}
|
||||
x1={8}
|
||||
x2={18}
|
||||
y1={6}
|
||||
y2={6}
|
||||
/>
|
||||
<RightAlignedText
|
||||
setWidth={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fill": "#343741",
|
||||
"fontSize": 10,
|
||||
}
|
||||
}
|
||||
value="19KB"
|
||||
x={23}
|
||||
y={11}
|
||||
/>
|
||||
<circle
|
||||
cx={8}
|
||||
cy={13}
|
||||
r={7}
|
||||
style={
|
||||
Object {
|
||||
"fillOpacity": 0,
|
||||
"stroke": "#343741",
|
||||
"strokeWidth": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Should render max label with std clamp notification 1`] = `
|
||||
<div>
|
||||
<EuiFlexGroup
|
||||
gutterSize="xs"
|
||||
justifyContent="spaceBetween"
|
||||
>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<EuiToolTip
|
||||
content="bytes"
|
||||
delay="regular"
|
||||
display="inlineBlock"
|
||||
position="top"
|
||||
title="Symbol size"
|
||||
>
|
||||
<EuiText
|
||||
className="eui-textTruncate"
|
||||
size="xs"
|
||||
style={
|
||||
Object {
|
||||
"maxWidth": "180px",
|
||||
}
|
||||
}
|
||||
>
|
||||
<small>
|
||||
<strong>
|
||||
bytes
|
||||
</strong>
|
||||
</small>
|
||||
</EuiText>
|
||||
</EuiToolTip>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<svg
|
||||
height={29}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g
|
||||
key="11"
|
||||
>
|
||||
<line
|
||||
style={
|
||||
Object {
|
||||
"stroke": "#d3dae6",
|
||||
}
|
||||
}
|
||||
x1={12}
|
||||
x2={27}
|
||||
y1={6}
|
||||
y2={6}
|
||||
/>
|
||||
<RightAlignedText
|
||||
setWidth={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fill": "#343741",
|
||||
"fontSize": 10,
|
||||
}
|
||||
}
|
||||
value="> 16KB"
|
||||
x={32}
|
||||
y={11}
|
||||
/>
|
||||
<circle
|
||||
cx={12}
|
||||
cy={17}
|
||||
r={11}
|
||||
style={
|
||||
Object {
|
||||
"fillOpacity": 0,
|
||||
"stroke": "#343741",
|
||||
"strokeWidth": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
`;
|
|
@ -0,0 +1,77 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Should render legend 1`] = `
|
||||
<RangedStyleLegendRow
|
||||
fieldLabel="bytes"
|
||||
header={
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
gutterSize="xs"
|
||||
justifyContent="spaceBetween"
|
||||
>
|
||||
<React.Fragment>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<CircleIcon
|
||||
style={
|
||||
Object {
|
||||
"fill": "none",
|
||||
"stroke": "grey",
|
||||
"strokeWidth": "1px",
|
||||
"width": "12px",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiHorizontalRule
|
||||
margin="xs"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</React.Fragment>
|
||||
<React.Fragment>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<CircleIcon
|
||||
style={
|
||||
Object {
|
||||
"fill": "none",
|
||||
"stroke": "grey",
|
||||
"strokeWidth": "2px",
|
||||
"width": "12px",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiHorizontalRule
|
||||
margin="xs"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</React.Fragment>
|
||||
<React.Fragment>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<CircleIcon
|
||||
style={
|
||||
Object {
|
||||
"fill": "none",
|
||||
"stroke": "grey",
|
||||
"strokeWidth": "3px",
|
||||
"width": "12px",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</React.Fragment>
|
||||
</EuiFlexGroup>
|
||||
}
|
||||
invert={false}
|
||||
maxLabel="19KB"
|
||||
minLabel="0KB"
|
||||
propertyLabel="Border width"
|
||||
/>
|
||||
`;
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export function getMaxLabel(
|
||||
isFieldMetaEnabled: boolean,
|
||||
isMaxOutsideStdRange: boolean,
|
||||
max: number | string
|
||||
) {
|
||||
return isFieldMetaEnabled && isMaxOutsideStdRange ? `> ${max}` : max;
|
||||
}
|
||||
|
||||
export function getMinLabel(
|
||||
isFieldMetaEnabled: boolean,
|
||||
isMinOutsideStdRange: boolean,
|
||||
min: number | string
|
||||
) {
|
||||
return isFieldMetaEnabled && isMinOutsideStdRange ? `< ${min}` : min;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export { MarkerSizeLegend } from './marker_size_legend';
|
||||
export { OrdinalLegend } from './ordinal_legend';
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
export interface Marker {
|
||||
svg: ReactNode;
|
||||
textY: number;
|
||||
}
|
||||
|
||||
export class MarkerList {
|
||||
private readonly _minFontDistance;
|
||||
private readonly _maxMarker;
|
||||
private readonly _markers: Marker[] = [];
|
||||
|
||||
constructor(fontSize: number, maxMarker: Marker) {
|
||||
this._minFontDistance = fontSize * 0.85;
|
||||
this._maxMarker = maxMarker;
|
||||
}
|
||||
|
||||
push(marker: Marker) {
|
||||
if (marker.textY - this._maxMarker.textY < this._minFontDistance) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._markers.length === 0) {
|
||||
this._markers.push(marker);
|
||||
return;
|
||||
}
|
||||
|
||||
// only push marker when there is enough vertical space to display text without collisions
|
||||
const prevMarker = this._markers[this._markers.length - 1];
|
||||
if (prevMarker.textY - marker.textY > this._minFontDistance) {
|
||||
this._markers.push(marker);
|
||||
}
|
||||
}
|
||||
|
||||
getMarkers() {
|
||||
const svgs = this._markers.map((marker: Marker) => {
|
||||
return marker.svg;
|
||||
});
|
||||
return [...svgs, this._maxMarker.svg];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import { FIELD_ORIGIN } from '../../../../../../../common/constants';
|
||||
import type { DynamicSizeProperty } from '../../../properties/dynamic_size_property';
|
||||
import type { IField } from '../../../../../fields/field';
|
||||
import { MarkerSizeLegend } from './marker_size_legend';
|
||||
|
||||
const dynamicSizeOptions = {
|
||||
minSize: 7,
|
||||
maxSize: 32,
|
||||
field: {
|
||||
name: 'bytes',
|
||||
origin: FIELD_ORIGIN.SOURCE,
|
||||
},
|
||||
fieldMetaOptions: {
|
||||
isEnabled: true,
|
||||
sigma: 3,
|
||||
},
|
||||
invert: false,
|
||||
};
|
||||
|
||||
const mockStyle = {
|
||||
formatField: (value: number) => {
|
||||
return `${value * 0.001}KB`;
|
||||
},
|
||||
getDisplayStyleName: () => {
|
||||
return 'Symbol size';
|
||||
},
|
||||
getField: () => {
|
||||
return {
|
||||
getLabel: () => {
|
||||
return 'bytes';
|
||||
},
|
||||
} as unknown as IField;
|
||||
},
|
||||
getOptions: () => {
|
||||
return dynamicSizeOptions;
|
||||
},
|
||||
getRangeFieldMeta: () => {
|
||||
return {
|
||||
min: 0,
|
||||
max: 19000,
|
||||
delta: 19000,
|
||||
};
|
||||
},
|
||||
isFieldMetaEnabled: () => {
|
||||
return true;
|
||||
},
|
||||
} as unknown as DynamicSizeProperty;
|
||||
|
||||
test('Should render legend', async () => {
|
||||
const component = shallow(<MarkerSizeLegend style={mockStyle} />);
|
||||
// Ensure all promises resolve
|
||||
await new Promise((resolve) => process.nextTick(resolve));
|
||||
// Ensure the state changes are reflected
|
||||
component.update();
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Should render legend with 3 markers when size difference does not provide enough vertical space for more labels', async () => {
|
||||
const component = shallow(
|
||||
<MarkerSizeLegend
|
||||
style={
|
||||
{
|
||||
...mockStyle,
|
||||
getOptions: () => {
|
||||
return {
|
||||
...dynamicSizeOptions,
|
||||
maxSize: 24,
|
||||
};
|
||||
},
|
||||
} as unknown as DynamicSizeProperty
|
||||
}
|
||||
/>
|
||||
);
|
||||
// Ensure all promises resolve
|
||||
await new Promise((resolve) => process.nextTick(resolve));
|
||||
// Ensure the state changes are reflected
|
||||
component.update();
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Should render legend with 2 markers when size difference does not provide enough vertical space for more labels', async () => {
|
||||
const component = shallow(
|
||||
<MarkerSizeLegend
|
||||
style={
|
||||
{
|
||||
...mockStyle,
|
||||
getOptions: () => {
|
||||
return {
|
||||
...dynamicSizeOptions,
|
||||
maxSize: 15,
|
||||
};
|
||||
},
|
||||
} as unknown as DynamicSizeProperty
|
||||
}
|
||||
/>
|
||||
);
|
||||
// Ensure all promises resolve
|
||||
await new Promise((resolve) => process.nextTick(resolve));
|
||||
// Ensure the state changes are reflected
|
||||
component.update();
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Should render legend with only max marker when size difference does not provide enough vertical space for more labels', async () => {
|
||||
const component = shallow(
|
||||
<MarkerSizeLegend
|
||||
style={
|
||||
{
|
||||
...mockStyle,
|
||||
getOptions: () => {
|
||||
return {
|
||||
...dynamicSizeOptions,
|
||||
maxSize: 11,
|
||||
};
|
||||
},
|
||||
} as unknown as DynamicSizeProperty
|
||||
}
|
||||
/>
|
||||
);
|
||||
// Ensure all promises resolve
|
||||
await new Promise((resolve) => process.nextTick(resolve));
|
||||
// Ensure the state changes are reflected
|
||||
component.update();
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Should render legend without label cutoff when min size is 1', async () => {
|
||||
const component = shallow(
|
||||
<MarkerSizeLegend
|
||||
style={
|
||||
{
|
||||
...mockStyle,
|
||||
getOptions: () => {
|
||||
return {
|
||||
...dynamicSizeOptions,
|
||||
minSize: 1,
|
||||
maxSize: 7,
|
||||
};
|
||||
},
|
||||
} as unknown as DynamicSizeProperty
|
||||
}
|
||||
/>
|
||||
);
|
||||
// Ensure all promises resolve
|
||||
await new Promise((resolve) => process.nextTick(resolve));
|
||||
// Ensure the state changes are reflected
|
||||
component.update();
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Should render max label with std clamp notification', async () => {
|
||||
const component = shallow(
|
||||
<MarkerSizeLegend
|
||||
style={
|
||||
{
|
||||
...mockStyle,
|
||||
getOptions: () => {
|
||||
return {
|
||||
...dynamicSizeOptions,
|
||||
maxSize: 11,
|
||||
};
|
||||
},
|
||||
getRangeFieldMeta: () => {
|
||||
return {
|
||||
min: 0,
|
||||
max: 16000,
|
||||
delta: 16000,
|
||||
isMaxOutsideStdRange: true,
|
||||
};
|
||||
},
|
||||
} as unknown as DynamicSizeProperty
|
||||
}
|
||||
/>
|
||||
);
|
||||
// Ensure all promises resolve
|
||||
await new Promise((resolve) => process.nextTick(resolve));
|
||||
// Ensure the state changes are reflected
|
||||
component.update();
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Should invert legend', async () => {
|
||||
const component = shallow(
|
||||
<MarkerSizeLegend
|
||||
style={
|
||||
{
|
||||
...mockStyle,
|
||||
getOptions: () => {
|
||||
return {
|
||||
...dynamicSizeOptions,
|
||||
maxSize: 24,
|
||||
invert: true,
|
||||
};
|
||||
},
|
||||
} as unknown as DynamicSizeProperty
|
||||
}
|
||||
/>
|
||||
);
|
||||
// Ensure all promises resolve
|
||||
await new Promise((resolve) => process.nextTick(resolve));
|
||||
// Ensure the state changes are reflected
|
||||
component.update();
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
|
@ -9,13 +9,14 @@ import React, { Component } from 'react';
|
|||
import _ from 'lodash';
|
||||
import { euiThemeVars } from '@kbn/ui-theme';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiText, EuiToolTip } from '@elastic/eui';
|
||||
import { RangeFieldMeta } from '../../../../../../common/descriptor_types';
|
||||
import { DynamicSizeProperty } from '../../properties/dynamic_size_property';
|
||||
import { RightAlignedText } from './right_aligned_text';
|
||||
import { RangeFieldMeta } from '../../../../../../../common/descriptor_types';
|
||||
import { DynamicSizeProperty } from '../../../properties/dynamic_size_property';
|
||||
import { RightAlignedText } from '../right_aligned_text';
|
||||
import { getMaxLabel, getMinLabel } from './get_ordinal_label';
|
||||
import { type Marker, MarkerList } from './marker_list';
|
||||
|
||||
const FONT_SIZE = 10;
|
||||
const HALF_FONT_SIZE = FONT_SIZE / 2;
|
||||
const MIN_MARKER_DISTANCE = (FONT_SIZE + 2) / 2;
|
||||
|
||||
const EMPTY_VALUE = '';
|
||||
|
||||
|
@ -103,29 +104,34 @@ export class MarkerSizeLegend extends Component<Props, State> {
|
|||
const circleCenterX = options.maxSize + circleStyle.strokeWidth;
|
||||
const circleBottomY = svgHeight - circleStyle.strokeWidth;
|
||||
|
||||
const makeMarker = (radius: number, formattedValue: string | number) => {
|
||||
const makeMarker = (radius: number, formattedValue: string | number): Marker => {
|
||||
const circleCenterY = circleBottomY - radius;
|
||||
const circleTopY = circleCenterY - radius;
|
||||
const textOffset = this.state.maxLabelWidth + HALF_FONT_SIZE;
|
||||
return (
|
||||
<g key={radius}>
|
||||
<line
|
||||
style={{ stroke: euiThemeVars.euiBorderColor }}
|
||||
x1={circleCenterX}
|
||||
y1={circleTopY}
|
||||
x2={circleCenterX * 2.25}
|
||||
y2={circleTopY}
|
||||
/>
|
||||
<RightAlignedText
|
||||
setWidth={this._onRightAlignedWidthChange}
|
||||
style={{ fontSize: FONT_SIZE, fill: euiThemeVars.euiTextColor }}
|
||||
x={circleCenterX * 2.25 + textOffset}
|
||||
y={circleTopY + HALF_FONT_SIZE}
|
||||
value={formattedValue}
|
||||
/>
|
||||
<circle style={circleStyle} cx={circleCenterX} cy={circleCenterY} r={radius} />
|
||||
</g>
|
||||
);
|
||||
const rawTextY = circleTopY + HALF_FONT_SIZE;
|
||||
const textY = rawTextY > svgHeight ? svgHeight : rawTextY;
|
||||
return {
|
||||
svg: (
|
||||
<g key={radius}>
|
||||
<line
|
||||
style={{ stroke: euiThemeVars.euiBorderColor }}
|
||||
x1={circleCenterX}
|
||||
y1={circleTopY}
|
||||
x2={circleCenterX * 2.25}
|
||||
y2={circleTopY}
|
||||
/>
|
||||
<RightAlignedText
|
||||
setWidth={this._onRightAlignedWidthChange}
|
||||
style={{ fontSize: FONT_SIZE, fill: euiThemeVars.euiTextColor }}
|
||||
x={circleCenterX * 2.25 + textOffset}
|
||||
y={textY}
|
||||
value={formattedValue}
|
||||
/>
|
||||
<circle style={circleStyle} cx={circleCenterX} cy={circleCenterY} r={radius} />
|
||||
</g>
|
||||
),
|
||||
textY,
|
||||
};
|
||||
};
|
||||
|
||||
function getMarkerRadius(percentage: number) {
|
||||
|
@ -142,34 +148,33 @@ export class MarkerSizeLegend extends Component<Props, State> {
|
|||
return fieldMeta!.delta > 3 ? Math.round(value) : value;
|
||||
}
|
||||
|
||||
const markers = [];
|
||||
const maxLabel = getMaxLabel(
|
||||
this.props.style.isFieldMetaEnabled(),
|
||||
Boolean(fieldMeta.isMaxOutsideStdRange),
|
||||
this._formatValue(fieldMeta.max)
|
||||
);
|
||||
|
||||
const minLabel = getMinLabel(
|
||||
this.props.style.isFieldMetaEnabled(),
|
||||
Boolean(fieldMeta.isMinOutsideStdRange),
|
||||
this._formatValue(fieldMeta.min)
|
||||
);
|
||||
|
||||
const markerList = new MarkerList(
|
||||
FONT_SIZE,
|
||||
makeMarker(options.maxSize, invert ? minLabel : maxLabel)
|
||||
);
|
||||
|
||||
if (fieldMeta.delta > 0) {
|
||||
const smallestMarker = makeMarker(
|
||||
options.minSize,
|
||||
this._formatValue(invert ? fieldMeta.max : fieldMeta.min)
|
||||
);
|
||||
markers.push(smallestMarker);
|
||||
|
||||
const markerDelta = options.maxSize - options.minSize;
|
||||
if (markerDelta > MIN_MARKER_DISTANCE * 3) {
|
||||
markers.push(makeMarker(getMarkerRadius(0.25), this._formatValue(getValue(0.25))));
|
||||
markers.push(makeMarker(getMarkerRadius(0.5), this._formatValue(getValue(0.5))));
|
||||
markers.push(makeMarker(getMarkerRadius(0.75), this._formatValue(getValue(0.75))));
|
||||
} else if (markerDelta > MIN_MARKER_DISTANCE) {
|
||||
markers.push(makeMarker(getMarkerRadius(0.5), this._formatValue(getValue(0.5))));
|
||||
}
|
||||
markerList.push(makeMarker(options.minSize, invert ? maxLabel : minLabel));
|
||||
markerList.push(makeMarker(getMarkerRadius(0.25), this._formatValue(getValue(0.25))));
|
||||
markerList.push(makeMarker(getMarkerRadius(0.5), this._formatValue(getValue(0.5))));
|
||||
markerList.push(makeMarker(getMarkerRadius(0.75), this._formatValue(getValue(0.75))));
|
||||
}
|
||||
|
||||
const largestMarker = makeMarker(
|
||||
options.maxSize,
|
||||
this._formatValue(invert ? fieldMeta.min : fieldMeta.max)
|
||||
);
|
||||
markers.push(largestMarker);
|
||||
|
||||
return (
|
||||
<svg height={svgHeight} xmlns="http://www.w3.org/2000/svg">
|
||||
{markers}
|
||||
{markerList.getMarkers()}
|
||||
</svg>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import { FIELD_ORIGIN, VECTOR_STYLES } from '../../../../../../../common/constants';
|
||||
import type { DynamicSizeProperty } from '../../../properties/dynamic_size_property';
|
||||
import type { IField } from '../../../../../fields/field';
|
||||
import { OrdinalLegend } from './ordinal_legend';
|
||||
|
||||
const dynamicSizeOptions = {
|
||||
minSize: 1,
|
||||
maxSize: 10,
|
||||
field: {
|
||||
name: 'bytes',
|
||||
origin: FIELD_ORIGIN.SOURCE,
|
||||
},
|
||||
fieldMetaOptions: {
|
||||
isEnabled: true,
|
||||
sigma: 3,
|
||||
},
|
||||
invert: false,
|
||||
};
|
||||
|
||||
const mockStyle = {
|
||||
formatField: (value: number) => {
|
||||
return `${value * 0.001}KB`;
|
||||
},
|
||||
getDisplayStyleName: () => {
|
||||
return 'Border width';
|
||||
},
|
||||
getField: () => {
|
||||
return {
|
||||
getLabel: () => {
|
||||
return 'bytes';
|
||||
},
|
||||
} as unknown as IField;
|
||||
},
|
||||
getOptions: () => {
|
||||
return dynamicSizeOptions;
|
||||
},
|
||||
getRangeFieldMeta: () => {
|
||||
return {
|
||||
min: 0,
|
||||
max: 19000,
|
||||
delta: 19000,
|
||||
};
|
||||
},
|
||||
getStyleName: () => {
|
||||
return VECTOR_STYLES.LINE_WIDTH;
|
||||
},
|
||||
isFieldMetaEnabled: () => {
|
||||
return true;
|
||||
},
|
||||
} as unknown as DynamicSizeProperty;
|
||||
|
||||
test('Should render legend', async () => {
|
||||
const component = shallow(<OrdinalLegend style={mockStyle} />);
|
||||
|
||||
// Ensure all promises resolve
|
||||
await new Promise((resolve) => process.nextTick(resolve));
|
||||
// Ensure the state changes are reflected
|
||||
component.update();
|
||||
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
|
@ -8,10 +8,11 @@
|
|||
import React, { Component, Fragment } from 'react';
|
||||
import _ from 'lodash';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule } from '@elastic/eui';
|
||||
import { RangedStyleLegendRow } from '../../../components/ranged_style_legend_row';
|
||||
import { VECTOR_STYLES } from '../../../../../../common/constants';
|
||||
import { CircleIcon } from './circle_icon';
|
||||
import { IDynamicStyleProperty } from '../../properties/dynamic_style_property';
|
||||
import { RangedStyleLegendRow } from '../../../../components/ranged_style_legend_row';
|
||||
import { VECTOR_STYLES } from '../../../../../../../common/constants';
|
||||
import { CircleIcon } from '../circle_icon';
|
||||
import { IDynamicStyleProperty } from '../../../properties/dynamic_style_property';
|
||||
import { getMaxLabel, getMinLabel } from './get_ordinal_label';
|
||||
|
||||
function getLineWidthIcons() {
|
||||
const defaultStyle = {
|
||||
|
@ -130,12 +131,18 @@ export class OrdinalLegend extends Component<Props, State> {
|
|||
let maxLabel: string | number = EMPTY_VALUE;
|
||||
if (fieldMeta) {
|
||||
const min = this._formatValue(_.get(fieldMeta, 'min', EMPTY_VALUE));
|
||||
minLabel =
|
||||
this.props.style.isFieldMetaEnabled() && fieldMeta.isMinOutsideStdRange ? `< ${min}` : min;
|
||||
minLabel = getMinLabel(
|
||||
this.props.style.isFieldMetaEnabled(),
|
||||
Boolean(fieldMeta.isMinOutsideStdRange),
|
||||
min
|
||||
);
|
||||
|
||||
const max = this._formatValue(_.get(fieldMeta, 'max', EMPTY_VALUE));
|
||||
maxLabel =
|
||||
this.props.style.isFieldMetaEnabled() && fieldMeta.isMaxOutsideStdRange ? `> ${max}` : max;
|
||||
maxLabel = getMaxLabel(
|
||||
this.props.style.isFieldMetaEnabled(),
|
||||
Boolean(fieldMeta.isMaxOutsideStdRange),
|
||||
max
|
||||
);
|
||||
}
|
||||
|
||||
const options = this.props.style.getOptions();
|
|
@ -1,236 +1,13 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renderLegendDetailRow Should render icon size scale 1`] = `
|
||||
exports[`renderLegendDetailRow Should render marker size legend for icon size property 1`] = `
|
||||
<div>
|
||||
<EuiFlexGroup
|
||||
gutterSize="xs"
|
||||
justifyContent="spaceBetween"
|
||||
>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<EuiToolTip
|
||||
content="foobar_label"
|
||||
delay="regular"
|
||||
display="inlineBlock"
|
||||
position="top"
|
||||
title="Symbol size"
|
||||
>
|
||||
<EuiText
|
||||
className="eui-textTruncate"
|
||||
size="xs"
|
||||
style={
|
||||
Object {
|
||||
"maxWidth": "180px",
|
||||
}
|
||||
}
|
||||
>
|
||||
<small>
|
||||
<strong>
|
||||
foobar_label
|
||||
</strong>
|
||||
</small>
|
||||
</EuiText>
|
||||
</EuiToolTip>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<svg
|
||||
height={27}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g
|
||||
key="0"
|
||||
>
|
||||
<line
|
||||
style={
|
||||
Object {
|
||||
"stroke": "#d3dae6",
|
||||
}
|
||||
}
|
||||
x1={11}
|
||||
x2={24.75}
|
||||
y1={26}
|
||||
y2={26}
|
||||
/>
|
||||
<RightAlignedText
|
||||
setWidth={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fill": "#343741",
|
||||
"fontSize": 10,
|
||||
}
|
||||
}
|
||||
value="0_format"
|
||||
x={29.75}
|
||||
y={31}
|
||||
/>
|
||||
<circle
|
||||
cx={11}
|
||||
cy={26}
|
||||
r={0}
|
||||
style={
|
||||
Object {
|
||||
"fillOpacity": 0,
|
||||
"stroke": "#343741",
|
||||
"strokeWidth": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</g>
|
||||
<g
|
||||
key="5"
|
||||
>
|
||||
<line
|
||||
style={
|
||||
Object {
|
||||
"stroke": "#d3dae6",
|
||||
}
|
||||
}
|
||||
x1={11}
|
||||
x2={24.75}
|
||||
y1={16}
|
||||
y2={16}
|
||||
/>
|
||||
<RightAlignedText
|
||||
setWidth={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fill": "#343741",
|
||||
"fontSize": 10,
|
||||
}
|
||||
}
|
||||
value="25_format"
|
||||
x={29.75}
|
||||
y={21}
|
||||
/>
|
||||
<circle
|
||||
cx={11}
|
||||
cy={21}
|
||||
r={5}
|
||||
style={
|
||||
Object {
|
||||
"fillOpacity": 0,
|
||||
"stroke": "#343741",
|
||||
"strokeWidth": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</g>
|
||||
<g
|
||||
key="10"
|
||||
>
|
||||
<line
|
||||
style={
|
||||
Object {
|
||||
"stroke": "#d3dae6",
|
||||
}
|
||||
}
|
||||
x1={11}
|
||||
x2={24.75}
|
||||
y1={6}
|
||||
y2={6}
|
||||
/>
|
||||
<RightAlignedText
|
||||
setWidth={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fill": "#343741",
|
||||
"fontSize": 10,
|
||||
}
|
||||
}
|
||||
value="100_format"
|
||||
x={29.75}
|
||||
y={11}
|
||||
/>
|
||||
<circle
|
||||
cx={11}
|
||||
cy={16}
|
||||
r={10}
|
||||
style={
|
||||
Object {
|
||||
"fillOpacity": 0,
|
||||
"stroke": "#343741",
|
||||
"strokeWidth": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
mockMarkerSizeLegend
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renderLegendDetailRow Should render line width simple range 1`] = `
|
||||
<RangedStyleLegendRow
|
||||
fieldLabel="foobar_label"
|
||||
header={
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
gutterSize="xs"
|
||||
justifyContent="spaceBetween"
|
||||
>
|
||||
<React.Fragment>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<CircleIcon
|
||||
style={
|
||||
Object {
|
||||
"fill": "none",
|
||||
"stroke": "grey",
|
||||
"strokeWidth": "1px",
|
||||
"width": "12px",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiHorizontalRule
|
||||
margin="xs"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</React.Fragment>
|
||||
<React.Fragment>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<CircleIcon
|
||||
style={
|
||||
Object {
|
||||
"fill": "none",
|
||||
"stroke": "grey",
|
||||
"strokeWidth": "2px",
|
||||
"width": "12px",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiHorizontalRule
|
||||
margin="xs"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</React.Fragment>
|
||||
<React.Fragment>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<CircleIcon
|
||||
style={
|
||||
Object {
|
||||
"fill": "none",
|
||||
"stroke": "grey",
|
||||
"strokeWidth": "3px",
|
||||
"width": "12px",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</React.Fragment>
|
||||
</EuiFlexGroup>
|
||||
}
|
||||
invert={false}
|
||||
maxLabel="100_format"
|
||||
minLabel="0_format"
|
||||
propertyLabel="Border width"
|
||||
/>
|
||||
exports[`renderLegendDetailRow Should render ordinal legend for line width style property 1`] = `
|
||||
<div>
|
||||
mockMarkerSizeLegend
|
||||
</div>
|
||||
`;
|
||||
|
|
|
@ -11,6 +11,15 @@ jest.mock('../../components/vector_style_editor', () => ({
|
|||
},
|
||||
}));
|
||||
|
||||
jest.mock('../../components/legend/size', () => ({
|
||||
MarkerSizeLegend: () => {
|
||||
return <div>mockMarkerSizeLegend</div>;
|
||||
},
|
||||
OrdinalLegend: () => {
|
||||
return <div>mockMarkerSizeLegend</div>;
|
||||
},
|
||||
}));
|
||||
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
|
@ -20,95 +29,37 @@ import { IField } from '../../../../fields/field';
|
|||
import { IVectorLayer } from '../../../../layers/vector_layer';
|
||||
|
||||
describe('renderLegendDetailRow', () => {
|
||||
test('Should render line width simple range', async () => {
|
||||
const field = {
|
||||
getLabel: async () => {
|
||||
return 'foobar_label';
|
||||
},
|
||||
getName: () => {
|
||||
return 'foodbar';
|
||||
},
|
||||
getOrigin: () => {
|
||||
return FIELD_ORIGIN.SOURCE;
|
||||
},
|
||||
supportsFieldMetaFromEs: () => {
|
||||
return true;
|
||||
},
|
||||
supportsFieldMetaFromLocalData: () => {
|
||||
return true;
|
||||
},
|
||||
} as unknown as IField;
|
||||
test('Should render ordinal legend for line width style property', () => {
|
||||
const sizeProp = new DynamicSizeProperty(
|
||||
{ minSize: 0, maxSize: 10, fieldMetaOptions: { isEnabled: true } },
|
||||
VECTOR_STYLES.LINE_WIDTH,
|
||||
field,
|
||||
{} as unknown as IField,
|
||||
{} as unknown as IVectorLayer,
|
||||
() => {
|
||||
return (value: RawValue) => value + '_format';
|
||||
},
|
||||
false
|
||||
);
|
||||
sizeProp.getRangeFieldMeta = () => {
|
||||
return {
|
||||
min: 0,
|
||||
max: 100,
|
||||
delta: 100,
|
||||
};
|
||||
};
|
||||
|
||||
const legendRow = sizeProp.renderLegendDetailRow();
|
||||
const component = shallow(legendRow);
|
||||
|
||||
// Ensure all promises resolve
|
||||
await new Promise((resolve) => process.nextTick(resolve));
|
||||
// Ensure the state changes are reflected
|
||||
component.update();
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Should render icon size scale', async () => {
|
||||
const field = {
|
||||
getLabel: async () => {
|
||||
return 'foobar_label';
|
||||
},
|
||||
getName: () => {
|
||||
return 'foodbar';
|
||||
},
|
||||
getOrigin: () => {
|
||||
return FIELD_ORIGIN.SOURCE;
|
||||
},
|
||||
supportsFieldMetaFromEs: () => {
|
||||
return true;
|
||||
},
|
||||
supportsFieldMetaFromLocalData: () => {
|
||||
return true;
|
||||
},
|
||||
} as unknown as IField;
|
||||
test('Should render marker size legend for icon size property', () => {
|
||||
const sizeProp = new DynamicSizeProperty(
|
||||
{ minSize: 0, maxSize: 10, fieldMetaOptions: { isEnabled: true } },
|
||||
VECTOR_STYLES.ICON_SIZE,
|
||||
field,
|
||||
{} as unknown as IField,
|
||||
{} as unknown as IVectorLayer,
|
||||
() => {
|
||||
return (value: RawValue) => value + '_format';
|
||||
},
|
||||
false
|
||||
);
|
||||
sizeProp.getRangeFieldMeta = () => {
|
||||
return {
|
||||
min: 0,
|
||||
max: 100,
|
||||
delta: 100,
|
||||
};
|
||||
};
|
||||
|
||||
const legendRow = sizeProp.renderLegendDetailRow();
|
||||
const component = shallow(legendRow);
|
||||
|
||||
// Ensure all promises resolve
|
||||
await new Promise((resolve) => process.nextTick(resolve));
|
||||
// Ensure the state changes are reflected
|
||||
component.update();
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
import React from 'react';
|
||||
import type { Map as MbMap } from '@kbn/mapbox-gl';
|
||||
import { DynamicStyleProperty } from '../dynamic_style_property';
|
||||
import { OrdinalLegend } from '../../components/legend/ordinal_legend';
|
||||
import { MarkerSizeLegend } from '../../components/legend/marker_size_legend';
|
||||
import { MarkerSizeLegend, OrdinalLegend } from '../../components/legend/size';
|
||||
import { makeMbClampedNumberExpression } from '../../style_util';
|
||||
import {
|
||||
FieldFormatter,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue