Implement borrower dimension

This commit is contained in:
Eric NGUYEN 2022-08-30 17:36:48 +02:00
parent 57e6c9a156
commit 5fa9db931f
7 changed files with 117 additions and 14 deletions

View file

@ -96,6 +96,7 @@ export function Menu(props: IMenuProps): JSX.Element {
}; };
} }
// TODO: Fix css
const visible = isOpen ? 'visible opacity-1' : 'invisible opacity-0'; const visible = isOpen ? 'visible opacity-1' : 'invisible opacity-0';
return ( return (
<div <div

View file

@ -1,11 +1,11 @@
import * as React from 'react'; import * as React from 'react';
import { Interweave, Node } from 'interweave'; import { Interweave, Node } from 'interweave';
import { IContainerModel } from '../../../Interfaces/IContainerModel'; import { IContainerModel } from '../../../Interfaces/IContainerModel';
import { DIMENSION_MARGIN, SHOW_CHILDREN_DIMENSIONS, SHOW_PARENT_DIMENSION, SHOW_TEXT } from '../../../utils/default'; import { DIMENSION_MARGIN, SHOW_BORROWER_DIMENSIONS, SHOW_CHILDREN_DIMENSIONS, SHOW_SELF_DIMENSIONS, SHOW_TEXT } from '../../../utils/default';
import { GetDepth } from '../../../utils/itertools'; import { CancelParentTransform, GetDepth, MakeIterator, Pairwise } from '../../../utils/itertools';
import { Dimension } from './Dimension'; import { Dimension } from './Dimension';
import { IContainerProperties } from '../../../Interfaces/IContainerProperties'; import { IContainerProperties } from '../../../Interfaces/IContainerProperties';
import { TransformX } from '../../../utils/svg'; import { RestoreX, TransformX } from '../../../utils/svg';
import { Camelize } from '../../../utils/stringtools'; import { Camelize } from '../../../utils/stringtools';
interface IContainerProps { interface IContainerProps {
@ -61,12 +61,12 @@ export function Container(props: IContainerProps): JSX.Element {
const strokeWidth = 1; const strokeWidth = 1;
const text = (width ?? 0).toString(); const text = (width ?? 0).toString();
let dimensionChildren: JSX.Element | null = null; let childrenDimensions: JSX.Element | null = null;
if (props.model.children.length > 1 && SHOW_CHILDREN_DIMENSIONS) { if (props.model.properties.showChildrenDimensions && props.model.children.length > 1 && SHOW_CHILDREN_DIMENSIONS) {
const { const {
childrenId, xChildrenStart, xChildrenEnd, yChildren, textChildren childrenId, xChildrenStart, xChildrenEnd, yChildren, textChildren
} = GetChildrenDimensionProps(props, dimensionMargin); } = GetChildrenDimensionProps(props, dimensionMargin);
dimensionChildren = <Dimension childrenDimensions = <Dimension
id={childrenId} id={childrenId}
xStart={xChildrenStart} xStart={xChildrenStart}
xEnd={xChildrenEnd} xEnd={xChildrenEnd}
@ -76,13 +76,51 @@ export function Container(props: IContainerProps): JSX.Element {
text={textChildren} />; text={textChildren} />;
} }
const borrowerDimensions: JSX.Element[] = [];
if (props.model.properties.isDimensionBorrower && SHOW_BORROWER_DIMENSIONS) {
const it = MakeIterator(props.model);
const marks = [];
for (const container of it) {
if (!container.properties.markPositionToDimensionBorrower) {
continue;
}
const x = TransformX(
container.properties.x,
container.properties.width,
container.properties.xPositionReference
);
const [restoredX] = CancelParentTransform(container.parent, x, 0, props.model);
marks.push(
restoredX
);
}
marks.push(0);
marks.push(props.model.properties.width);
marks.sort((a, b) => a - b);
let count = 0;
for (const { cur, next } of Pairwise(marks)) {
const id = `dim-borrow-${props.model.properties.id}-{${count}}`;
borrowerDimensions.push(<Dimension
key={id}
id={id}
xStart={cur}
xEnd={next}
yStart={props.model.properties.height + yDim * -1}
yEnd={props.model.properties.height + yDim * -1}
strokeWidth={strokeWidth}
text={(next - cur).toString()} />);
count++;
}
}
return ( return (
<g <g
style={defaultStyle} style={defaultStyle}
transform={transform} transform={transform}
key={`container-${props.model.properties.id}`} key={`container-${props.model.properties.id}`}
> >
{SHOW_PARENT_DIMENSION {(props.model.properties.showSelfDimensions && SHOW_SELF_DIMENSIONS)
? <Dimension ? <Dimension
id={id} id={id}
xStart={xStart} xStart={xStart}
@ -92,7 +130,8 @@ export function Container(props: IContainerProps): JSX.Element {
strokeWidth={strokeWidth} strokeWidth={strokeWidth}
text={text} /> text={text} />
: null} : null}
{dimensionChildren} {childrenDimensions}
{borrowerDimensions}
{svg} {svg}
{SHOW_TEXT {SHOW_TEXT
? <text ? <text

View file

@ -20,6 +20,22 @@ export interface IAvailableContainer {
XPositionReference?: XPositionReference XPositionReference?: XPositionReference
CustomSVG?: string CustomSVG?: string
DefaultChildType?: string DefaultChildType?: string
/** if true, show the dimension of the container */
ShowSelfDimensions?: boolean
/** if true show the overall dimensions of its children */
ShowChildrenDimensions?: boolean
/**
* if true, allows a parent dimension borrower to uses its x coordinate for as a reference point for a dimension
*/
MarkPositionToDimensionBorrower?: boolean
/**
* if true, show a dimension from the edge of the container to end
* and insert dimensions marks at lift up children (see liftDimensionToBorrower)
*/
IsDimensionBorrower?: boolean
Style?: React.CSSProperties Style?: React.CSSProperties
Actions?: IAction[] Actions?: IAction[]
UserData?: object UserData?: object

View file

@ -57,6 +57,24 @@ export interface IContainerProperties {
/** Horizontal alignment, also determines the visual location of x {Left = 0, Center, Right } */ /** Horizontal alignment, also determines the visual location of x {Left = 0, Center, Right } */
xPositionReference: XPositionReference xPositionReference: XPositionReference
/** if true, show the dimension of the container */
showSelfDimensions: boolean
/** if true show the overall dimensions of its children */
showChildrenDimensions: boolean
/**
* if true, allows a parent dimension borrower to borrow its x coordinate
* as a reference point for a dimension
*/
markPositionToDimensionBorrower: boolean
/**
* if true, show a dimension from the edge of the container to end
* and insert dimensions marks at lift up children (see liftDimensionToBorrower)
*/
isDimensionBorrower: boolean
/** /**
* (optional) * (optional)
* Replace a <rect> by a customized "SVG". It is not really an svg but it at least allows * Replace a <rect> by a customized "SVG". It is not really an svg but it at least allows

View file

@ -16,9 +16,10 @@ export const DEFAULTCHILDTYPE_MAX_DEPTH = 10;
/// DIMENSIONS DEFAULTS /// /// DIMENSIONS DEFAULTS ///
export const SHOW_PARENT_DIMENSION = true; export const SHOW_SELF_DIMENSIONS = true;
export const SHOW_CHILDREN_DIMENSIONS = false; export const SHOW_CHILDREN_DIMENSIONS = false;
export const SHOW_DIMENSIONS_PER_DEPTH = true; export const SHOW_BORROWER_DIMENSIONS = true;
export const SHOW_DIMENSIONS_PER_DEPTH = false;
export const DIMENSION_MARGIN = 50; export const DIMENSION_MARGIN = 50;
export const NOTCHES_LENGTH = 4; export const NOTCHES_LENGTH = 4;
@ -51,7 +52,7 @@ export function GetDefaultEditorState(configuration: IConfiguration): IEditorSta
history: [ history: [
{ {
lastAction: '', lastAction: '',
mainContainer: mainContainer, mainContainer,
selectedContainerId: mainContainer.properties.id, selectedContainerId: mainContainer.properties.id,
typeCounters: {}, typeCounters: {},
symbols: new Map(), symbols: new Map(),
@ -110,6 +111,10 @@ export const DEFAULT_MAINCONTAINER_PROPS: IContainerProperties = {
isAnchor: false, isAnchor: false,
isFlex: false, isFlex: false,
xPositionReference: XPositionReference.Left, xPositionReference: XPositionReference.Left,
showChildrenDimensions: true, // TODO: put the dimension at the top (see pdf)
showSelfDimensions: true, // TODO: put the dimension at the bottom (see pdf)
isDimensionBorrower: true, // second dimensions from the bottom
markPositionToDimensionBorrower: false,
style: { style: {
stroke: 'black', stroke: 'black',
fillOpacity: 0 fillOpacity: 0
@ -150,6 +155,10 @@ export function GetDefaultContainerProps(type: string,
xPositionReference: containerConfig.XPositionReference ?? XPositionReference.Left, xPositionReference: containerConfig.XPositionReference ?? XPositionReference.Left,
minWidth: containerConfig.MinWidth ?? 1, minWidth: containerConfig.MinWidth ?? 1,
maxWidth: containerConfig.MaxWidth ?? Number.MAX_SAFE_INTEGER, maxWidth: containerConfig.MaxWidth ?? Number.MAX_SAFE_INTEGER,
showChildrenDimensions: containerConfig.ShowChildrenDimensions ?? false,
showSelfDimensions: containerConfig.ShowSelfDimensions ?? false,
markPositionToDimensionBorrower: containerConfig.MarkPositionToDimensionBorrower ?? false,
isDimensionBorrower: containerConfig.IsDimensionBorrower ?? false,
customSVG: containerConfig.CustomSVG, customSVG: containerConfig.CustomSVG,
style: structuredClone(containerConfig.Style), style: structuredClone(containerConfig.Style),
userData: structuredClone(containerConfig.UserData) userData: structuredClone(containerConfig.UserData)

View file

@ -83,9 +83,14 @@ export function GetAbsolutePosition(container: IContainerModel): [number, number
* @param y value to be restored * @param y value to be restored
* @returns x and y such that the transformations of the parent are cancelled * @returns x and y such that the transformations of the parent are cancelled
*/ */
export function CancelParentTransform(parent: IContainerModel | null, x: number, y: number): [number, number] { export function CancelParentTransform(
parent: IContainerModel | null,
x: number,
y: number,
stop?: IContainerModel
): [number, number] {
let current = parent; let current = parent;
while (current != null) { while (current !== stop && current != null) {
x += current.properties.x; x += current.properties.x;
y += current.properties.y; y += current.properties.y;
current = current.parent; current = current.parent;

View file

@ -61,7 +61,9 @@ const GetSVGLayoutConfiguration = () => {
strokeWidth: 2, strokeWidth: 2,
stroke: 'red', stroke: 'red',
fill: '#d3c9b7', fill: '#d3c9b7',
} },
ShowSelfDimensions: true,
IsDimensionBorrower: true
}, },
{ {
Type: 'Trou', Type: 'Trou',
@ -117,6 +119,19 @@ const GetSVGLayoutConfiguration = () => {
Type: 'Montant', Type: 'Montant',
Width: 10, Width: 10,
XPositionReference: 1, XPositionReference: 1,
MarkPositionToDimensionBorrower: true,
Style: {
fillOpacity: 0,
strokeWidth: 2,
stroke: '#713f12',
fill: '#713f12',
}
},
{
Type: 'Dilatation',
Width: 2,
XPositionReference: 1,
MarkPositionToDimensionBorrower: true,
Style: { Style: {
fillOpacity: 0, fillOpacity: 0,
strokeWidth: 2, strokeWidth: 2,