From 338a2c157c8830d532aa3cad61cfa1e78fac94cc Mon Sep 17 00:00:00 2001 From: Eric Nguyen Date: Mon, 13 Feb 2023 14:54:50 +0000 Subject: [PATCH 1/2] Merged PR 330: Add DimensionStyle + Refactor dimensionLayer + Add width and dashArray to style Add DimensionStyle + Refactor dimensionLayer + Add width and dashArray to style Related work items: #7977 --- .../SVGLDLibs/Models/DimensionOptions.cs | 51 +- .../SVGLDLibs/Models/DimensionStyle.cs | 27 ++ .../ContainerProperties/ContainerForm.tsx | 452 +++++++++++------- .../Editor/Actions/ContainerOperations.ts | 12 + src/Components/SVG/Elements/Dimension.tsx | 12 +- .../SVG/Elements/DimensionLayer.tsx | 111 ++--- src/Enums/PropertyType.ts | 15 +- src/Interfaces/IAvailableContainer.ts | 16 +- src/Interfaces/IDimensionOptions.ts | 9 +- src/Interfaces/IDimensionStyle.ts | 12 + src/Interfaces/ISymbolModel.ts | 2 +- src/Translations/translation.en.json | 9 +- src/Translations/translation.fr.json | 3 + src/utils/default.ts | 68 +-- 14 files changed, 475 insertions(+), 324 deletions(-) create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/DimensionStyle.cs create mode 100644 src/Interfaces/IDimensionStyle.ts diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/DimensionOptions.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/DimensionOptions.cs index a98e500..42aafd7 100644 --- a/csharp/SVGLDLibs/SVGLDLibs/Models/DimensionOptions.cs +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/DimensionOptions.cs @@ -1,28 +1,23 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.Serialization; -using System.Text; -using System.Threading.Tasks; - -namespace SVGLDLibs.Models -{ - - [DataContract] - public class DimensionOptions - { - - /** positions of the dimension */ - [DataMember(EmitDefaultValue = false)] - public Position[] positions; - - /** color */ - [DataMember(EmitDefaultValue = false)] - public string color; - - - - - } - -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; + +namespace SVGLDLibs.Models +{ + + [DataContract] + public class DimensionOptions + { + + /** positions of the dimension */ + [DataMember(EmitDefaultValue = false)] + public Position[] positions; + + /** color */ + [DataMember(EmitDefaultValue = false)] + public DimensionStyle style; + } +} diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/DimensionStyle.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/DimensionStyle.cs new file mode 100644 index 0000000..c35cd5f --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/DimensionStyle.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; + +namespace SVGLDLibs.Models +{ + + [DataContract] + public class DimensionStyle + { + /** color */ + [DataMember(EmitDefaultValue = false)] + public string color; + + /** width */ + + [DataMember(EmitDefaultValue = false)] + public double width; + + /** color */ + [DataMember(EmitDefaultValue = false)] + public string dashArray; + } +} diff --git a/src/Components/ContainerProperties/ContainerForm.tsx b/src/Components/ContainerProperties/ContainerForm.tsx index 4bdc262..6781302 100644 --- a/src/Components/ContainerProperties/ContainerForm.tsx +++ b/src/Components/ContainerProperties/ContainerForm.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { PropertyType } from '../../Enums/PropertyType'; -import { IContainerProperties } from '../../Interfaces/IContainerProperties'; -import { ISymbolModel } from '../../Interfaces/ISymbolModel'; +import { type IContainerProperties } from '../../Interfaces/IContainerProperties'; +import { type ISymbolModel } from '../../Interfaces/ISymbolModel'; import { SHOW_BORROWER_DIMENSIONS, SHOW_CHILDREN_DIMENSIONS, @@ -46,7 +46,7 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element { inputClassName='' type='string' value={props.properties.displayedText?.toString()} - onChange={(value) => props.onChange('displayedText', value)}/> + onChange={(value) => { props.onChange('displayedText', value); }}/> props.onChange( - 'x', - ApplyXMargin( - RestoreX( - Number(value), - props.properties.width, - props.properties.positionReference - ), - props.properties.margin.left - ) - )}/> + onChange={(value) => { + props.onChange( + 'x', + ApplyXMargin( + RestoreX( + Number(value), + props.properties.width, + props.properties.positionReference + ), + props.properties.margin.left + ) + ); + }}/> props.onChange( - 'y', - ApplyXMargin( - RestoreY( - Number(value), - props.properties.height, - props.properties.positionReference - ), - props.properties.margin.top - ) - )}/> + onChange={(value) => { + props.onChange( + 'y', + ApplyXMargin( + RestoreY( + Number(value), + props.properties.height, + props.properties.positionReference + ), + props.properties.margin.top + ) + ); + }}/> @@ -171,7 +175,7 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element { type='number' min={1} value={props.properties.minWidth.toString()} - onChange={(value) => props.onChange('minWidth', Number(value))}/> + onChange={(value) => { props.onChange('minWidth', Number(value)); }}/> props.onChange('width', ApplyWidthMargin(Number(value), props.properties.margin.left, props.properties.margin.right))} + onChange={(value) => { props.onChange('width', ApplyWidthMargin(Number(value), props.properties.margin.left, props.properties.margin.right)); }} isDisabled={props.properties.isFlex}/> props.onChange('maxWidth', Number(value))}/> + onChange={(value) => { props.onChange('maxWidth', Number(value)); }}/>
props.onChange('minHeight', Number(value))}/> + onChange={(value) => { props.onChange('minHeight', Number(value)); }}/> props.onChange('height', ApplyWidthMargin(Number(value), props.properties.margin.top, props.properties.margin.bottom))} + onChange={(value) => { props.onChange('height', ApplyWidthMargin(Number(value), props.properties.margin.top, props.properties.margin.bottom)); }} isDisabled={props.properties.isFlex} /> props.onChange('maxHeight', Number(value))}/> + onChange={(value) => { props.onChange('maxHeight', Number(value)); }}/> @@ -247,7 +251,7 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element { type='number' min={0} value={(props.properties.margin.left ?? 0).toString()} - onChange={(value) => props.onChange('left', Number(value), PropertyType.Margin)}/> + onChange={(value) => { props.onChange('left', Number(value), PropertyType.Margin); }}/> props.onChange('bottom', Number(value), PropertyType.Margin)}/> + onChange={(value) => { props.onChange('bottom', Number(value), PropertyType.Margin); }}/> props.onChange('top', Number(value), PropertyType.Margin)}/> + onChange={(value) => { props.onChange('top', Number(value), PropertyType.Margin); }}/> props.onChange('right', Number(value), PropertyType.Margin)}/> + onChange={(value) => { props.onChange('right', Number(value), PropertyType.Margin); }}/> @@ -295,7 +299,7 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element { inputClassName='ml-auto mr-auto block' type={ToggleType.Full} checked={props.properties.isFlex} - onChange={(event) => props.onChange('isFlex', event.target.checked)} + onChange={(event) => { props.onChange('isFlex', event.target.checked); }} /> props.onChange('isAnchor', event.target.checked)}/> + onChange={(event) => { props.onChange('isAnchor', event.target.checked); }}/> @@ -334,7 +338,7 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element { value: symbol.id }))} value={props.properties.linkedSymbolId ?? ''} - onChange={(event) => props.onChange('linkedSymbolId', event.target.value)}/> + onChange={(event) => { props.onChange('linkedSymbolId', event.target.value); }}/> @@ -347,168 +351,244 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
{ SHOW_SELF_DIMENSIONS && -
- props.onChange(key, value, PropertyType.SelfDimension)} - /> - props.onChange('color', e.target.value, PropertyType.SelfDimension)}/> -
+
+ { props.onChange(key, value, PropertyType.SelfDimension); }} + /> + { props.onChange('color', e.target.value, PropertyType.SelfDimensionStyle); }}/> + { props.onChange('width', Number(value), PropertyType.SelfDimensionStyle); }}/> + { props.onChange('dashArray', value, PropertyType.SelfDimensionStyle); }}/> +
} { SHOW_SELF_MARGINS_DIMENSIONS && -
- props.onChange(key, value, PropertyType.SelfMarginDimension)} - /> - props.onChange('color', e.target.value, PropertyType.SelfMarginDimension)}/> -
+
+ { props.onChange(key, value, PropertyType.SelfMarginDimension); }} + /> + { props.onChange('color', e.target.value, PropertyType.SelfMarginDimensionStyle); }}/> + { props.onChange('width', Number(value), PropertyType.SelfMarginDimensionStyle); }}/> + { props.onChange('dashArray', value, PropertyType.SelfMarginDimensionStyle); }}/> +
} { SHOW_CHILDREN_DIMENSIONS && -
- props.onChange(key, value, PropertyType.ChildrenDimensions)} - /> - props.onChange('color', e.target.value, PropertyType.ChildrenDimensions)}/> -
+
+ { props.onChange(key, value, PropertyType.ChildrenDimensions); }} + /> + { props.onChange('color', e.target.value, PropertyType.ChildrenDimensionsStyle); }}/> + { props.onChange('width', Number(value), PropertyType.ChildrenDimensionsStyle); }}/> + { props.onChange('dashArray', value, PropertyType.ChildrenDimensionsStyle); }}/> +
} { SHOW_BORROWER_DIMENSIONS && - <> -
- props.onChange(key, value, PropertyType.DimensionOptions)} - /> -
-
- props.onChange(key, value, PropertyType.DimensionWithMarks)} - /> - props.onChange('color', e.target.value, PropertyType.DimensionWithMarks)}/> -
- + <> +
+ { props.onChange(key, value, PropertyType.DimensionOptions); }} + /> +
+
+ { props.onChange(key, value, PropertyType.DimensionWithMarks); }} + /> + { props.onChange('color', e.target.value, PropertyType.DimensionWithMarksStyle); }}/> + { props.onChange('width', Number(value), PropertyType.DimensionWithMarksStyle); }}/> + { props.onChange('dashArray', value, PropertyType.DimensionWithMarksStyle); }}/> +
+ }
{props.properties.style !== undefined && - -
- props.onChange('stroke', value, PropertyType.Style)} - /> - props.onChange('strokeOpacity', Number(event.target.value), PropertyType.Style)} - /> - props.onChange('strokeWidth', Number(value), PropertyType.Style)} - /> - props.onChange('fill', value, PropertyType.Style)} - /> - props.onChange('fillOpacity', Number(event.target.value), PropertyType.Style)} - /> -
-
+ +
+ { props.onChange('stroke', value, PropertyType.Style); }} + /> + { props.onChange('strokeOpacity', Number(event.target.value), PropertyType.Style); }} + /> + { props.onChange('strokeWidth', Number(value), PropertyType.Style); }} + /> + { props.onChange('fill', value, PropertyType.Style); }} + /> + { props.onChange('fillOpacity', Number(event.target.value), PropertyType.Style); }} + /> +
+
} ); diff --git a/src/Components/Editor/Actions/ContainerOperations.ts b/src/Components/Editor/Actions/ContainerOperations.ts index 82162e3..4d5490a 100644 --- a/src/Components/Editor/Actions/ContainerOperations.ts +++ b/src/Components/Editor/Actions/ContainerOperations.ts @@ -362,6 +362,18 @@ function AssignProperty(container: IContainerModel, key: string, value: string | case PropertyType.DimensionWithMarks: (container.properties.dimensionOptions.dimensionWithMarks as any)[key] = value; break; + case PropertyType.SelfDimensionStyle: + (container.properties.dimensionOptions.selfDimensions.style as any)[key] = value; + break; + case PropertyType.SelfMarginDimensionStyle: + (container.properties.dimensionOptions.selfMarginsDimensions.style as any)[key] = value; + break; + case PropertyType.ChildrenDimensionsStyle: + (container.properties.dimensionOptions.childrenDimensions.style as any)[key] = value; + break; + case PropertyType.DimensionWithMarksStyle: + (container.properties.dimensionOptions.dimensionWithMarks.style as any)[key] = value; + break; case PropertyType.DimensionOptions: (container.properties.dimensionOptions as any)[key] = value; break; diff --git a/src/Components/SVG/Elements/Dimension.tsx b/src/Components/SVG/Elements/Dimension.tsx index 0848bea..88f7c99 100644 --- a/src/Components/SVG/Elements/Dimension.tsx +++ b/src/Components/SVG/Elements/Dimension.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { type IDimensionStyle } from '../../../Interfaces/IDimensionStyle'; import { NOTCHES_LENGTH } from '../../../utils/default'; interface IDimensionProps { @@ -8,7 +9,7 @@ interface IDimensionProps { xEnd: number yEnd: number text: string - color: string + style: IDimensionStyle scale?: number } @@ -28,8 +29,9 @@ function ApplyParametric(x0: number, t: number, vx: number): number { export function Dimension(props: IDimensionProps): JSX.Element { const scale = props.scale ?? 1; const style: React.CSSProperties = { - stroke: props.color, - strokeWidth: 2 / scale + stroke: props.style.color, + strokeWidth: (props.style.width ?? 2) / scale, + strokeDasharray: props.style.dashArray }; /// We need to find the points of the notches @@ -79,9 +81,11 @@ export function Dimension(props: IDimensionProps): JSX.Element { x2={endBottomX} y2={endBottomY} style={style}/> - @@ -37,8 +38,7 @@ function ActionByPosition( horizontalAction: (dim: number, ...params: any[]) => void, verticalAction: (dim: number, isRight: boolean, ...params: any[]) => void, params: any[] -): boolean { - let incrementDepthSymbols = false; +): void { positions.forEach((position: Position) => { const dim = dimMapped[position]; switch (position) { @@ -50,12 +50,10 @@ function ActionByPosition( } case Position.Down: case Position.Up: - incrementDepthSymbols = true; horizontalAction(dim, ...params); break; } }); - return incrementDepthSymbols; } /** @@ -74,7 +72,6 @@ function Dimensions({ containers, symbols, root, scale }: IDimensionLayerProps): if (!SHOW_SELF_DIMENSIONS) { return []; } - let startDepthSymbols: number = 0; for (const { container, depth, currentTransform } of it) { const offset = (DIMENSION_MARGIN * (depth + 1)) / scale; @@ -84,7 +81,7 @@ function Dimensions({ containers, symbols, root, scale }: IDimensionLayerProps): const containerRightDim = rightDim + offset; const dimMapped = [containerLeftDim, containerBottomDim, containerTopDim, containerRightDim]; if (SHOW_SELF_DIMENSIONS && container.properties.dimensionOptions.selfDimensions.positions.length > 0) { - const incrementDepthSymbol = ActionByPosition( + ActionByPosition( dimMapped, container.properties.dimensionOptions.selfDimensions.positions, AddHorizontalSelfDimension, @@ -93,14 +90,13 @@ function Dimensions({ containers, symbols, root, scale }: IDimensionLayerProps): container, currentTransform, dimensions, - scale, - container.properties.dimensionOptions.selfDimensions.color] + scale + ] ); - if (incrementDepthSymbol) { startDepthSymbols++; } } if (SHOW_SELF_MARGINS_DIMENSIONS && container.properties.dimensionOptions.selfMarginsDimensions.positions.length > 0) { - const incrementDepthSymbol = ActionByPosition( + ActionByPosition( dimMapped, container.properties.dimensionOptions.selfMarginsDimensions.positions, AddHorizontalSelfMarginsDimension, @@ -109,14 +105,13 @@ function Dimensions({ containers, symbols, root, scale }: IDimensionLayerProps): container, currentTransform, dimensions, - scale, - container.properties.dimensionOptions.selfMarginsDimensions.color] + scale + ] ); - if (incrementDepthSymbol) { startDepthSymbols++; } } if (SHOW_BORROWER_DIMENSIONS && container.properties.dimensionOptions.dimensionWithMarks.positions.length > 0) { - const incrementDepthSymbol = ActionByPosition( + ActionByPosition( dimMapped, container.properties.dimensionOptions.dimensionWithMarks.positions, @@ -128,14 +123,13 @@ function Dimensions({ containers, symbols, root, scale }: IDimensionLayerProps): depth, currentTransform, dimensions, - scale, - container.properties.dimensionOptions.dimensionWithMarks.color] + scale + ] ); - if (incrementDepthSymbol) { startDepthSymbols++; } } if (SHOW_CHILDREN_DIMENSIONS && container.properties.dimensionOptions.childrenDimensions.positions.length > 0 && container.children.length >= 2) { - const incrementDepthSymbol = ActionByPosition( + ActionByPosition( dimMapped, container.properties.dimensionOptions.childrenDimensions.positions, AddHorizontalChildrenDimension, @@ -145,28 +139,32 @@ function Dimensions({ containers, symbols, root, scale }: IDimensionLayerProps): container, currentTransform, dimensions, - scale, - container.properties.dimensionOptions.childrenDimensions.color] + scale + ] ); - - if (incrementDepthSymbol) { startDepthSymbols++; } } } + let startDepthSymbols: number = 0; for (const symbol of symbols) { if (symbol[1].showDimension) { startDepthSymbols++; - AddHorizontalSymbolDimension(symbol[1], dimensions, scale, 'black', startDepthSymbols); + AddHorizontalSymbolDimension( + symbol[1], + dimensions, + scale, + startDepthSymbols + ); } } return dimensions; } -function AddHorizontalSymbolDimension(symbol: ISymbolModel, +function AddHorizontalSymbolDimension( + symbol: ISymbolModel, dimensions: React.ReactNode[], scale: number, - color: string, depth: number ): void { const width = symbol.x + (symbol.width / 2); @@ -177,6 +175,11 @@ function AddHorizontalSymbolDimension(symbol: ISymbolModel, const text = width .toFixed(0) .toString(); + + // TODO: Put this in default.ts + const defaultDimensionSymbolStyle: IDimensionStyle = { + color: 'black' + }; dimensions.push( + style={defaultDimensionSymbolStyle}/> ); } } @@ -213,10 +216,10 @@ function AddHorizontalChildrenDimension( container: IContainerModel, currentTransform: [number, number], dimensions: React.ReactNode[], - scale: number, - color: string + scale: number ): void { const childrenId = `dim-y${yDim.toFixed(0)}-children-${container.properties.id}`; + const style = container.properties.dimensionOptions.childrenDimensions.style; const lastChildId = container.children[container.children.length - 1]; const lastChild = FindContainerById(containers, lastChildId); @@ -266,7 +269,7 @@ function AddHorizontalChildrenDimension( yEnd={yDim} text={textChildren} scale={scale} - color={color}/>); + style={style}/>); } function AddVerticalChildrenDimension( @@ -276,10 +279,10 @@ function AddVerticalChildrenDimension( container: IContainerModel, currentTransform: [number, number], dimensions: React.ReactNode[], - scale: number, - color: string + scale: number ): void { const childrenId = `dim-x${xDim.toFixed(0)}-children-${container.properties.id}`; + const style = container.properties.dimensionOptions.childrenDimensions.style; const lastChildId = container.children[container.children.length - 1]; const lastChild = FindContainerById(containers, lastChildId); @@ -334,7 +337,7 @@ function AddVerticalChildrenDimension( yEnd={yChildrenEnd + offset} text={textChildren} scale={scale} - color={color} + style={style} />); } @@ -345,9 +348,9 @@ function AddHorizontalBorrowerDimension( depth: number, currentTransform: [number, number], dimensions: React.ReactNode[], - scale: number, - color: string + scale: number ): void { + const style = container.properties.dimensionOptions.dimensionWithMarks.style; const it = MakeRecursionDFSIterator(container, containers, depth, currentTransform); const marks = []; // list of vertical lines for the dimension for (const { @@ -392,7 +395,7 @@ function AddHorizontalBorrowerDimension( yEnd={yDim} text={value.toFixed(0)} scale={scale} - color={color}/>); + style={style}/>); count++; } } @@ -405,9 +408,9 @@ function AddVerticalBorrowerDimension( depth: number, currentTransform: [number, number], dimensions: React.ReactNode[], - scale: number, - color: string + scale: number ): void { + const style = container.properties.dimensionOptions.dimensionWithMarks.style; const it = MakeRecursionDFSIterator(container, containers, depth, currentTransform); const marks = []; // list of vertical lines for the dimension for (const { @@ -457,7 +460,7 @@ function AddVerticalBorrowerDimension( yEnd={next} text={value.toFixed(0)} scale={scale} - color={color}/>); + style={style}/>); count++; } } @@ -468,9 +471,9 @@ function AddVerticalSelfDimension( container: IContainerModel, currentTransform: [number, number], dimensions: React.ReactNode[], - scale: number, - color: string + scale: number ): void { + const style = container.properties.dimensionOptions.selfDimensions.style; const height = container.properties.height; const idVert = `dim-x${xDim.toFixed(0)}-${container.properties.id}`; let yStart = container.properties.y + currentTransform[1] + height; @@ -493,7 +496,7 @@ function AddVerticalSelfDimension( yEnd={yEnd} text={textVert} scale={scale} - color={color}/> + style={style}/> ); } @@ -502,9 +505,9 @@ function AddHorizontalSelfDimension( container: IContainerModel, currentTransform: [number, number], dimensions: React.ReactNode[], - scale: number, - color: string + scale: number ): void { + const style = container.properties.dimensionOptions.selfDimensions.style; const width = container.properties.width; const id = `dim-y${yDim.toFixed(0)}-${container.properties.id}`; const xStart = container.properties.x + currentTransform[0]; @@ -522,7 +525,7 @@ function AddHorizontalSelfDimension( yEnd={yDim} text={text} scale={scale} - color={color}/> + style={style}/> ); } @@ -531,9 +534,9 @@ function AddHorizontalSelfMarginsDimension( container: IContainerModel, currentTransform: [number, number], dimensions: React.ReactNode[], - scale: number, - color: string + scale: number ): void { + const style = container.properties.dimensionOptions.selfMarginsDimensions.style; const left = container.properties.margin.left; if (left != null) { const id = `dim-y-margin-left${yDim.toFixed(0)}-${container.properties.id}`; @@ -552,7 +555,7 @@ function AddHorizontalSelfMarginsDimension( yEnd={yDim} text={text} scale={scale} - color={color}/> + style={style}/> ); } @@ -574,7 +577,7 @@ function AddHorizontalSelfMarginsDimension( yEnd={yDim} text={text} scale={scale} - color={color}/> + style={style}/> ); } } @@ -585,9 +588,9 @@ function AddVerticalSelfMarginDimension( container: IContainerModel, currentTransform: [number, number], dimensions: React.ReactNode[], - scale: number, - color: string + scale: number ): void { + const style = container.properties.dimensionOptions.selfMarginsDimensions.style; const top = container.properties.margin.top; if (top != null) { const idVert = `dim-x-margin-top${xDim.toFixed(0)}-${container.properties.id}`; @@ -611,7 +614,7 @@ function AddVerticalSelfMarginDimension( yEnd={yEnd} text={textVert} scale={scale} - color={color}/> + style={style}/> ); } const bottom = container.properties.margin.bottom; @@ -637,7 +640,7 @@ function AddVerticalSelfMarginDimension( yEnd={yEnd} text={textVert} scale={scale} - color={color}/> + style={style}/> ); } } diff --git a/src/Enums/PropertyType.ts b/src/Enums/PropertyType.ts index edd78ff..7c133b1 100644 --- a/src/Enums/PropertyType.ts +++ b/src/Enums/PropertyType.ts @@ -24,9 +24,16 @@ export enum PropertyType { * Dimension options */ SelfDimension, - SelfMarginDimension, - ChildrenDimensions, - DimensionWithMarks, - DimensionOptions + SelfDimensionStyle, + SelfMarginDimension, + SelfMarginDimensionStyle, + + ChildrenDimensions, + ChildrenDimensionsStyle, + + DimensionWithMarks, + DimensionWithMarksStyle, + + DimensionOptions } diff --git a/src/Interfaces/IAvailableContainer.ts b/src/Interfaces/IAvailableContainer.ts index dab4e59..d655ab2 100644 --- a/src/Interfaces/IAvailableContainer.ts +++ b/src/Interfaces/IAvailableContainer.ts @@ -1,12 +1,12 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import { AddMethod } from '../Enums/AddMethod'; -import { PositionReference } from '../Enums/PositionReference'; -import { IAction } from './IAction'; -import { IMargin } from './IMargin'; -import { Orientation } from '../Enums/Orientation'; -import { IKeyValue } from './IKeyValue'; -import { IStyle } from './IStyle'; -import { IDimensions } from './IDimensions'; +import { type AddMethod } from '../Enums/AddMethod'; +import { type PositionReference } from '../Enums/PositionReference'; +import { type IAction } from './IAction'; +import { type IMargin } from './IMargin'; +import { type Orientation } from '../Enums/Orientation'; +import { type IKeyValue } from './IKeyValue'; +import { type IStyle } from './IStyle'; +import { type IDimensions } from './IDimensions'; /** Model of available container used in application configuration */ export interface IAvailableContainer { diff --git a/src/Interfaces/IDimensionOptions.ts b/src/Interfaces/IDimensionOptions.ts index 4c44adf..b847626 100644 --- a/src/Interfaces/IDimensionOptions.ts +++ b/src/Interfaces/IDimensionOptions.ts @@ -1,10 +1,9 @@ -import { Position } from '../Enums/Position'; +import { type Position } from '../Enums/Position'; +import { type IDimensionStyle } from './IDimensionStyle'; export interface IDimensionOptions { positions: Position[] - /** - * Stroke color - */ - color: string + + style: IDimensionStyle } diff --git a/src/Interfaces/IDimensionStyle.ts b/src/Interfaces/IDimensionStyle.ts new file mode 100644 index 0000000..80e33a9 --- /dev/null +++ b/src/Interfaces/IDimensionStyle.ts @@ -0,0 +1,12 @@ +export interface IDimensionStyle { + /** + * Stroke color + */ + color?: string + + /** stroke-width */ + width?: number + + /** stroke-dasharray */ + dashArray?: string +} diff --git a/src/Interfaces/ISymbolModel.ts b/src/Interfaces/ISymbolModel.ts index 3a71290..ca0604b 100644 --- a/src/Interfaces/ISymbolModel.ts +++ b/src/Interfaces/ISymbolModel.ts @@ -1,4 +1,4 @@ -import { IAvailableSymbol } from './IAvailableSymbol'; +import { type IAvailableSymbol } from './IAvailableSymbol'; export interface ISymbolModel { /** Identifier */ diff --git a/src/Translations/translation.en.json b/src/Translations/translation.en.json index b9d78ed..65d7410 100644 --- a/src/Translations/translation.en.json +++ b/src/Translations/translation.en.json @@ -59,11 +59,14 @@ "@ContainerAlignmentInput": "Alignment", "@ContainerAlignWithSymbol": "Align to symbol", "@ContainerDimensions": "Dimensions", - "@ContainerShowDimension": "Show Dimension", - "@ContainerShowChildrenDimension": "Show surrounding dimension of children", + "@ContainerShowDimension": "Show dimensions", + "@ContainerShowChildrenDimension": "Show surrounding dimensions of children", "@ContainerMarkPosition": "Mark the position for the parents", - "@ContainerShowDimensionWithMarks": "Show dimension with marked children", + "@ContainerShowDimensionWithMarks": "Show dimensions with marked children", + "@ContainerShowMarginsDimension": "Show margins dimensions", "@ContainerStyle": "Style", + "@StyleStrokeColor": "Stroke Color", + "@StyleStrokeDashArray": "Stroke Dash Array", "@StyleStroke": "Stroke", "@StyleStrokeOpacity": "Stroke Opacity", "@StyleStrokeWidth": "Stroke Width", diff --git a/src/Translations/translation.fr.json b/src/Translations/translation.fr.json index 3d71f2c..3d2ce91 100644 --- a/src/Translations/translation.fr.json +++ b/src/Translations/translation.fr.json @@ -63,7 +63,10 @@ "@ContainerShowChildrenDimension": "Afficher les cotations englobante des enfants", "@ContainerMarkPosition": "Marquer la position pour les parents", "@ContainerShowDimensionWithMarks": "Afficher les cotations avec les enfants marqués", + "@ContainerShowMarginsDimension": "Afficher les cotations des marges", "@ContainerStyle": "Style", + "@StyleStrokeColor": "Couleur du tracé", + "@StyleStrokeDashArray": "Tableau de traits", "@StyleStroke": "Tracé", "@StyleStrokeOpacity": "Opacité du tracé", "@StyleStrokeWidth": "Epaisseur du tracé", diff --git a/src/utils/default.ts b/src/utils/default.ts index 632c12a..1b02c4f 100644 --- a/src/utils/default.ts +++ b/src/utils/default.ts @@ -1,13 +1,14 @@ import { PositionReference } from '../Enums/PositionReference'; -import { IAvailableContainer } from '../Interfaces/IAvailableContainer'; -import { IAvailableSymbol } from '../Interfaces/IAvailableSymbol'; -import { IConfiguration } from '../Interfaces/IConfiguration'; -import { ContainerModel, IContainerModel } from '../Interfaces/IContainerModel'; -import { IContainerProperties } from '../Interfaces/IContainerProperties'; -import { IEditorState } from '../Interfaces/IEditorState'; -import { ISymbolModel } from '../Interfaces/ISymbolModel'; +import { type IAvailableContainer } from '../Interfaces/IAvailableContainer'; +import { type IAvailableSymbol } from '../Interfaces/IAvailableSymbol'; +import { type IConfiguration } from '../Interfaces/IConfiguration'; +import { ContainerModel, type IContainerModel } from '../Interfaces/IContainerModel'; +import { type IContainerProperties } from '../Interfaces/IContainerProperties'; +import { type IEditorState } from '../Interfaces/IEditorState'; +import { type ISymbolModel } from '../Interfaces/ISymbolModel'; import { Orientation } from '../Enums/Orientation'; import { AppState } from '../Enums/AppState'; +import { type IDimensionOptions } from '../Interfaces/IDimensionOptions'; /// EDITOR DEFAULTS /// @@ -187,6 +188,16 @@ const DEFAULT_CONTAINER_STYLE = { strokeWidth: 2 }; +const DEFAULT_DIMENSION_STYLE = { + color: '#000000', + width: 2 +}; + +const DEFAULT_DIMENSION_OPTION: IDimensionOptions = { + positions: [], + style: DEFAULT_DIMENSION_STYLE +}; + /** * Default Main container properties */ @@ -211,23 +222,11 @@ export const DEFAULT_MAINCONTAINER_PROPS: IContainerProperties = { positionReference: PositionReference.TopLeft, hideChildrenInTreeview: false, dimensionOptions: { - childrenDimensions: { - color: '#000000', - positions: [] - }, - selfDimensions: { - color: '#000000', - positions: [] - }, - selfMarginsDimensions: { - color: '#000000', - positions: [] - }, + childrenDimensions: clone(DEFAULT_DIMENSION_OPTION), + selfDimensions: clone(DEFAULT_DIMENSION_OPTION), + selfMarginsDimensions: clone(DEFAULT_DIMENSION_OPTION), markPosition: [], - dimensionWithMarks: { - color: '#000000', - positions: [] - } + dimensionWithMarks: clone(DEFAULT_DIMENSION_OPTION) }, warning: '', style: DEFAULT_CONTAINER_STYLE @@ -276,21 +275,21 @@ export function GetDefaultContainerProps(type: string, hideChildrenInTreeview: containerConfig.HideChildrenInTreeview ?? false, dimensionOptions: { childrenDimensions: { - color: containerConfig.DimensionOptions?.childrenDimensions.color ?? '#000000', - positions: containerConfig.DimensionOptions?.childrenDimensions.positions ?? [] + positions: containerConfig.DimensionOptions?.childrenDimensions.positions ?? [], + style: containerConfig.DimensionOptions?.dimensionWithMarks.style ?? clone(DEFAULT_DIMENSION_STYLE) }, selfDimensions: { - color: containerConfig.DimensionOptions?.selfDimensions.color ?? '#000000', - positions: containerConfig.DimensionOptions?.selfDimensions.positions ?? [] + positions: containerConfig.DimensionOptions?.selfDimensions.positions ?? [], + style: containerConfig.DimensionOptions?.dimensionWithMarks.style ?? clone(DEFAULT_DIMENSION_STYLE) }, selfMarginsDimensions: { - color: containerConfig.DimensionOptions?.selfMarginsDimensions.color ?? '#000000', - positions: containerConfig.DimensionOptions?.selfMarginsDimensions.positions ?? [] + positions: containerConfig.DimensionOptions?.selfMarginsDimensions.positions ?? [], + style: containerConfig.DimensionOptions?.dimensionWithMarks.style ?? clone(DEFAULT_DIMENSION_STYLE) }, markPosition: containerConfig.DimensionOptions?.markPosition ?? [], dimensionWithMarks: { - color: containerConfig.DimensionOptions?.dimensionWithMarks.color ?? '#000000', - positions: containerConfig.DimensionOptions?.dimensionWithMarks.positions ?? [] + positions: containerConfig.DimensionOptions?.dimensionWithMarks.positions ?? [], + style: containerConfig.DimensionOptions?.dimensionWithMarks.style ?? clone(DEFAULT_DIMENSION_STYLE) } }, warning: '', @@ -317,3 +316,10 @@ export function GetDefaultSymbolModel(name: string, showDimension: false }; } + +/** + * Macro function for JSON.parse(JSON.stringify(obj)) + */ +function clone(object: T): T { + return JSON.parse(JSON.stringify(object)); +} From a123407b3a83e0eda800f96718092d4069a4feca Mon Sep 17 00:00:00 2001 From: Eric Nguyen Date: Mon, 13 Feb 2023 15:18:53 +0000 Subject: [PATCH 2/2] Merged PR 331: Remove DepthDimensionLayer + Add fixes from !330 --- src/Components/API/api.test.tsx | 22 +--- .../ContainerProperties.test.tsx | 21 +--- .../SVG/Elements/DepthDimensionLayer.tsx | 100 ------------------ src/Components/SVG/SVG.tsx | 6 +- src/utils/default.ts | 5 +- 5 files changed, 13 insertions(+), 141 deletions(-) delete mode 100644 src/Components/SVG/Elements/DepthDimensionLayer.tsx diff --git a/src/Components/API/api.test.tsx b/src/Components/API/api.test.tsx index 53f3ae0..08fcbad 100644 --- a/src/Components/API/api.test.tsx +++ b/src/Components/API/api.test.tsx @@ -10,7 +10,7 @@ import { IConfiguration } from '../../Interfaces/IConfiguration'; import { IContainerModel, ContainerModel } from '../../Interfaces/IContainerModel'; import { IHistoryState } from '../../Interfaces/IHistoryState'; import { IPattern } from '../../Interfaces/IPattern'; -import { DEFAULT_MAINCONTAINER_PROPS, GetDefaultContainerProps } from '../../utils/default'; +import { DEFAULT_DIMENSION_OPTION, DEFAULT_MAINCONTAINER_PROPS, GetDefaultContainerProps } from '../../utils/default'; import { FetchConfiguration } from './api'; const CSHARP_WEB_API_BASE_URL = 'http://localhost:5209/'; @@ -144,23 +144,11 @@ describe.concurrent('Models test suite', () => { PositionReference: 0, HideChildrenInTreeview: true, DimensionOptions: { - childrenDimensions: { - color: '#000000', - positions: [] - }, - selfDimensions: { - color: '#000000', - positions: [] - }, - selfMarginsDimensions: { - color: '#000000', - positions: [] - }, + childrenDimensions: DEFAULT_DIMENSION_OPTION, + selfDimensions: DEFAULT_DIMENSION_OPTION, + selfMarginsDimensions: DEFAULT_DIMENSION_OPTION, markPosition: [], - dimensionWithMarks: { - color: '#000000', - positions: [] - } + dimensionWithMarks: DEFAULT_DIMENSION_OPTION }, IsHidden: true, Blacklist: [ diff --git a/src/Components/ContainerProperties/ContainerProperties.test.tsx b/src/Components/ContainerProperties/ContainerProperties.test.tsx index cd2da15..01c36bd 100644 --- a/src/Components/ContainerProperties/ContainerProperties.test.tsx +++ b/src/Components/ContainerProperties/ContainerProperties.test.tsx @@ -5,6 +5,7 @@ import { PositionReference } from '../../Enums/PositionReference'; import { IContainerProperties } from '../../Interfaces/IContainerProperties'; import { Orientation } from '../../Enums/Orientation'; import { ContainerProperties } from './ContainerProperties'; +import { DEFAULT_DIMENSION_OPTION } from '../../utils/default'; describe.concurrent('Properties', () => { it('No properties', () => { @@ -43,23 +44,11 @@ describe.concurrent('Properties', () => { warning: '', hideChildrenInTreeview: false, dimensionOptions: { - childrenDimensions: { - color: '#000000', - positions: [] - }, - selfDimensions: { - color: '#000000', - positions: [] - }, - selfMarginsDimensions: { - color: '#000000', - positions: [] - }, + childrenDimensions: DEFAULT_DIMENSION_OPTION, + selfDimensions: DEFAULT_DIMENSION_OPTION, + selfMarginsDimensions: DEFAULT_DIMENSION_OPTION, markPosition: [], - dimensionWithMarks: { - color: '#000000', - positions: [] - } + dimensionWithMarks: DEFAULT_DIMENSION_OPTION } }; diff --git a/src/Components/SVG/Elements/DepthDimensionLayer.tsx b/src/Components/SVG/Elements/DepthDimensionLayer.tsx deleted file mode 100644 index f4bff37..0000000 --- a/src/Components/SVG/Elements/DepthDimensionLayer.tsx +++ /dev/null @@ -1,100 +0,0 @@ -import * as React from 'react'; -import { IContainerModel } from '../../../Interfaces/IContainerModel'; -import { DIMENSION_MARGIN } from '../../../utils/default'; -import { GetAbsolutePosition, MakeBFSIterator } from '../../../utils/itertools'; -import { TransformX } from '../../../utils/svg'; -import { Dimension } from './Dimension'; - -interface IDimensionLayerProps { - containers: Map - roots: IContainerModel | IContainerModel[] | null - scale?: number -} - -function GetDimensionsNodes( - containers: Map, - root: IContainerModel, - scale: number -): React.ReactNode[] { - const it = MakeBFSIterator(root, containers); - const dimensions: React.ReactNode[] = []; - let currentDepth = 0; - let min = Infinity; - let max = -Infinity; - let lastY = 0; - for (const { container, depth } of it) { - if (currentDepth !== depth) { - AddNewDimension(currentDepth, min, max, lastY, scale, '#000000', dimensions); - - currentDepth = depth; - min = Infinity; - max = -Infinity; - } - - const absoluteX = GetAbsolutePosition(containers, container)[0]; - const x = TransformX(absoluteX, container.properties.width, container.properties.positionReference); - lastY = container.properties.y + container.properties.height; - if (x < min) { - min = x; - } - - if (x > max) { - max = x; - } - } - - AddNewDimension(currentDepth, min, max, lastY, scale, '#000000', dimensions); - - return dimensions; -} - -/** - * A layer containing all dimension - * @param props - * @returns - */ -export function DepthDimensionLayer(props: IDimensionLayerProps): JSX.Element { - let dimensions: React.ReactNode[] = []; - const scale = props.scale ?? 1; - if (Array.isArray(props.roots)) { - props.roots.forEach(child => { - dimensions.concat(GetDimensionsNodes(props.containers, child, scale)); - }); - } else if (props.roots !== null) { - dimensions = GetDimensionsNodes(props.containers, props.roots, scale); - } - return ( - - {dimensions} - - ); -} - -function AddNewDimension(currentDepth: number, min: number, max: number, lastY: number, scale: number, color: string, dimensions: React.ReactNode[]): void { - const id = `dim-depth-${currentDepth}`; - const xStart = min; - const xEnd = max; - const y = lastY + (DIMENSION_MARGIN * (currentDepth + 1)) / scale; - const width = xEnd - xStart; - const text = width - .toFixed(0) - .toString(); - - if (width === 0) { - return; - } - - dimensions.push( - - ); -} diff --git a/src/Components/SVG/SVG.tsx b/src/Components/SVG/SVG.tsx index cdb11de..dc80773 100644 --- a/src/Components/SVG/SVG.tsx +++ b/src/Components/SVG/SVG.tsx @@ -3,8 +3,7 @@ import { ReactSVGPanZoom, Tool, TOOL_PAN, Value } from 'react-svg-pan-zoom'; import { Container } from './Elements/Container'; import { IContainerModel } from '../../Interfaces/IContainerModel'; import { Selector } from './Elements/Selector/Selector'; -import { DepthDimensionLayer } from './Elements/DepthDimensionLayer'; -import { MAX_FRAMERATE, SHOW_DIMENSIONS_PER_DEPTH } from '../../utils/default'; +import { MAX_FRAMERATE } from '../../utils/default'; import { SymbolLayer } from './Elements/SymbolLayer'; import { ISymbolModel } from '../../Interfaces/ISymbolModel'; import { DimensionLayer } from './Elements/DimensionLayer'; @@ -94,9 +93,6 @@ export function SVG(props: ISVGProps): JSX.Element { > {children} - {SHOW_DIMENSIONS_PER_DEPTH - ? - : null} {/* leave this at the end so it can be removed during the svg export */} diff --git a/src/utils/default.ts b/src/utils/default.ts index 1b02c4f..a5a6271 100644 --- a/src/utils/default.ts +++ b/src/utils/default.ts @@ -66,7 +66,6 @@ export const SHOW_SELF_DIMENSIONS = true; export const SHOW_SELF_MARGINS_DIMENSIONS = true; export const SHOW_CHILDREN_DIMENSIONS = true; export const SHOW_BORROWER_DIMENSIONS = true; -export const SHOW_DIMENSIONS_PER_DEPTH = false; export const DIMENSION_MARGIN = 50; export const SYMBOL_MARGIN = 25; export const NOTCHES_LENGTH = 10; @@ -188,12 +187,12 @@ const DEFAULT_CONTAINER_STYLE = { strokeWidth: 2 }; -const DEFAULT_DIMENSION_STYLE = { +export const DEFAULT_DIMENSION_STYLE = { color: '#000000', width: 2 }; -const DEFAULT_DIMENSION_OPTION: IDimensionOptions = { +export const DEFAULT_DIMENSION_OPTION: IDimensionOptions = { positions: [], style: DEFAULT_DIMENSION_STYLE };