// @flow import SrlLayout from "../SrlLayout/SrlLayout"; import TokenAbsolute from "./TokenAbsolute"; import LabelAbsolute from "./LabelAbsolute"; import BarAbsolute from "./BarAbsolute"; import ArrowAbsolute from "./ArrowAbsolute"; import PredLabel from "../SrlLayout/PredLabel"; import RoleLayout from "../SrlLayout/RoleLayout"; import RoleLabel from "../SrlLayout/RoleLabel"; const ARROW_MAX_HEIGHT_MULTIPLIER = 0.8; class SrlAbsolute { tokens: TokenAbsolute[]; labels: LabelAbsolute[]; bars: BarAbsolute[]; arrows: ArrowAbsolute[]; height: number; width: number; constructor(layout: SrlLayout, showArrow: boolean, tokenHeight: number, labelHeight: number, width: number) { this.tokens = []; this.labels = []; this.bars = []; this.arrows = []; this.height = 0; this.width = width; if(layout.tokens.length<=0) { return; } const elevationHeight = showArrow?labelHeight*2:labelHeight; const getBottomY = (lineIndex:number, elevationIndex:number):number=> { let lineY = 0; for(let i=0; inew TokenAbsolute( i, token.x, getBottomY(token.lineIndex, 0), token.w, token.h )); // compute host height this.height = getBottomY(layout.tokens[layout.tokens.length-1].lineIndex, 0) + tokenHeight; // compute labels and arrow coords layout.frames.forEach((frame,frameIndex)=>{ frame.roles.forEach((role: RoleLayout, roleIndex)=>{ role.labels.forEach((label: RoleLabel, labelIndex)=>{ const labelBottomY = getBottomY(label.lineIndex, label.elevation); if(showArrow && label instanceof PredLabel) { this.arrows = [...this.arrows, ...computeArrows(label, labelBottomY - labelHeight, labelHeight*ARROW_MAX_HEIGHT_MULTIPLIER, frameIndex)]; } this.labels.push(new LabelAbsolute( frameIndex, roleIndex, labelIndex, label.cx - label.w/2, labelBottomY - labelHeight,label.w,label.h)); const anchor = role.barAnchors[labelIndex]; this.bars.push(new BarAbsolute( frameIndex, roleIndex, labelIndex, anchor[0], anchor[1], labelBottomY)); }); }); }); } } function computeArrows(pred:PredLabel, labelTopY: number, maxArrowHeight:number, frameIndex: number):ArrowAbsolute[] { return [ ...computeArrorOneSide(pred.cx, labelTopY, pred.arrowsFromLeft, maxArrowHeight, frameIndex), ...computeArrorOneSide(pred.cx, labelTopY, pred.arrowsFromRight, maxArrowHeight, frameIndex)]; } function computeArrorOneSide(predCx: number, labelTopY: number, arrowsFrom:RoleLabel[], maxArrowHeight: number, frameIndex: number):ArrowAbsolute[] { const fromXs = arrowsFrom.map((role):number=>role.cx).sort((x1,x2)=>Math.abs(x1-predCx)-Math.abs(x2-predCx)); return fromXs.map((x,i)=>new ArrowAbsolute(x, predCx, labelTopY, maxArrowHeight*(i+1)/fromXs.length, frameIndex)); } export default SrlAbsolute;