Skip to content

Commit

Permalink
fix(vrender-components): label shoud omit automaticly when label's wi…
Browse files Browse the repository at this point in the history
…dth exceeds item's width, relate VisActor/VChart#505
  • Loading branch information
kkxxkk2019 committed Aug 15, 2023
1 parent b49157e commit 197efae
Show file tree
Hide file tree
Showing 2 changed files with 302 additions and 12 deletions.
279 changes: 278 additions & 1 deletion packages/vrender-components/__tests__/unit/legend/discrete.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { IGraphic, Stage } from '@visactor/vrender';
import { expect } from 'vitest';
import type { IGraphic, IGroup, IText, Stage } from '@visactor/vrender';
import { DiscreteLegend } from '../../../src';
import { createCanvas } from '../../util/dom';
import { createStage } from '../../util/vrender';
Expand Down Expand Up @@ -227,4 +228,280 @@ describe('DiscreteLegend', () => {

expect(legend.AABBBounds.width()).toBe(76);
});

it("should omit when label's width exceeds item's width", () => {
const legend = new DiscreteLegend({
layout: 'vertical',
title: {
align: 'start',
space: 12,
textStyle: {
fontSize: 12,
fontWeight: 'bold',
fill: '#2C3542'
}
},
item: {
spaceCol: 10,
spaceRow: 10,
shape: {
space: 4,
style: {
size: 10,
cursor: 'pointer'
},
state: {
selectedHover: {
opacity: 0.85
},
unSelected: {
fill: '#D8D8D8',
fillOpacity: 0.5
}
}
},
label: {
space: 4,
style: {
fontSize: 12,
fill: '#89909D',
cursor: 'pointer'
},
state: {
selectedHover: {
opacity: 0.85
},
unSelected: {
fill: '#D8D8D8',
fillOpacity: 0.5
}
}
},
value: {
alignRight: true,
style: {
fontSize: 10,
fill: '#333',
cursor: 'pointer',
fillOpacity: 0.8
},
state: {
selectedHover: {
opacity: 0.85
},
unSelected: {
fill: '#D8D8D8'
},
unselected: {
fill: '#d8d8d8'
}
}
},
background: {
style: {
cursor: 'pointer'
},
state: {
selectedHover: {
fill: 'gray',
fillOpacity: 0.7
},
unSelectedHover: {
fill: 'gray',
fillOpacity: 0.2
}
}
},
focus: false,
focusIconStyle: {
size: 10,
symbolType:
'M8 1C11.866 1 15 4.13401 15 8C15 11.866 11.866 15 8 15C4.13401 15 1 11.866 1 8C1 4.13401 4.13401 1 8 1ZM8.75044 2.55077L8.75 3.75H7.25L7.25006 2.5507C4.81247 2.88304 2.88304 4.81247 2.5507 7.25006L3.75 7.25V8.75L2.55077 8.75044C2.8833 11.1878 4.81264 13.117 7.25006 13.4493L7.25 12.25H8.75L8.75044 13.4492C11.1876 13.1167 13.1167 11.1876 13.4492 8.75044L12.25 8.75V7.25L13.4493 7.25006C13.117 4.81264 11.1878 2.8833 8.75044 2.55077ZM8 5.5C9.38071 5.5 10.5 6.61929 10.5 8C10.5 9.38071 9.38071 10.5 8 10.5C6.61929 10.5 5.5 9.38071 5.5 8C5.5 6.61929 6.61929 5.5 8 5.5ZM8 7C7.44772 7 7 7.44772 7 8C7 8.55228 7.44772 9 8 9C8.55228 9 9 8.55228 9 8C9 7.44772 8.55228 7 8 7Z',
fill: '#333',
cursor: 'pointer'
},
visible: true,
padding: 2,
width: 121.95
},
autoPage: true,
pager: {
space: 12,
handler: {
style: {
size: 10
},
space: 4
}
},
hover: true,
select: true,
selectMode: 'multiple',
allowAllCanceled: false,
items: [
{
label: 'OneOneOneOneOne',
shape: {
fill: '#1664FF',
symbolType: 'square',
stroke: null,
fillOpacity: 1,
strokeOpacity: 1,
opacity: 1,
texture: null,
texturePadding: null,
textureSize: null,
textureColor: null,
innerBorder: null,
outerBorder: null
},
value: '26.32%',
id: 'OneOneOneOneOne',
index: 0
},
{
label: 'Two',
shape: {
fill: '#1AC6FF',
symbolType: 'square',
stroke: null,
fillOpacity: 1,
strokeOpacity: 1,
opacity: 1,
texture: null,
texturePadding: null,
textureSize: null,
textureColor: null,
innerBorder: null,
outerBorder: null
},
value: '23.68%',
id: 'Two',
index: 1
},
{
label: 'Three',
shape: {
fill: '#FF8A00',
symbolType: 'square',
stroke: null,
fillOpacity: 1,
strokeOpacity: 1,
opacity: 1,
texture: null,
texturePadding: null,
textureSize: null,
textureColor: null,
innerBorder: null,
outerBorder: null
},
value: '15.79%',
id: 'Three',
index: 2
},
{
label: 'Four',
shape: {
fill: '#3CC780',
symbolType: 'square',
stroke: null,
fillOpacity: 1,
strokeOpacity: 1,
opacity: 1,
texture: null,
texturePadding: null,
textureSize: null,
textureColor: null,
innerBorder: null,
outerBorder: null
},
value: '13.16%',
id: 'Four',
index: 3
},
{
label: 'Five',
shape: {
fill: '#7442D4',
symbolType: 'square',
stroke: null,
fillOpacity: 1,
strokeOpacity: 1,
opacity: 1,
texture: null,
texturePadding: null,
textureSize: null,
textureColor: null,
innerBorder: null,
outerBorder: null
},
value: '10.53%',
id: 'Five',
index: 4
},
{
label: 'Six',
shape: {
fill: '#FFC400',
symbolType: 'square',
stroke: null,
fillOpacity: 1,
strokeOpacity: 1,
opacity: 1,
texture: null,
texturePadding: null,
textureSize: null,
textureColor: null,
innerBorder: null,
outerBorder: null
},
value: '7.89%',
id: 'Six',
index: 5
},
{
label: 'Seven',
shape: {
fill: '#304D77',
symbolType: 'square',
stroke: null,
fillOpacity: 1,
strokeOpacity: 1,
opacity: 1,
texture: null,
texturePadding: null,
textureSize: null,
textureColor: null,
innerBorder: null,
outerBorder: null
},
value: '2.63%',
id: 'Seven',
index: 6
}
],
zIndex: 500,
maxWidth: 813,
maxHeight: 416,
defaultSelected: ['OneOneOneOneOne', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven'],
width: 147.6698455810547,
height: 186,
dx: 0,
dy: 0,
x: 100,
y: 42
});

stage.defaultLayer.add(legend as unknown as IGraphic);
stage.render();

expect((legend.getElementsByName('legendItem')[0] as IGroup).AABBBounds.width()).toBe(121.95);
expect(
(legend.getElementsByName('legendItem')[0].getElementsByName('legendItemLabel')[0] as IText)._AABBBounds.width()
).toBeCloseTo(57.143951416015625);
expect(
(legend.getElementsByName('legendItem')[0].getElementsByName('legendItemValue')[0] as IText).attribute
.maxLineWidth
).toBeUndefined();
});
});
35 changes: 24 additions & 11 deletions packages/vrender-components/src/legend/discrete/discrete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -435,18 +435,31 @@ export class DiscreteLegend extends LegendBase<DiscreteLegendAttrs> {
valueShape.addState(isSelected ? LegendStateValue.selected : LegendStateValue.unSelected);

if (this._itemWidthByUser) {
valueShape.setAttribute(
'maxLineWidth',
// 计算用来防止文本的宽度
const layoutWidth =
this._itemWidthByUser -
parsedPadding[1] -
parsedPadding[3] -
shapeSize -
shapeSpace -
labelShape.AABBBounds.width() -
labelSpace -
focusSpace -
valueSpace
);
parsedPadding[1] -
parsedPadding[3] -
shapeSize -
shapeSpace -
labelSpace -
focusSpace -
valueSpace;
const valueBounds = valueShape.AABBBounds;
const labelBounds = labelShape.AABBBounds;
const valueWidth = valueBounds.width();
const labelWidth = labelBounds.width();
if (valueWidth + labelWidth > layoutWidth) {
if ((layoutWidth - valueWidth) / labelWidth > 0.4) {
// 设置一个值,如果剩余的宽度和 label 自身的比例不低于 0.4 的话,优先展示全 label
labelShape.setAttribute('maxLineWidth', layoutWidth - valueWidth);
} else {
valueShape.setAttribute('maxLineWidth', layoutWidth * 0.5);
labelShape.setAttribute('maxLineWidth', layoutWidth * 0.5);
}
} else {
valueShape.setAttribute('maxLineWidth', layoutWidth - labelWidth);
}
if (valueAttr.alignRight) {
valueShape.setAttributes({
// @ts-ignore
Expand Down

0 comments on commit 197efae

Please sign in to comment.