fix: macro action text overlap (#811)
This commit is contained in:
committed by
László Monda
parent
2ff65537a0
commit
7e4b7c5c8b
@@ -8,8 +8,9 @@
|
||||
[attr.x]="0"
|
||||
[attr.y]="textY"
|
||||
[attr.text-anchor]="'middle'"
|
||||
[attr.font-size]="11">
|
||||
<tspan [attr.x]="spanX">{{ text }}</tspan>
|
||||
[attr.font-size]="fontSize">
|
||||
<tspan [attr.x]="spanX" [attr.dy]="text1Y">{{ text1 }}</tspan>
|
||||
<tspan [attr.x]="spanX" [attr.dy]="text2Y">{{ text2 }}</tspan>
|
||||
</svg:text>
|
||||
<svg:g svg-secondary-role
|
||||
*ngIf="secondaryText"
|
||||
|
||||
|
Before Width: | Height: | Size: 499 B After Width: | Height: | Size: 596 B |
@@ -2,6 +2,7 @@ import { Component, Input, ChangeDetectionStrategy, OnChanges, SimpleChanges } f
|
||||
|
||||
import { isRectangleAsSecondaryRoleKey } from '../util';
|
||||
import { SECONDARY_ROLE_BOTTOM_MARGIN } from '../../constants';
|
||||
import { getContentWidth } from '../../../../util';
|
||||
|
||||
@Component({
|
||||
selector: 'g[svg-icon-text-key]',
|
||||
@@ -21,8 +22,14 @@ export class SvgIconTextKeyComponent implements OnChanges {
|
||||
useY: number;
|
||||
textY: number;
|
||||
spanX: number;
|
||||
textWidth: number;
|
||||
secondaryTextY: number;
|
||||
secondaryHeight: number;
|
||||
fontSize: number;
|
||||
text1: string;
|
||||
text1Y: number;
|
||||
text2: string;
|
||||
text2Y: number;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
@@ -32,22 +39,120 @@ export class SvgIconTextKeyComponent implements OnChanges {
|
||||
}
|
||||
|
||||
private calculatePositions(): void {
|
||||
let textYModifier = 0;
|
||||
let secondaryYModifier = 0;
|
||||
|
||||
if (this.secondaryText && isRectangleAsSecondaryRoleKey(this.width, this.height)) {
|
||||
textYModifier = this.height / 5;
|
||||
secondaryYModifier = 5;
|
||||
}
|
||||
|
||||
const isRectangle = this.width > this.height * 1.8;
|
||||
|
||||
this.useWidth = this.width / 3;
|
||||
this.useHeight = this.height / 3;
|
||||
this.useX = (this.width > 2 * this.height) ? 0 : this.width / 3;
|
||||
this.useY = (this.width > 2 * this.height) ? this.height / 3 : this.height / 10;
|
||||
this.textY = (this.width > 2 * this.height) ? this.height / 2 : this.height * 0.6;
|
||||
this.spanX = (this.width > 2 * this.height) ? this.width * 0.6 : this.width / 2;
|
||||
|
||||
this.secondaryHeight = this.height / 4;
|
||||
this.secondaryTextY = this.height - this.secondaryHeight - SECONDARY_ROLE_BOTTOM_MARGIN - secondaryYModifier;
|
||||
if (isRectangle) {
|
||||
this.textWidth = this.width * 0.65;
|
||||
this.useX = 0;
|
||||
this.useY = this.height / 3;
|
||||
this.spanX = this.width * 0.6;
|
||||
} else {
|
||||
this.textWidth = this.width * 0.95;
|
||||
this.useX = this.width / 3;
|
||||
this.useY = this.height / 10;
|
||||
this.spanX = this.width / 2;
|
||||
}
|
||||
|
||||
if (this.secondaryText) {
|
||||
this.secondaryHeight = this.height / 4;
|
||||
this.secondaryTextY = this.height - this.secondaryHeight - SECONDARY_ROLE_BOTTOM_MARGIN - secondaryYModifier;
|
||||
} else {
|
||||
this.secondaryHeight = 0;
|
||||
this.secondaryTextY = 0;
|
||||
}
|
||||
this.fontSize = 19;
|
||||
this.text1 = '';
|
||||
this.text2 = '';
|
||||
while (this.fontSize > 10 && !this.isFullTextVisible()) {
|
||||
this.calculateTexts(isRectangle);
|
||||
this.fontSize--;
|
||||
}
|
||||
}
|
||||
|
||||
private calculateTexts(isRectangle: boolean): void {
|
||||
if (!this.text) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.text1 = this.getText(0);
|
||||
|
||||
this.text2 = this.getText(this.text1.length);
|
||||
|
||||
const lineHeight = this.fontSize;
|
||||
const lines = this.text2 ? 1 : 0;
|
||||
|
||||
if (isRectangle) {
|
||||
const textboxHeight = this.height - this.secondaryHeight;
|
||||
this.textY = textboxHeight / 2 - 0.5 * lines * lineHeight;
|
||||
} else {
|
||||
const textboxHeight = this.height - this.secondaryHeight + this.useHeight;
|
||||
this.textY = textboxHeight / 2 - 0.5 * lines * lineHeight;
|
||||
}
|
||||
this.text1Y = 0;
|
||||
this.text2Y = this.text1Y + 1.2 * lines * lineHeight;
|
||||
}
|
||||
|
||||
private getText(startPosition: number): string {
|
||||
const style: CSSStyleDeclaration = {
|
||||
font: `${this.fontSize}px Helvetica`
|
||||
} as any;
|
||||
|
||||
let result = '';
|
||||
let lastSpacePosition = 0;
|
||||
|
||||
for (let i = startPosition; i < this.text.length; i++) {
|
||||
const char = this.text[i];
|
||||
|
||||
// skip space if result start with space
|
||||
if (char === ' ' && result === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
const newText = result += char;
|
||||
const textWidth = getContentWidth(style, newText);
|
||||
|
||||
if (char === ' ') {
|
||||
lastSpacePosition = i;
|
||||
}
|
||||
|
||||
if (textWidth > this.textWidth) {
|
||||
break;
|
||||
}
|
||||
|
||||
result = newText;
|
||||
}
|
||||
|
||||
if (lastSpacePosition > 0 && lastSpacePosition < result.length) {
|
||||
result = result.substr(0, lastSpacePosition);
|
||||
} else if (this.fontSize === 11) {
|
||||
const cleanResult = result.replace(/ /g, '');
|
||||
const cleanText = this.text.substr(startPosition).replace(/ /g, '');
|
||||
if (cleanResult.length < cleanText.length) {
|
||||
result = result.substring(0, result.length - 3) + '...';
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private isFullTextVisible(): boolean {
|
||||
const visibleText = (this.text1 + this.text2).replace(/ /g, '');
|
||||
|
||||
if (this.text2.endsWith('...')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const textLength = this.text.replace(/ /g, '').length;
|
||||
|
||||
return visibleText.length === textLength;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user