Skip to content

Commit

Permalink
Feat: add more datamarker annotation direction (#298)
Browse files Browse the repository at this point in the history
* feat: 标注dataMarker类型增加更多的朝向

* test: 增加datamarker测试用例

---------

Co-authored-by: 荊芥 <[email protected]>
  • Loading branch information
sersishen and 荊芥 authored Apr 3, 2023
1 parent 799abf0 commit b773f31
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 34 deletions.
116 changes: 83 additions & 33 deletions src/annotation/data-marker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,40 +144,69 @@ class DataMarkerAnnotation extends GroupComponent<DataMarkerAnnotationCfg> imple
}

if (textGroup) {
let translateX = textGroup.attr('x'), translateY = textGroup.attr('y');
let textBaseline, textAlign;
let xFactor = 0, yFactor = 0;
if (x + minX <= coordinateBBox.minX) {
// 左侧超出
const overflow = coordinateBBox.minX - (x + minX);
applyTranslate(textGroup, textGroup.attr('x') + overflow, textGroup.attr('y'));
}
if (x + maxX >= coordinateBBox.maxX) {
if (direction === 'leftward') {
textAlign = 'start';
xFactor = 1;
} else {
const overflow = coordinateBBox.minX - (x + minX);
translateX = textGroup.attr('x') + overflow;
}
} else if (x + maxX >= coordinateBBox.maxX) {
// 右侧超出
const overflow = x + maxX - coordinateBBox.maxX;
applyTranslate(textGroup, textGroup.attr('x') - overflow, textGroup.attr('y'));
if (direction === 'rightward') {
textAlign = 'end';
xFactor = -1;
} else {
const overflow = x + maxX - coordinateBBox.maxX;
translateX = textGroup.attr('x') - overflow;
}
}
}

if (
(direction === 'upward' && y + minY <= coordinateBBox.minY) ||
(direction !== 'upward' && y + maxY >= coordinateBBox.maxY)
) {
// 上方或者下方超出
let textBaseline;
let factor;
if (direction === 'upward' && y + minY <= coordinateBBox.minY) {
textBaseline = 'top';
factor = 1;
} else {
textBaseline = 'bottom';
factor = -1;
if (!!xFactor && textAlign) {
textShape.attr('textAlign', textAlign);
if (lineShape) {
lineShape.attr('path', [
['M', 0, 0],
['L', lineLength * xFactor, 0],
]);
}
translateX = (lineLength + 2) * xFactor;
}
textShape.attr('textBaseline', textBaseline);
if (lineShape) {
lineShape.attr('path', [
['M', 0, 0],
['L', 0, lineLength * factor],
]);
if (y + minY <= coordinateBBox.minY) {
// 上方超出
if (direction === 'upward') {
textBaseline = 'top';
yFactor = 1;
} else {
const overflow = coordinateBBox.minY - (y + minY);
translateY = textGroup.attr('y') + overflow;
}
} else if (y + maxY >= coordinateBBox.maxY) {
// 下方超出
if (direction === 'downward') {
textBaseline = 'bottom';
yFactor = -1;
} else {
const overflow = y + maxY - coordinateBBox.maxY;
translateY = textGroup.attr('y') - overflow;
}
}
applyTranslate(textGroup, textGroup.attr('x'), (lineLength + 2) * factor)
if (!!yFactor && textBaseline) {
textShape.attr('textBaseline', textBaseline);
if (lineShape) {
lineShape.attr('path', [
['M', 0, 0],
['L', 0, lineLength * yFactor],
]);
}
translateY = (lineLength + 2) * yFactor;
}
if (translateX !== textGroup.attr('x') || translateY !== textGroup.attr('y'))
applyTranslate(textGroup, translateX, translateY);
}
}

Expand All @@ -188,7 +217,27 @@ class DataMarkerAnnotation extends GroupComponent<DataMarkerAnnotationCfg> imple
const textStyle = get(this.get('text'), 'style', {});
const direction = this.get('direction');
const lineLength = lineDisplay ? get(this.get('line'), 'length', 0) : 0;
const factor = direction === 'upward' ? -1 : 1;
let xFactor = 0, yFactor = 0;
let textBaseline = 'top',
textAlign = 'start';
switch (direction) {
case 'upward':
yFactor = -1;
textBaseline = 'bottom';
break;
case 'downward':
yFactor = 1;
textBaseline = 'top';
break;
case 'leftward':
xFactor = -1;
textAlign = 'end';
break;
case 'rightward':
xFactor = 1;
textAlign = 'start';
break;
}
return {
point: {
x: 0,
Expand All @@ -198,15 +247,16 @@ class DataMarkerAnnotation extends GroupComponent<DataMarkerAnnotationCfg> imple
line: {
path: [
['M', 0, 0],
['L', 0, lineLength * factor],
['L', 0, lineLength * xFactor, lineLength * yFactor],
],
...lineStyle,
},
text: {
x: 0,
y: (lineLength + 2) * factor,
x: (lineLength + 2) * xFactor,
y: (lineLength + 2) * yFactor,
text: get(this.get('text'), 'content', ''),
textBaseline: direction === 'upward' ? 'bottom' : 'top',
textBaseline,
textAlign,
...textStyle,
},
};
Expand Down
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1219,7 +1219,7 @@ export interface DataMarkerAnnotationCfg extends GroupComponentCfg {
/**
* 方向
*/
direction?: 'upward' | 'downward';
direction?: 'upward' | 'downward' | 'leftward' | 'rightward';
/**
* 是否自动调整
*/
Expand Down
50 changes: 50 additions & 0 deletions tests/unit/annotation/data-marker-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,56 @@ describe('annotation data-marker', () => {
expect(textGroup.attr('y')).toBeGreaterThan(pointShape.attr('y'));
});

it('render leftward', () => {
dataMarker.update({
direction: 'leftward',
});

// group matrix
expect(dataMarker.get('group').attr('matrix')).toEqual([1, 0, 0, 0, 1, 0, 100, 150, 1]);

// point rendered
const pointShape: IShape = dataMarker.getElementByLocalId('point');
expect(pointShape).toBeDefined();

// line rendered
const lineShape: IShape = dataMarker.getElementByLocalId('line');
expect(lineShape).toBeDefined();

// text rendered
const textShape: IShape = dataMarker.getElementByLocalId('text');
expect(textShape.attr('text')).toBe('test text');

const textGroup = dataMarker.getElementByLocalId('text-group');
expect(textGroup.attr('x')).toBeLessThan(pointShape.attr('x'))
expect(textGroup.attr('y')).toBe(pointShape.attr('y'));
});

it('render rightward', () => {
dataMarker.update({
direction: 'rightward',
});

// group matrix
expect(dataMarker.get('group').attr('matrix')).toEqual([1, 0, 0, 0, 1, 0, 100, 150, 1]);

// point rendered
const pointShape: IShape = dataMarker.getElementByLocalId('point');
expect(pointShape).toBeDefined();

// line rendered
const lineShape: IShape = dataMarker.getElementByLocalId('line');
expect(lineShape).toBeDefined();

// text rendered
const textShape: IShape = dataMarker.getElementByLocalId('text');
expect(textShape.attr('text')).toBe('test text');

const textGroup = dataMarker.getElementByLocalId('text-group');
expect(textGroup.attr('x')).toBeGreaterThan(pointShape.attr('x'))
expect(textGroup.attr('y')).toBe(pointShape.attr('y'));
});

it('render styled', () => {
dataMarker.update({
point: {
Expand Down

0 comments on commit b773f31

Please sign in to comment.