Merged PR 375: Symbol Y

Implement y axis in symbol

Related work items: #7306
This commit is contained in:
Carl Fuchs 2023-02-23 11:54:36 +00:00 committed by Eric Nguyen
commit 9e9a5f3f52
20 changed files with 423 additions and 208 deletions

View file

@ -2,10 +2,15 @@ import { Orientation } from '../../Enums/Orientation';
import { Position } from '../../Enums/Position'; import { Position } from '../../Enums/Position';
import { type IContainerModel } from '../../Interfaces/IContainerModel'; import { type IContainerModel } from '../../Interfaces/IContainerModel';
import { type ISymbolModel } from '../../Interfaces/ISymbolModel'; import { type ISymbolModel } from '../../Interfaces/ISymbolModel';
import { SHOW_SELF_DIMENSIONS, SHOW_BORROWER_DIMENSIONS, SHOW_CHILDREN_DIMENSIONS, DIMENSION_MARGIN, SHOW_SELF_MARGINS_DIMENSIONS } from '../../utils/default'; import {
SHOW_SELF_DIMENSIONS,
SHOW_BORROWER_DIMENSIONS,
SHOW_CHILDREN_DIMENSIONS,
DIMENSION_MARGIN,
SHOW_SELF_MARGINS_DIMENSIONS, DEFAULT_DIMENSION_SYMBOL_STYLE
} from '../../utils/default';
import { FindContainerById, MakeRecursionDFSIterator, Pairwise } from '../../utils/itertools'; import { FindContainerById, MakeRecursionDFSIterator, Pairwise } from '../../utils/itertools';
import { TransformX, TransformY } from '../../utils/svg'; import { TransformX, TransformY } from '../../utils/svg';
import { type IDimensionStyle } from '../SVG/Elements/Dimension';
import { RenderDimension } from './Dimension'; import { RenderDimension } from './Dimension';
export function AddContainerDimensions( export function AddContainerDimensions(
@ -90,6 +95,16 @@ export function AddSymbolDimensions(
scale: number, scale: number,
depth: number depth: number
): void { ): void {
if (symbol.isVertical) {
AddVerticalSymbolDimension(
ctx,
symbol,
scale,
depth
);
return;
}
AddHorizontalSymbolDimension( AddHorizontalSymbolDimension(
ctx, ctx,
symbol, symbol,
@ -100,6 +115,7 @@ export function AddSymbolDimensions(
/** /**
* Fonction that call another function given the positions * Fonction that call another function given the positions
* @param ctx
* @param dimMapped Position mapped depending on the Position enum in order: * @param dimMapped Position mapped depending on the Position enum in order:
* [0:left, 1:bottom, 2:up, 3:right] * [0:left, 1:bottom, 2:up, 3:right]
* @param positions List of positions * @param positions List of positions
@ -569,7 +585,7 @@ function AddHorizontalSymbolDimension(
scale: number, scale: number,
depth: number depth: number
): void { ): void {
const width = symbol.x + (symbol.width / 2); const width = TransformX(symbol.offset, symbol.width, symbol.config.PositionReference);
if (width == null || width <= 0) { if (width == null || width <= 0) {
return; return;
@ -582,11 +598,6 @@ function AddHorizontalSymbolDimension(
.toFixed(0) .toFixed(0)
.toString(); .toString();
// TODO: Put this in default.ts
const defaultDimensionSymbolStyle: IDimensionStyle = {
color: 'black'
};
RenderDimension(ctx, { RenderDimension(ctx, {
id, id,
xStart: 0, xStart: 0,
@ -595,6 +606,37 @@ function AddHorizontalSymbolDimension(
yEnd: -offset, yEnd: -offset,
text, text,
scale, scale,
style: defaultDimensionSymbolStyle style: DEFAULT_DIMENSION_SYMBOL_STYLE
});
}
function AddVerticalSymbolDimension(
ctx: CanvasRenderingContext2D,
symbol: ISymbolModel,
scale: number,
depth: number
): void {
const height = TransformY(symbol.offset, symbol.height, symbol.config.PositionReference);
if (height == null || height <= 0) {
return;
}
const id = `dim-y-margin-left${symbol.width.toFixed(0)}-${symbol.id}`;
const offset = (DIMENSION_MARGIN * (depth + 1)) / scale;
const text = height
.toFixed(0)
.toString();
RenderDimension(ctx, {
id,
xStart: -offset,
yStart: height,
xEnd: -offset,
yEnd: 0,
text,
scale,
style: DEFAULT_DIMENSION_SYMBOL_STYLE
}); });
} }

View file

@ -71,16 +71,15 @@ export function RenderSymbols(
symbols: Map<string, ISymbolModel>, symbols: Map<string, ISymbolModel>,
scale: number scale: number
): void { ): void {
let count = 0;
symbols.forEach((symbol: ISymbolModel) => { symbols.forEach((symbol: ISymbolModel) => {
RenderSymbol(ctx, symbol, scale); RenderSymbol(ctx, symbol);
if (!symbol.showDimension) { if (!symbol.showDimension) {
return; return;
} }
AddSymbolDimensions(ctx, symbol, scale, count); // TODO: Implement DimensionManager
count++; AddSymbolDimensions(ctx, symbol, scale, 0);
}); });
} }

View file

@ -5,7 +5,6 @@ import { RenderSelector } from './Selector';
interface ISelectorProps { interface ISelectorProps {
symbols: Map<string, ISymbolModel> symbols: Map<string, ISymbolModel>
selected?: ISymbolModel selected?: ISymbolModel
scale?: number
} }
export function RenderSymbolSelector( export function RenderSymbolSelector(
@ -17,15 +16,20 @@ export function RenderSymbolSelector(
return; return;
} }
const scale = (props.scale ?? 1);
const [width, height] = [ const [width, height] = [
props.selected.width / scale, props.selected.width,
props.selected.height / scale props.selected.height
]; ];
const [x, y] = [ let x, y: number;
props.selected.x + props.selected.width / 2,
-SYMBOL_MARGIN - height]; if (props.selected.isVertical) {
x = -SYMBOL_MARGIN - props.selected.width;
y = props.selected.offset;
} else {
x = props.selected.offset;
y = -SYMBOL_MARGIN - props.selected.height;
}
const text = props.selected.displayedText; const text = props.selected.displayedText;
RenderSelector( RenderSelector(
@ -37,7 +41,7 @@ export function RenderSymbolSelector(
y, y,
width, width,
height, height,
scale scale: 1
} }
); );
} }

View file

@ -1,12 +1,11 @@
import { type ISymbolModel } from '../../Interfaces/ISymbolModel'; import { type ISymbolModel } from '../../Interfaces/ISymbolModel';
import { DIMENSION_MARGIN, SYMBOL_MARGIN } from '../../utils/default'; import { SYMBOL_MARGIN } from '../../utils/default';
const IMAGE_CACHE = new Map<string, HTMLImageElement>(); const IMAGE_CACHE = new Map<string, HTMLImageElement>();
export function RenderSymbol( export function RenderSymbol(
ctx: CanvasRenderingContext2D, ctx: CanvasRenderingContext2D,
symbol: ISymbolModel, symbol: ISymbolModel): void {
scale: number): void {
const href = symbol.config.Image.Base64Image ?? symbol.config.Image.Url; const href = symbol.config.Image.Base64Image ?? symbol.config.Image.Url;
if (href === undefined) { if (href === undefined) {
@ -19,28 +18,36 @@ export function RenderSymbol(
newImage.src = href; newImage.src = href;
IMAGE_CACHE.set(href, newImage); IMAGE_CACHE.set(href, newImage);
newImage.onload = () => { newImage.onload = () => {
DrawImage(ctx, scale, newImage, symbol); DrawImage(ctx, newImage, symbol);
}; };
return; return;
} }
DrawImage(ctx, scale, image, symbol); DrawImage(ctx, image, symbol);
} }
function DrawImage( function DrawImage(
ctx: CanvasRenderingContext2D, ctx: CanvasRenderingContext2D,
scale: number,
image: HTMLImageElement, image: HTMLImageElement,
symbol: ISymbolModel symbol: ISymbolModel
): void { ): void {
let x, y: number;
if (symbol.isVertical) {
x = -SYMBOL_MARGIN - symbol.width;
y = symbol.offset;
} else {
x = symbol.offset;
y = -SYMBOL_MARGIN - symbol.height;
}
ctx.save(); ctx.save();
ctx.fillStyle = '#000000'; ctx.fillStyle = '#000000';
const width = symbol.width / scale; const width = symbol.width;
const height = symbol.height / scale; const height = symbol.height;
ctx.drawImage( ctx.drawImage(
image, image,
symbol.x + symbol.width / 2, x,
-SYMBOL_MARGIN - height, y,
width, width,
height height
); );

View file

@ -5,7 +5,8 @@ import { type ISymbolModel } from '../../Interfaces/ISymbolModel';
import { import {
SHOW_BORROWER_DIMENSIONS, SHOW_BORROWER_DIMENSIONS,
SHOW_CHILDREN_DIMENSIONS, SHOW_CHILDREN_DIMENSIONS,
SHOW_SELF_DIMENSIONS, SHOW_SELF_MARGINS_DIMENSIONS SHOW_SELF_DIMENSIONS,
SHOW_SELF_MARGINS_DIMENSIONS
} from '../../utils/default'; } from '../../utils/default';
import { import {
ApplyWidthMargin, ApplyWidthMargin,
@ -27,8 +28,12 @@ import { OrientationSelector } from '../RadioGroupButtons/OrientationSelector';
import { OrientationCheckboxes } from '../CheckboxGroupButtons/OrientationCheckboxes'; import { OrientationCheckboxes } from '../CheckboxGroupButtons/OrientationCheckboxes';
import { PositionCheckboxes } from '../CheckboxGroupButtons/PositionCheckboxes'; import { PositionCheckboxes } from '../CheckboxGroupButtons/PositionCheckboxes';
import { Category } from '../Category/Category'; import { Category } from '../Category/Category';
import { Orientation } from '../../Enums/Orientation';
import { FindContainerById } from '../../utils/itertools';
import { type IContainerModel } from '../../Interfaces/IContainerModel';
interface IContainerFormProps { interface IContainerFormProps {
containers: Map<string, IContainerModel>
properties: IContainerProperties properties: IContainerProperties
symbols: Map<string, ISymbolModel> symbols: Map<string, ISymbolModel>
onChange: (key: string, value: string | number | boolean | number[], type?: PropertyType) => void onChange: (key: string, value: string | number | boolean | number[], type?: PropertyType) => void
@ -36,6 +41,8 @@ interface IContainerFormProps {
export function ContainerForm(props: IContainerFormProps): JSX.Element { export function ContainerForm(props: IContainerFormProps): JSX.Element {
const categoryHeight = 'h-11'; const categoryHeight = 'h-11';
const parent = FindContainerById(props.containers, props.properties.parentId);
const isVertical = parent?.properties.orientation === Orientation.Vertical;
return ( return (
<div className='grid grid-cols-1 gap-y-4 items-center'> <div className='grid grid-cols-1 gap-y-4 items-center'>
<TextInputGroup <TextInputGroup
@ -185,8 +192,14 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
type='number' type='number'
min={props.properties.minWidth} min={props.properties.minWidth}
max={props.properties.maxWidth} max={props.properties.maxWidth}
value={(RemoveWidthMargin(props.properties.width, props.properties.margin.left, props.properties.margin.right)).toString()} value={(RemoveWidthMargin(props.properties.width,
onChange={(value) => { props.onChange('width', ApplyWidthMargin(Number(value), props.properties.margin.left, props.properties.margin.right)); }} props.properties.margin.left,
props.properties.margin.right)).toString()}
onChange={(value) => {
props.onChange('width', ApplyWidthMargin(Number(value),
props.properties.margin.left,
props.properties.margin.right));
}}
isDisabled={props.properties.isFlex}/> isDisabled={props.properties.isFlex}/>
<TextInputGroup <TextInputGroup
id={`${props.properties.id}-maxWidth`} id={`${props.properties.id}-maxWidth`}
@ -218,8 +231,14 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
type='number' type='number'
min={props.properties.minHeight} min={props.properties.minHeight}
max={props.properties.maxHeight} max={props.properties.maxHeight}
value={(RemoveWidthMargin(props.properties.height, props.properties.margin.top, props.properties.margin.bottom)).toString()} value={(RemoveWidthMargin(props.properties.height,
onChange={(value) => { props.onChange('height', ApplyWidthMargin(Number(value), props.properties.margin.top, props.properties.margin.bottom)); }} props.properties.margin.top,
props.properties.margin.bottom)).toString()}
onChange={(value) => {
props.onChange('height', ApplyWidthMargin(Number(value),
props.properties.margin.top,
props.properties.margin.bottom));
}}
isDisabled={props.properties.isFlex} isDisabled={props.properties.isFlex}
/> />
<TextInputGroup <TextInputGroup
@ -332,7 +351,7 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
labelText={Text({ textId: '@ContainerAlignWithSymbol' })} labelText={Text({ textId: '@ContainerAlignWithSymbol' })}
labelClassName='' labelClassName=''
inputClassName='' inputClassName=''
inputs={[...props.symbols.values()].map(symbol => ({ inputs={[...props.symbols.values()].filter(symbol => (symbol.isVertical === isVertical)).map(symbol => ({
key: symbol.id, key: symbol.id,
text: symbol.id, text: symbol.id,
value: symbol.id value: symbol.id
@ -366,7 +385,7 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
labelClassName='' labelClassName=''
inputClassName='' inputClassName=''
type='color' type='color'
value={props.properties.dimensionOptions.selfDimensions.color} value={props.properties.dimensionOptions.selfDimensions.color ?? '#000000'}
onChange={(e) => { props.onChange('color', e.target.value, PropertyType.SelfDimension); }}/> onChange={(e) => { props.onChange('color', e.target.value, PropertyType.SelfDimension); }}/>
<TextInputGroup <TextInputGroup
id={`${props.properties.id}-selfDimensions-width`} id={`${props.properties.id}-selfDimensions-width`}
@ -406,7 +425,7 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
labelClassName='' labelClassName=''
inputClassName='' inputClassName=''
type='color' type='color'
value={props.properties.dimensionOptions.selfMarginsDimensions.color} value={props.properties.dimensionOptions.selfMarginsDimensions.color ?? '#000000'}
onChange={(e) => { props.onChange('color', e.target.value, PropertyType.SelfMarginDimension); }}/> onChange={(e) => { props.onChange('color', e.target.value, PropertyType.SelfMarginDimension); }}/>
<TextInputGroup <TextInputGroup
id={`${props.properties.id}-selfMarginsDimensions-width`} id={`${props.properties.id}-selfMarginsDimensions-width`}
@ -446,7 +465,7 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
labelClassName='' labelClassName=''
inputClassName='' inputClassName=''
type='color' type='color'
value={props.properties.dimensionOptions.childrenDimensions.color} value={props.properties.dimensionOptions.childrenDimensions.color ?? '#000000'}
onChange={(e) => { props.onChange('color', e.target.value, PropertyType.ChildrenDimensions); }}/> onChange={(e) => { props.onChange('color', e.target.value, PropertyType.ChildrenDimensions); }}/>
<TextInputGroup <TextInputGroup
id={`${props.properties.id}-childrenDimensions-width`} id={`${props.properties.id}-childrenDimensions-width`}
@ -496,7 +515,7 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
labelClassName='' labelClassName=''
inputClassName='' inputClassName=''
type='color' type='color'
value={props.properties.dimensionOptions.dimensionWithMarks.color} value={props.properties.dimensionOptions.dimensionWithMarks.color ?? '#000000'}
onChange={(e) => { props.onChange('color', e.target.value, PropertyType.DimensionWithMarks); }}/> onChange={(e) => { props.onChange('color', e.target.value, PropertyType.DimensionWithMarks); }}/>
<TextInputGroup <TextInputGroup
id={`${props.properties.id}-dimensionWithMarks-width`} id={`${props.properties.id}-dimensionWithMarks-width`}
@ -531,16 +550,14 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
heightClass={`${categoryHeight}`} heightClass={`${categoryHeight}`}
> >
<div className='grid grid-cols-5 gap-6 items-center prop-category-body'> <div className='grid grid-cols-5 gap-6 items-center prop-category-body'>
<TextInputGroup <InputGroup
id={`${props.properties.id}-stroke`}
labelText={Text({ textId: '@StyleStroke' })} labelText={Text({ textId: '@StyleStroke' })}
inputKey='stroke' inputKey={`${props.properties.id}-stroke`}
labelClassName='col-span-2' labelClassName='col-span-2'
inputClassName='col-span-3' inputClassName='col-span-3'
type='string' type='color'
value={props.properties.style.stroke ?? 'black'} value={props.properties.style.stroke ?? '#000000'}
onChange={(value) => { props.onChange('stroke', value, PropertyType.Style); }} onChange={(e) => { props.onChange('stroke', e.target.value, PropertyType.Style); }}/>
/>
<InputGroup <InputGroup
labelKey={`${props.properties.id}-strokeOpacity`} labelKey={`${props.properties.id}-strokeOpacity`}
labelText={Text({ textId: '@StyleStrokeOpacity' })} labelText={Text({ textId: '@StyleStrokeOpacity' })}
@ -564,16 +581,14 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
value={(props.properties.style.strokeWidth ?? 1).toString()} value={(props.properties.style.strokeWidth ?? 1).toString()}
onChange={(value) => { props.onChange('strokeWidth', Number(value), PropertyType.Style); }} onChange={(value) => { props.onChange('strokeWidth', Number(value), PropertyType.Style); }}
/> />
<TextInputGroup <InputGroup
id={`${props.properties.id}-fill`}
labelText={Text({ textId: '@StyleFill' })} labelText={Text({ textId: '@StyleFill' })}
inputKey='fill' inputKey={`${props.properties.id}-fill`}
labelClassName='col-span-2' labelClassName='col-span-2'
inputClassName='col-span-3' inputClassName='col-span-3'
type='string' type='color'
value={props.properties.style.fill ?? 'black'} value={props.properties.style.fill ?? '#000000'}
onChange={(value) => { props.onChange('fill', value, PropertyType.Style); }} onChange={(e) => { props.onChange('fill', e.target.value, PropertyType.Style); }}/>
/>
<InputGroup <InputGroup
labelKey={`${props.properties.id}-fillOpacity`} labelKey={`${props.properties.id}-fillOpacity`}
labelText={Text({ textId: '@StyleFillOpacity' })} labelText={Text({ textId: '@StyleFillOpacity' })}

View file

@ -1,10 +1,12 @@
import React from 'react'; import React from 'react';
import { PropertyType } from '../../Enums/PropertyType'; import { type PropertyType } from '../../Enums/PropertyType';
import { IContainerProperties } from '../../Interfaces/IContainerProperties'; import { type IContainerProperties } from '../../Interfaces/IContainerProperties';
import { ISymbolModel } from '../../Interfaces/ISymbolModel'; import { type ISymbolModel } from '../../Interfaces/ISymbolModel';
import { ContainerForm } from './ContainerForm'; import { ContainerForm } from './ContainerForm';
import { type IContainerModel } from '../../Interfaces/IContainerModel';
interface IPropertiesProps { interface IPropertiesProps {
containers: Map<string, IContainerModel>
properties?: IContainerProperties properties?: IContainerProperties
symbols: Map<string, ISymbolModel> symbols: Map<string, ISymbolModel>
onChange: (key: string, value: string | number | boolean | number[], type?: PropertyType) => void onChange: (key: string, value: string | number | boolean | number[], type?: PropertyType) => void
@ -18,6 +20,7 @@ export function ContainerProperties(props: IPropertiesProps): JSX.Element {
return ( return (
<div className='h-full p-3 bg-slate-200 overflow-y-auto'> <div className='h-full p-3 bg-slate-200 overflow-y-auto'>
<ContainerForm <ContainerForm
containers={props.containers}
properties={props.properties} properties={props.properties}
symbols={props.symbols} symbols={props.symbols}
onChange={props.onChange} /> onChange={props.onChange} />

View file

@ -1,10 +1,10 @@
import { IConfiguration } from '../../../Interfaces/IConfiguration'; import { type IConfiguration } from '../../../Interfaces/IConfiguration';
import { IContainerModel } from '../../../Interfaces/IContainerModel'; import { type IContainerModel } from '../../../Interfaces/IContainerModel';
import { IHistoryState } from '../../../Interfaces/IHistoryState'; import { type IHistoryState } from '../../../Interfaces/IHistoryState';
import { ISymbolModel } from '../../../Interfaces/ISymbolModel'; import { type ISymbolModel } from '../../../Interfaces/ISymbolModel';
import { GetDefaultSymbolModel } from '../../../utils/default'; import { GetDefaultSymbolModel } from '../../../utils/default';
import { FindContainerById } from '../../../utils/itertools'; import { FindContainerById } from '../../../utils/itertools';
import { RestoreX } from '../../../utils/svg'; import {RestoreX, RestoreY} from '../../../utils/svg';
import { ApplyBehaviors, ApplyBehaviorsOnSiblingsChildren } from '../Behaviors/Behaviors'; import { ApplyBehaviors, ApplyBehaviorsOnSiblingsChildren } from '../Behaviors/Behaviors';
import { GetCurrentHistory, GetCurrentHistoryState, UpdateCounters } from '../Editor'; import { GetCurrentHistory, GetCurrentHistoryState, UpdateCounters } from '../Editor';
import { AddContainers } from './AddContainer'; import { AddContainers } from './AddContainer';
@ -32,7 +32,12 @@ export function AddSymbol(
const newSymbols = structuredClone(current.symbols); const newSymbols = structuredClone(current.symbols);
const newSymbol: ISymbolModel = GetDefaultSymbolModel(name, typeCounters, type, symbolConfig); const newSymbol: ISymbolModel = GetDefaultSymbolModel(name, typeCounters, type, symbolConfig);
const containers = structuredClone(current.containers); const containers = structuredClone(current.containers);
newSymbol.x = RestoreX(newSymbol.x, newSymbol.width, newSymbol.config.PositionReference);
if (newSymbol.isVertical) {
newSymbol.offset = RestoreY(newSymbol.offset, newSymbol.height, newSymbol.config.PositionReference);
} else {
newSymbol.offset = RestoreX(newSymbol.offset, newSymbol.width, newSymbol.config.PositionReference);
}
newSymbols.set(newSymbol.id, newSymbol); newSymbols.set(newSymbol.id, newSymbol);

View file

@ -1,11 +1,33 @@
import { IContainerModel } from '../../../Interfaces/IContainerModel'; import { type IContainerModel } from '../../../Interfaces/IContainerModel';
import { ISymbolModel } from '../../../Interfaces/ISymbolModel'; import { type ISymbolModel } from '../../../Interfaces/ISymbolModel';
import { ApplyParentTransform, FindContainerById } from '../../../utils/itertools'; import { ApplyParentTransform, FindContainerById } from '../../../utils/itertools';
import { RestoreX, TransformX } from '../../../utils/svg'; import { RestoreX, RestoreY, TransformX, TransformY } from '../../../utils/svg';
export function ApplySymbol(containers: Map<string, IContainerModel>, container: IContainerModel, symbol: ISymbolModel): IContainerModel { export function ApplySymbol(containers: Map<string, IContainerModel>,
container.properties.x = TransformX(symbol.x, symbol.width, symbol.config.PositionReference); container: IContainerModel,
container.properties.x = RestoreX(container.properties.x, container.properties.width, container.properties.positionReference); symbol: ISymbolModel): IContainerModel {
if (symbol.isVertical) {
container.properties.y = TransformY(symbol.offset,
symbol.height,
symbol.config.PositionReference);
container.properties.y = RestoreY(container.properties.y,
container.properties.height,
container.properties.positionReference);
const parent = FindContainerById(containers, container.properties.parentId);
let y = 0;
if (parent !== undefined && parent !== null) {
([,y] = ApplyParentTransform(containers, parent, 0, container.properties.y));
}
container.properties.y = y;
return container;
} else {
container.properties.x = TransformX(
symbol.offset,
symbol.width,
symbol.config.PositionReference);
container.properties.x = RestoreX(container.properties.x,
container.properties.width,
container.properties.positionReference);
const parent = FindContainerById(containers, container.properties.parentId); const parent = FindContainerById(containers, container.properties.parentId);
let x = 0; let x = 0;
if (parent !== undefined && parent !== null) { if (parent !== undefined && parent !== null) {
@ -14,3 +36,4 @@ export function ApplySymbol(containers: Map<string, IContainerModel>, container:
container.properties.x = x; container.properties.x = x;
return container; return container;
} }
}

View file

@ -169,6 +169,7 @@ export function ElementsSidebar(props: IElementsSidebarProps): JSX.Element {
{props.selectedExtendedSidebar === ExtendedSidebar.Property && {props.selectedExtendedSidebar === ExtendedSidebar.Property &&
<div className='flex flex-1 flex-col w-64 border-r-2 border-slate-400'> <div className='flex flex-1 flex-col w-64 border-r-2 border-slate-400'>
<ContainerProperties <ContainerProperties
containers ={props.containers}
properties={props.selectedContainer?.properties} properties={props.selectedContainer?.properties}
symbols={props.symbols} symbols={props.symbols}
onChange={props.onPropertyChange} onChange={props.onPropertyChange}
@ -231,8 +232,10 @@ function ElementsListRow(
: 'bg-slate-300/60 hover:bg-slate-400 hover:shadow-slate-400'; : 'bg-slate-300/60 hover:bg-slate-400 hover:shadow-slate-400';
return <button type="button" return <button type="button"
className={`transition-all border-blue-500 hover:shadow-lg elements-sidebar-row whitespace-pre className={`transition-all border-blue-500
text-left text-sm font-medium flex items-center align-middle group ${container.properties.type} ${buttonSelectedClass}`} hover:shadow-lg elements-sidebar-row whitespace-pre
text-left text-sm font-medium flex items-center align-middle group
${container.properties.type} ${buttonSelectedClass}`}
id={key} id={key}
key={key} key={key}
style={style} style={style}

View file

@ -31,7 +31,7 @@ function ApplyParametric(x0: number, t: number, vx: number): number {
export function Dimension(props: IDimensionProps): JSX.Element { export function Dimension(props: IDimensionProps): JSX.Element {
const scale = props.scale ?? 1; const scale = props.scale ?? 1;
const style: React.CSSProperties = { const style: React.CSSProperties = {
stroke: props.style.color, stroke: props.style.color ?? '#000000',
strokeWidth: (props.style.width ?? 2) / scale, strokeWidth: (props.style.width ?? 2) / scale,
strokeDasharray: props.style.dashArray strokeDasharray: props.style.dashArray
}; };

View file

@ -2,6 +2,7 @@ import * as React from 'react';
import { Orientation } from '../../../Enums/Orientation'; import { Orientation } from '../../../Enums/Orientation';
import { Position } from '../../../Enums/Position'; import { Position } from '../../../Enums/Position';
import { import {
DEFAULT_DIMENSION_SYMBOL_STYLE,
DIMENSION_MARGIN, DIMENSION_MARGIN,
SHOW_BORROWER_DIMENSIONS, SHOW_BORROWER_DIMENSIONS,
SHOW_CHILDREN_DIMENSIONS, SHOW_CHILDREN_DIMENSIONS,
@ -10,7 +11,7 @@ import {
} from '../../../utils/default'; } from '../../../utils/default';
import { FindContainerById, MakeRecursionDFSIterator, Pairwise } from '../../../utils/itertools'; import { FindContainerById, MakeRecursionDFSIterator, Pairwise } from '../../../utils/itertools';
import { TransformX, TransformY } from '../../../utils/svg'; import { TransformX, TransformY } from '../../../utils/svg';
import { Dimension, type IDimensionStyle } from './Dimension'; import { Dimension } from './Dimension';
import { type IContainerModel } from '../../../Interfaces/IContainerModel'; import { type IContainerModel } from '../../../Interfaces/IContainerModel';
import { type ISymbolModel } from '../../../Interfaces/ISymbolModel'; import { type ISymbolModel } from '../../../Interfaces/ISymbolModel';
@ -41,14 +42,12 @@ function ActionByPosition(
positions.forEach((position: Position) => { positions.forEach((position: Position) => {
const dim = dimMapped[position]; const dim = dimMapped[position];
switch (position) { switch (position) {
case Position.Right:
case Position.Left: case Position.Left:
case Position.Right: { verticalAction(dim, false, ...params);
const isRight = position === Position.Right;
verticalAction(dim, isRight, ...params);
break; break;
}
case Position.Down:
case Position.Up: case Position.Up:
case Position.Down:
horizontalAction(dim, ...params); horizontalAction(dim, ...params);
break; break;
} }
@ -94,7 +93,8 @@ function Dimensions({ containers, symbols, root, scale }: IDimensionLayerProps):
); );
} }
if (SHOW_SELF_MARGINS_DIMENSIONS && container.properties.dimensionOptions.selfMarginsDimensions.positions.length > 0) { if (SHOW_SELF_MARGINS_DIMENSIONS &&
container.properties.dimensionOptions.selfMarginsDimensions.positions.length > 0) {
ActionByPosition( ActionByPosition(
dimMapped, dimMapped,
container.properties.dimensionOptions.selfMarginsDimensions.positions, container.properties.dimensionOptions.selfMarginsDimensions.positions,
@ -127,7 +127,9 @@ function Dimensions({ containers, symbols, root, scale }: IDimensionLayerProps):
); );
} }
if (SHOW_CHILDREN_DIMENSIONS && container.properties.dimensionOptions.childrenDimensions.positions.length > 0 && container.children.length >= 2) { if (SHOW_CHILDREN_DIMENSIONS &&
container.properties.dimensionOptions.childrenDimensions.positions.length > 0 &&
container.children.length >= 2) {
ActionByPosition( ActionByPosition(
dimMapped, dimMapped,
container.properties.dimensionOptions.childrenDimensions.positions, container.properties.dimensionOptions.childrenDimensions.positions,
@ -144,24 +146,76 @@ function Dimensions({ containers, symbols, root, scale }: IDimensionLayerProps):
} }
} }
let startDepthSymbols: number = 0; // TODO: Implement DimensionManager
symbols.forEach((symbol: ISymbolModel) => { symbols.forEach((symbol) => {
if (!symbol.showDimension) { if (symbol.showDimension) {
return; if (symbol.isVertical) {
AddVerticalSymbolDimension(symbol, dimensions, scale, 0);
} else {
AddHorizontalSymbolDimension(symbol, dimensions, scale, 0);
}
} }
startDepthSymbols++;
AddHorizontalSymbolDimension(
symbol,
dimensions,
scale,
startDepthSymbols
);
}); });
return dimensions; return dimensions;
} }
function AddHorizontalSymbolDimension(symbol: ISymbolModel,
dimensions: React.ReactNode[],
scale: number,
depth: number
): void {
const width = TransformX(symbol.offset, symbol.width, symbol.config.PositionReference);
if (width != null && width > 0) {
const id = `dim-y-margin-left${symbol.width.toFixed(0)}-${symbol.id}`;
const offset = (DIMENSION_MARGIN * (depth + 1)) / scale;
const text = width
.toFixed(0)
.toString();
dimensions.push(
<Dimension
key={id}
id={id}
xStart={0}
yStart={-offset}
xEnd={width}
yEnd={-offset}
text={text}
scale={scale}
style={DEFAULT_DIMENSION_SYMBOL_STYLE}/>
);
}
}
function AddVerticalSymbolDimension(symbol: ISymbolModel,
dimensions: React.ReactNode[],
scale: number,
depth: number
): void {
const height = TransformY(symbol.offset, symbol.height, symbol.config.PositionReference);
if (height != null && height > 0) {
const id = `dim-x-margin-left${symbol.height.toFixed(0)}-${symbol.id}`;
const offset = (DIMENSION_MARGIN * (depth + 1)) / scale;
const text = height
.toFixed(0)
.toString();
dimensions.push(
<Dimension
key={id}
id={id}
xStart={-offset}
yStart={height}
xEnd={-offset}
yEnd={0}
text={text}
scale={scale}
style={DEFAULT_DIMENSION_SYMBOL_STYLE}/>
);
}
}
/** /**
* A layer containing all dimension * A layer containing all dimension
* @param props * @param props
@ -195,8 +249,12 @@ function AddHorizontalChildrenDimension(
return; return;
} }
let xChildrenStart = TransformX(lastChild.properties.x, lastChild.properties.width, lastChild.properties.positionReference); let xChildrenStart = TransformX(lastChild.properties.x,
let xChildrenEnd = TransformX(lastChild.properties.x, lastChild.properties.width, lastChild.properties.positionReference); lastChild.properties.width,
lastChild.properties.positionReference);
let xChildrenEnd = TransformX(lastChild.properties.x,
lastChild.properties.width,
lastChild.properties.positionReference);
// Find the min and max // Find the min and max
for (let i = container.children.length - 2; i >= 0; i--) { for (let i = container.children.length - 2; i >= 0; i--) {
@ -258,8 +316,12 @@ function AddVerticalChildrenDimension(
return; return;
} }
let yChildrenStart = TransformY(lastChild.properties.y, lastChild.properties.height, lastChild.properties.positionReference); let yChildrenStart = TransformY(lastChild.properties.y,
let yChildrenEnd = TransformY(lastChild.properties.y, lastChild.properties.height, lastChild.properties.positionReference); lastChild.properties.height,
lastChild.properties.positionReference);
let yChildrenEnd = TransformY(lastChild.properties.y,
lastChild.properties.height,
lastChild.properties.positionReference);
// Find the min and max // Find the min and max
for (let i = container.children.length - 2; i >= 0; i--) { for (let i = container.children.length - 2; i >= 0; i--) {
@ -611,40 +673,3 @@ function AddVerticalSelfMarginDimension(
); );
} }
} }
function AddHorizontalSymbolDimension(
symbol: ISymbolModel,
dimensions: React.ReactNode[],
scale: number,
depth: number
): void {
const width = symbol.x + (symbol.width / 2);
if (width == null || width <= 0) {
return;
}
const id = `dim-y-margin-left${symbol.width.toFixed(0)}-${symbol.id}`;
const offset = (DIMENSION_MARGIN * (depth + 1)) / scale;
const text = width
.toFixed(0)
.toString();
// TODO: Put this in default.ts
const defaultDimensionSymbolStyle: IDimensionStyle = {
color: 'black'
};
dimensions.push(
<Dimension
key={id}
id={id}
xStart={0}
yStart={-offset}
xEnd={width}
yEnd={-offset}
text={text}
scale={scale}
style={defaultDimensionSymbolStyle}/>
);
}

View file

@ -1,13 +1,12 @@
import '../Selector.scss'; import '../Selector.scss';
import * as React from 'react'; import * as React from 'react';
import { SYMBOL_MARGIN } from '../../../../utils/default'; import { DIMENSION_MARGIN, SYMBOL_MARGIN } from '../../../../utils/default';
import { type ISymbolModel } from '../../../../Interfaces/ISymbolModel'; import { type ISymbolModel } from '../../../../Interfaces/ISymbolModel';
import { Selector } from '../Selector/Selector'; import { Selector } from '../Selector/Selector';
interface ISelectorSymbolProps { interface ISelectorSymbolProps {
symbols: Map<string, ISymbolModel> symbols: Map<string, ISymbolModel>
selected?: ISymbolModel selected?: ISymbolModel
scale?: number
} }
export function SelectorSymbol(props: ISelectorSymbolProps): JSX.Element { export function SelectorSymbol(props: ISelectorSymbolProps): JSX.Element {
@ -18,30 +17,27 @@ export function SelectorSymbol(props: ISelectorSymbolProps): JSX.Element {
); );
} }
const scale = (props.scale ?? 1); let x, y: number;
const [width, height] = [
props.selected.width / scale,
props.selected.height / scale
];
const [x, y] = [ const scaledHeight = props.selected.height;
props.selected.x + props.selected.width / 2, const scaledWidth = props.selected.width;
-SYMBOL_MARGIN - height];
const style: React.CSSProperties = { if (props.selected.isVertical) {
transform: 'translateX(-50%)', x = -SYMBOL_MARGIN - props.selected.width;
transformBox: 'fill-box' y = props.selected.offset;
}; } else {
x = props.selected.offset;
y = -SYMBOL_MARGIN - props.selected.height;
}
return ( return (
<Selector <Selector
text={props.selected.displayedText} text={props.selected.displayedText}
x={x} x={x}
y={y} y={y}
width={width} width={scaledWidth}
height={height} height={scaledHeight}
scale={scale} scale={1}
style={style}
/> />
); );
} }

View file

@ -1,7 +1,7 @@
import { Interweave } from 'interweave'; import { Interweave } from 'interweave';
import * as React from 'react'; import * as React from 'react';
import { ISymbolModel } from '../../../Interfaces/ISymbolModel'; import { type ISymbolModel } from '../../../Interfaces/ISymbolModel';
import { DIMENSION_MARGIN, SYMBOL_MARGIN } from '../../../utils/default'; import { SYMBOL_MARGIN } from '../../../utils/default';
interface ISymbolProps { interface ISymbolProps {
model: ISymbolModel model: ISymbolModel
@ -12,11 +12,22 @@ export function Symbol(props: ISymbolProps): JSX.Element {
const href = props.model.config.Image.Base64Image ?? props.model.config.Image.Url; const href = props.model.config.Image.Base64Image ?? props.model.config.Image.Url;
const hasSVG = props.model.config.Image.Svg !== undefined && const hasSVG = props.model.config.Image.Svg !== undefined &&
props.model.config.Image.Svg !== null; props.model.config.Image.Svg !== null;
let x, y: number;
if (props.model.isVertical) {
x = -SYMBOL_MARGIN - props.model.width;
y = props.model.offset;
} else {
x = props.model.offset;
y = -SYMBOL_MARGIN - props.model.height;
}
if (hasSVG) { if (hasSVG) {
return ( return (
<g <g
x={props.model.x} x={x}
y={-DIMENSION_MARGIN / props.scale} y={y}
> >
<Interweave <Interweave
noWrap={true} noWrap={true}
@ -31,14 +42,9 @@ export function Symbol(props: ISymbolProps): JSX.Element {
<image <image
href={href} href={href}
preserveAspectRatio="none" preserveAspectRatio="none"
style={{ x={x}
fill: 'none', y={y}
transform: 'translateY(-100%) translateX(-50%)', height={props.model.height}
transformBox: 'fill-box' width={props.model.width} />
}}
x={props.model.x + props.model.width / 2}
y={-SYMBOL_MARGIN}
height={props.model.height / props.scale}
width={props.model.width / props.scale} />
); );
} }

View file

@ -1,11 +1,11 @@
import * as React from 'react'; import * as React from 'react';
import { ISymbolModel } from '../../Interfaces/ISymbolModel'; import { type ISymbolModel } from '../../Interfaces/ISymbolModel';
import { RestoreX, TransformX } from '../../utils/svg'; import { RestoreX, RestoreY, TransformX, TransformY } from '../../utils/svg';
import { InputGroup } from '../InputGroup/InputGroup'; import { InputGroup } from '../InputGroup/InputGroup';
import { TextInputGroup } from '../InputGroup/TextInputGroup'; import { TextInputGroup } from '../InputGroup/TextInputGroup';
import { Text } from '../Text/Text'; import { Text } from '../Text/Text';
import { PropertyType } from '../../Enums/PropertyType';
import { ToggleButton } from '../ToggleButton/ToggleButton'; import { ToggleButton } from '../ToggleButton/ToggleButton';
import { type PositionReference } from '../../Enums/PositionReference';
interface ISymbolFormProps { interface ISymbolFormProps {
symbol: ISymbolModel symbol: ISymbolModel
@ -13,6 +13,29 @@ interface ISymbolFormProps {
onChange: (key: string, value: string | number | boolean) => void onChange: (key: string, value: string | number | boolean) => void
} }
function Restore(offset: number,
isVertical: boolean,
height: number,
width: number,
position: PositionReference | undefined): number {
if (isVertical) {
return RestoreY(offset, height, position);
} else {
return RestoreX(offset, width, position);
}
}
function Transform(offset: number,
isVertical: boolean,
height: number,
width: number,
position: PositionReference | undefined): number {
if (isVertical) {
return TransformY(offset, height, position);
} else {
return TransformX(offset, width, position);
}
}
export function SymbolForm(props: ISymbolFormProps): JSX.Element { export function SymbolForm(props: ISymbolFormProps): JSX.Element {
return ( return (
<div className='grid grid-cols-2 gap-y-4'> <div className='grid grid-cols-2 gap-y-4'>
@ -32,16 +55,34 @@ export function SymbolForm(props: ISymbolFormProps): JSX.Element {
inputClassName='' inputClassName=''
type='string' type='string'
value={props.symbol.displayedText} value={props.symbol.displayedText}
onChange={(value) => props.onChange('displayedText', value)} /> onChange={(value) => { props.onChange('displayedText', value); }} />
<TextInputGroup <TextInputGroup
id='x' id='offset'
labelText={Text({ textId: '@SymbolX' })} labelText={Text({ textId: '@SymbolOffset' })}
inputKey='x' inputKey='offset'
labelClassName='' labelClassName=''
inputClassName='' inputClassName=''
type='number' type='number'
value={TransformX(props.symbol.x, props.symbol.width, props.symbol.config.PositionReference).toString()} value={Transform(props.symbol.offset,
onChange={(value) => props.onChange('x', RestoreX(Number(value), props.symbol.width, props.symbol.config.PositionReference))} /> props.symbol.isVertical,
props.symbol.height,
props.symbol.width,
props.symbol.config.PositionReference).toString()}
onChange={(value) => {
props.onChange('offset',
Restore(Number(value),
props.symbol.isVertical,
props.symbol.height,
props.symbol.width,
props.symbol.config.PositionReference));
}} />
<ToggleButton
labelText={Text({ textId: '@IsVertical' })}
inputKey='isVertical'
labelClassName=''
inputClassName=''
checked={props.symbol.isVertical}
onChange={(e) => { props.onChange('isVertical', e.target.checked); }}/>
<TextInputGroup <TextInputGroup
id='height' id='height'
labelText={Text({ textId: '@SymbolHeight' })} labelText={Text({ textId: '@SymbolHeight' })}
@ -51,7 +92,7 @@ export function SymbolForm(props: ISymbolFormProps): JSX.Element {
type='number' type='number'
min={0} min={0}
value={props.symbol.height.toString()} value={props.symbol.height.toString()}
onChange={(value) => props.onChange('height', Number(value))} /> onChange={(value) => { props.onChange('height', Number(value)); }} />
<TextInputGroup <TextInputGroup
id='width' id='width'
labelText={Text({ textId: '@SymbolWidth' })} labelText={Text({ textId: '@SymbolWidth' })}
@ -61,14 +102,14 @@ export function SymbolForm(props: ISymbolFormProps): JSX.Element {
type='number' type='number'
min={0} min={0}
value={props.symbol.width.toString()} value={props.symbol.width.toString()}
onChange={(value) => props.onChange('width', Number(value))} /> onChange={(value) => { props.onChange('width', Number(value)); }} />
<ToggleButton <ToggleButton
labelText={Text({ textId: '@ShowDimension' })} labelText={Text({ textId: '@ShowDimension' })}
inputKey='showDimension' inputKey='showDimension'
labelClassName='' labelClassName=''
inputClassName='' inputClassName=''
checked={props.symbol.showDimension} checked={props.symbol.showDimension}
onChange={(e) => props.onChange('showDimension', e.target.checked)}/> onChange={(e) => { props.onChange('showDimension', e.target.checked); }}/>
</div> </div>
); );
} }

View file

@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/naming-convention */ /* eslint-disable @typescript-eslint/naming-convention */
import { PositionReference } from '../Enums/PositionReference'; import { type PositionReference } from '../Enums/PositionReference';
import { IAvailableContainer } from './IAvailableContainer'; import { type IAvailableContainer } from './IAvailableContainer';
import { IImage } from './IImage'; import { type IImage } from './IImage';
/** /**
* Model of available symbol to configure the application */ * Model of available symbol to configure the application */
@ -13,9 +13,9 @@ export interface IAvailableSymbol {
/** displayed text */ /** displayed text */
DisplayedText?: string DisplayedText?: string
X?: number isVertical?: boolean
Y?: number offset?: number
Width?: number Width?: number

View file

@ -13,10 +13,10 @@ export interface ISymbolModel {
/** Configuration of the symbol */ /** Configuration of the symbol */
config: IAvailableSymbol config: IAvailableSymbol
/** Horizontal offset */ isVertical: boolean
x: number
// TODO: Implement Y and verticality /** offset */
offset: number
/** Width */ /** Width */
width: number width: number

View file

@ -76,7 +76,9 @@
"@SymbolName": "Name", "@SymbolName": "Name",
"@SymbolDisplayedText": "Displayed text", "@SymbolDisplayedText": "Displayed text",
"@SymbolX": "x", "@SymbolOffset" : "Offset",
"@IsVertical" : "Vertical",
"@ShowDimension" : "Dimension",
"@SymbolHeight": "Height", "@SymbolHeight": "Height",
"@SymbolWidth": "Width" "@SymbolWidth": "Width"
} }

View file

@ -76,7 +76,9 @@
"@SymbolName": "Nom", "@SymbolName": "Nom",
"@SymbolDisplayedText": "Texte affiché", "@SymbolDisplayedText": "Texte affiché",
"@SymbolX": "x", "@SymbolOffset" : "Décalage",
"@IsVertical" : "Vertical",
"@ShowDimension" : "Cotation",
"@SymbolHeight": "Hauteur", "@SymbolHeight": "Hauteur",
"@SymbolWidth": "Largeur" "@SymbolWidth": "Largeur"
} }

View file

@ -9,6 +9,7 @@ import { type ISymbolModel } from '../Interfaces/ISymbolModel';
import { Orientation } from '../Enums/Orientation'; import { Orientation } from '../Enums/Orientation';
import { AppState } from '../Enums/AppState'; import { AppState } from '../Enums/AppState';
import { type IDimensionOptions } from '../Interfaces/IDimensionOptions'; import { type IDimensionOptions } from '../Interfaces/IDimensionOptions';
import { type IDimensionStyle } from '../Components/SVG/Elements/Dimension';
/// EDITOR DEFAULTS /// /// EDITOR DEFAULTS ///
@ -69,10 +70,14 @@ export const SHOW_BORROWER_DIMENSIONS = true;
export const DIMENSION_MARGIN = 50; export const DIMENSION_MARGIN = 50;
export const SYMBOL_MARGIN = 25; export const SYMBOL_MARGIN = 25;
export const NOTCHES_LENGTH = 10; export const NOTCHES_LENGTH = 10;
export const DEFAULT_DIMENSION_SYMBOL_STYLE: IDimensionStyle = {
color: '#000000'
};
/// SYMBOL DEFAULTS /// /// SYMBOL DEFAULTS ///
export const DEFAULT_SYMBOL_WIDTH = 32; export const DEFAULT_SYMBOL_WIDTH = 32;
export const DEFAULT_SYMBOL_IS_VERTICAL = false;
export const DEFAULT_SYMBOL_HEIGHT = 32; export const DEFAULT_SYMBOL_HEIGHT = 32;
/** /**
@ -270,7 +275,7 @@ export function GetDefaultContainerProps(type: string,
hideChildrenInTreeview: containerConfig.HideChildrenInTreeview ?? false, hideChildrenInTreeview: containerConfig.HideChildrenInTreeview ?? false,
dimensionOptions: { dimensionOptions: {
childrenDimensions: { childrenDimensions: {
...containerConfig.DimensionOptions?.selfDimensions, ...containerConfig.DimensionOptions?.childrenDimensions,
positions: containerConfig.DimensionOptions?.childrenDimensions.positions ?? [] positions: containerConfig.DimensionOptions?.childrenDimensions.positions ?? []
}, },
selfDimensions: { selfDimensions: {
@ -304,7 +309,8 @@ export function GetDefaultSymbolModel(name: string,
displayedText: symbolConfig.DisplayedText ?? id, displayedText: symbolConfig.DisplayedText ?? id,
type: name, type: name,
config: structuredClone(symbolConfig), config: structuredClone(symbolConfig),
x: 0, offset: 0,
isVertical: symbolConfig.isVertical ?? DEFAULT_SYMBOL_IS_VERTICAL,
width: symbolConfig.Width ?? DEFAULT_SYMBOL_WIDTH, width: symbolConfig.Width ?? DEFAULT_SYMBOL_WIDTH,
height: symbolConfig.Height ?? DEFAULT_SYMBOL_HEIGHT, height: symbolConfig.Height ?? DEFAULT_SYMBOL_HEIGHT,
linkedContainers: new Set(), linkedContainers: new Set(),

View file

@ -81,7 +81,7 @@ const GetSVGLayoutConfiguration = () => {
Style: { Style: {
fillOpacity: 1, fillOpacity: 1,
strokeWidth: 2, strokeWidth: 2,
stroke: 'red', stroke: '#ff0000',
fill: '#d3c9b7', fill: '#d3c9b7',
}, },
IsFlex: true, IsFlex: true,
@ -96,7 +96,7 @@ const GetSVGLayoutConfiguration = () => {
Style: { Style: {
fillOpacity: 1, fillOpacity: 1,
strokeWidth: 2, strokeWidth: 2,
stroke: 'red', stroke: '#ff0000',
fill: '#d3c9b7', fill: '#d3c9b7',
}, },
IsFlex: true, IsFlex: true,
@ -115,8 +115,8 @@ const GetSVGLayoutConfiguration = () => {
Style: { Style: {
fillOpacity: 1, fillOpacity: 1,
strokeWidth: 2, strokeWidth: 2,
stroke: 'green', stroke: '#00ff00',
fill: 'white' fill: '#ffffff'
}, },
Category: "Stuff", Category: "Stuff",
IsFlex: true, IsFlex: true,
@ -258,8 +258,8 @@ const GetSVGLayoutConfiguration = () => {
Style: { Style: {
fillOpacity: 1, fillOpacity: 1,
strokeWidth: 2, strokeWidth: 2,
stroke: 'blue', stroke: '#0000ff',
fill: 'blue', fill: '#0000ff',
} }
}, },
{ {
@ -270,8 +270,8 @@ const GetSVGLayoutConfiguration = () => {
Style: { Style: {
fillOpacity: 1, fillOpacity: 1,
strokeWidth: 2, strokeWidth: 2,
stroke: 'red', stroke: '#ff0000',
fill: 'red', fill: '#ff0000',
} }
} }
], ],
@ -286,8 +286,8 @@ const GetSVGLayoutConfiguration = () => {
Svg: null, Svg: null,
Url: 'https://www.manutan.fr/img/S/GRP/ST/AIG3930272.jpg' Url: 'https://www.manutan.fr/img/S/GRP/ST/AIG3930272.jpg'
}, },
Name: 'Poteau structure', Name: 'Poteau CenterCenter',
PositionReference: 1, PositionReference: 4,
AssociatedContainer: { AssociatedContainer: {
Type: 'Montant' Type: 'Montant'
} }
@ -297,13 +297,49 @@ const GetSVGLayoutConfiguration = () => {
Height: 32, Height: 32,
Image: { Image: {
Base64Image: null, Base64Image: null,
Name: 'Arrow', Name: 'ArrowTopLeft',
Svg: null, Svg: null,
Url: './images/arrow-down.svg' Url: './images/arrow-down.svg'
}, },
Name: 'Arrow', Name: 'ArrowTopLeft',
PositionReference: 0 PositionReference: 0
}, },
{
Width: 32,
Height: 32,
Image: {
Base64Image: null,
Name: 'ArrowTopRight',
Svg: null,
Url: './images/arrow-down.svg'
},
Name: 'ArrowTopRight',
PositionReference: 2
},
{
Width: 32,
Height: 32,
Image: {
Base64Image: null,
Name: 'ArrowCenterRight',
Svg: null,
Url: './images/arrow-down.svg'
},
Name: 'ArrowCenterRight',
PositionReference: 5
},
{
Width: 32,
Height: 32,
Image: {
Base64Image: null,
Name: 'ArrowBottomRight',
Svg: null,
Url: './images/arrow-down.svg'
},
Name: 'ArrowBottomRight',
PositionReference: 8
},
{ {
Width: 32, Width: 32,
Height: 32, Height: 32,
@ -334,7 +370,7 @@ const GetSVGLayoutConfiguration = () => {
Height: 200, Height: 200,
Orientation: 0, Orientation: 0,
Style: { Style: {
stroke: 'black', stroke: '#000000',
strokeWidth: 2, strokeWidth: 2,
fillOpacity: 0 fillOpacity: 0
} }