diff --git a/@beautiful-tree/react/src/BeautifulTree.tsx b/@beautiful-tree/react/src/BeautifulTree.tsx index 0669637..9aeb974 100644 --- a/@beautiful-tree/react/src/BeautifulTree.tsx +++ b/@beautiful-tree/react/src/BeautifulTree.tsx @@ -1,9 +1,14 @@ +import { + computeAxesCoefAndNodeDimension, + coordinateCreators, +} from './treePosition' import { computeSmartLayout, edgesIterator, postOrderIterator, } from '@beautiful-tree/algorithms' import { Fragment } from 'react' +import type { Orientation } from './treePosition' import type { Tree } from '@beautiful-tree/types' import type { WrappedTreeWithLayout } from '@beautiful-tree/algorithms' export { @@ -33,6 +38,7 @@ export interface BeautifulTreeProps { readonly nodeShape?: 'circle' | 'rect' readonly hCoef?: number readonly tree: Tree + readonly orientation?: Orientation readonly computeLayout?: | ((tree: Readonly) => Readonly) | undefined @@ -63,6 +69,7 @@ export function BeautifulTree({ nodeShape, hCoef = 1, tree, + orientation = 'T-D', computeLayout, getNodeClass, getNodeShape, @@ -74,14 +81,32 @@ export function BeautifulTree({ const { tree: treeWithLayout, mX, mY } = computeLayout(tree) const { width, height, sizeUnit = 'px' } = svgProps - const xCoef = width / (mX + 2) - const yCoef = height / (mY + 2) - const maxNodeWidth = xCoef * 0.5 - const maxNodeHeight = Math.min(yCoef * 0.5, maxNodeWidth * hCoef) + const { xCoef, yCoef, maxNodeHeight, maxNodeWidth } = + computeAxesCoefAndNodeDimension(orientation, { + width, + height, + hCoef, + mX, + mY, + }) + const widthCenterShift = maxNodeWidth * 0.5 const heightCenterShift = maxNodeHeight * 0.5 const maxNodeRadius = maxNodeHeight * 0.5 + const { + circleCoordinateCreator, + lineCoordinateCreator, + rectCoordinateCreator, + } = coordinateCreators(orientation, { + width, + height, + xCoef, + yCoef, + heightCenterShift, + widthCenterShift, + }) + return ( ) })} @@ -134,8 +156,7 @@ export function BeautifulTree({ getNodeClass, node.data, )}`} - x={(nm.pos.x + 1) * xCoef - widthCenterShift} - y={(nm.pos.y + 1) * yCoef - heightCenterShift} + {...rectCoordinateCreator(nm)} width={maxNodeWidth} height={maxNodeHeight} /> @@ -143,16 +164,14 @@ export function BeautifulTree({ )} {getNodeContent ? ( diff --git a/@beautiful-tree/react/src/stories/BeautifulTree.stories.ts b/@beautiful-tree/react/src/stories/BeautifulTree.stories.ts index 18ce4e9..2103116 100644 --- a/@beautiful-tree/react/src/stories/BeautifulTree.stories.ts +++ b/@beautiful-tree/react/src/stories/BeautifulTree.stories.ts @@ -211,3 +211,100 @@ export const Centered3_Wide_Tree_Random: Story = { getEdgeClass: getCssFromEdgeData, }, } + +export const Normal_Orientation_Small_Tree: Story = { + args: { + id: 'normal_orientation_small_tree', + svgProps: { + width: 400, + height: 400, + }, + tree: smallTree, + orientation: 'T-D', + getNodeContent: (data) => data?.['v']?.toString() ?? '', + }, +} + +export const LR_Orientation_Small_Tree: Story = { + args: { + id: 'lr_orientation_small_tree', + svgProps: { + width: 400, + height: 400, + }, + tree: smallTree, + orientation: 'L-R', + getNodeContent: (data) => data?.['v']?.toString() ?? '', + }, +} + +export const RL_Orientation_Small_Tree: Story = { + args: { + id: 'rl_orientation_small_tree', + svgProps: { + width: 400, + height: 400, + }, + tree: smallTree, + orientation: 'R-L', + computeLayout: computeSmartLayout, + getNodeContent: (data) => data?.['v']?.toString() ?? '', + }, +} + +export const DT_Orientation_Small_Tree: Story = { + args: { + id: 'dt_orientation_small_tree', + svgProps: { + width: 400, + height: 400, + }, + tree: smallTree, + orientation: 'D-T', + computeLayout: computeSmartLayout, + getNodeContent: (data) => data?.['v']?.toString() ?? '', + }, +} + +export const LR_Orientation_Wide_Tree_A_On_Rectangle: Story = { + args: { + id: 'lr_orientation_wide_tree_a_on_rectangle', + svgProps: { + width: 250, + height: 450, + }, + tree: wideTree_A, + orientation: 'L-R', + computeLayout: computeSmartLayout, + getNodeClass: getCssFromNodeData, + getEdgeClass: getCssFromEdgeData, + }, +} + +export const RL_Orientation_Wide_Tree_Bm_On_Rectangle: Story = { + args: { + id: 'rl_orientation_wide_tree_bm_on_rectangle', + svgProps: { + width: 250, + height: 450, + }, + tree: smallTree, + orientation: 'R-L', + computeLayout: computeSmartLayout, + getNodeContent: (data) => data?.['v']?.toString() ?? '', + }, +} + +export const DT_Orientation_Wide_Tree_D_On_Rectangle: Story = { + args: { + id: 'dt_orientation_wide_tree_d_on_rectangle', + svgProps: { + width: 250, + height: 450, + }, + tree: smallTree, + orientation: 'D-T', + computeLayout: computeSmartLayout, + getNodeContent: (data) => data?.['v']?.toString() ?? '', + }, +} diff --git a/@beautiful-tree/react/src/tests/BeautifulTree.test.tsx b/@beautiful-tree/react/src/tests/BeautifulTree.test.tsx index 6adff86..c887f7a 100644 --- a/@beautiful-tree/react/src/tests/BeautifulTree.test.tsx +++ b/@beautiful-tree/react/src/tests/BeautifulTree.test.tsx @@ -225,4 +225,75 @@ describe('BeautifulTree : Smart Layout', () => { expect(rendered).toMatchSnapshot() }) + + it('renders small tree, with T-D orientation', () => { + const rendered = render( + , + ) + + expect(rendered).toMatchSnapshot() + }) + + it('renders small tree, with L-R orientation', () => { + const rendered = render( + data?.['v']?.toString() ?? ''} + />, + ) + + expect(rendered).toMatchSnapshot() + }) + + it('renders small tree, with R-L orientation', () => { + const rendered = render( + data?.['v']?.toString() ?? ''} + />, + ) + + expect(rendered).toMatchSnapshot() + }) + + it('renders small tree, with D-T orientation', () => { + const rendered = render( + data?.['v']?.toString() ?? ''} + />, + ) + + expect(rendered).toMatchSnapshot() + }) }) diff --git a/@beautiful-tree/react/src/tests/__snapshots__/BeautifulTree.test.tsx.snap b/@beautiful-tree/react/src/tests/__snapshots__/BeautifulTree.test.tsx.snap index a15ff88..5916261 100644 --- a/@beautiful-tree/react/src/tests/__snapshots__/BeautifulTree.test.tsx.snap +++ b/@beautiful-tree/react/src/tests/__snapshots__/BeautifulTree.test.tsx.snap @@ -1752,6 +1752,15748 @@ exports[`BeautifulTree : Smart Layout > renders small tree 1`] = ` } `; +exports[`BeautifulTree : Smart Layout > renders small tree, with D-T orientation 1`] = ` +{ + "asFragment": [Function], + "baseElement": +
+ + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + +
+ 48 +
+
+ + +
+ 49 +
+
+ + +
+ 45 +
+
+ + +
+ 43 +
+
+ + +
+ 46 +
+
+ + +
+ 50 +
+
+ + +
+ 51 +
+
+ + +
+ 47 +
+
+ + +
+ 44 +
+
+ + +
+ 52 +
+
+ + +
+ 42 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + +
+ 48 +
+
+ + +
+ 49 +
+
+ + +
+ 45 +
+
+ + +
+ 43 +
+
+ + +
+ 61 +
+
+ + +
+ 46 +
+
+ + +
+ 55 +
+
+ + +
+ 56 +
+
+ + +
+ 57 +
+
+ + +
+ 58 +
+
+ + +
+ 59 +
+
+ + +
+ 60 +
+
+ + +
+ 50 +
+
+ + +
+ 51 +
+
+ + +
+ 47 +
+
+ + +
+ 44 +
+
+ + +
+ 52 +
+
+ + +
+ 42 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + +
+ 52 +
+
+ + +
+ 51 +
+
+ + +
+ 50 +
+
+ + +
+ 60 +
+
+ + +
+ 59 +
+
+ + +
+ 58 +
+
+ + +
+ 57 +
+
+ + +
+ 56 +
+
+ + +
+ 55 +
+
+ + +
+ 47 +
+
+ + +
+ 46 +
+
+ + +
+ 44 +
+
+ + +
+ 61 +
+
+ + +
+ 49 +
+
+ + +
+ 48 +
+
+ + +
+ 45 +
+
+ + +
+ 43 +
+
+ + +
+ 42 +
+
+
+
+
+ + + + + + + + + + + + + + +
+ -3 +
+
+ + +
+ -1.5 +
+
+ + +
+ -2 +
+
+ + +
+ -0.5 +
+
+ + +
+ -1 +
+
+ + +
+ 0.5 +
+
+ + +
+ 1.5 +
+
+ + +
+ 3 +
+
+ + +
+ 2 +
+
+ + +
+ 1 +
+
+ + +
+ 0 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + +
+ -4 +
+
+ + +
+ -2.5 +
+
+ + +
+ -3 +
+
+ + +
+ -1.5 +
+
+ + +
+ -2 +
+
+ + +
+ -0.5 +
+
+ + +
+ -1 +
+
+ + +
+ 0.5 +
+
+ + +
+ 1.5 +
+
+ + +
+ 2.5 +
+
+ + +
+ 4 +
+
+ + +
+ 3 +
+
+ + +
+ 2 +
+
+ + +
+ 1 +
+
+ + +
+ 0 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + +
+
+ + + + + + + + + + + + + + +
+
+ + + + + + + + + +
+ C +
+
+ + +
+ B +
+
+ + +
+ E +
+
+ + +
+ F +
+
+ + +
+ D +
+
+ + +
+ A +
+
+
+
+
+ + + + + + + + + +
+ C +
+
+ + +
+ B +
+
+ + +
+ E +
+
+ + +
+ F +
+
+ + +
+ D +
+
+ + +
+ A +
+
+
+
+
+ + + + + + + + + +
+ C +
+
+ + +
+ B +
+
+ + +
+ E +
+
+ + +
+ F +
+
+ + +
+ D +
+
+ + +
+ A +
+
+
+
+ , + "container":
+ + + + + + + + + +
+ C +
+
+ + +
+ B +
+
+ + +
+ E +
+
+ + +
+ F +
+
+ + +
+ D +
+
+ + +
+ A +
+
+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; + +exports[`BeautifulTree : Smart Layout > renders small tree, with L-R orientation 1`] = ` +{ + "asFragment": [Function], + "baseElement": +
+ + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + +
+ 48 +
+
+ + +
+ 49 +
+
+ + +
+ 45 +
+
+ + +
+ 43 +
+
+ + +
+ 46 +
+
+ + +
+ 50 +
+
+ + +
+ 51 +
+
+ + +
+ 47 +
+
+ + +
+ 44 +
+
+ + +
+ 52 +
+
+ + +
+ 42 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + +
+ 48 +
+
+ + +
+ 49 +
+
+ + +
+ 45 +
+
+ + +
+ 43 +
+
+ + +
+ 61 +
+
+ + +
+ 46 +
+
+ + +
+ 55 +
+
+ + +
+ 56 +
+
+ + +
+ 57 +
+
+ + +
+ 58 +
+
+ + +
+ 59 +
+
+ + +
+ 60 +
+
+ + +
+ 50 +
+
+ + +
+ 51 +
+
+ + +
+ 47 +
+
+ + +
+ 44 +
+
+ + +
+ 52 +
+
+ + +
+ 42 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + +
+ 52 +
+
+ + +
+ 51 +
+
+ + +
+ 50 +
+
+ + +
+ 60 +
+
+ + +
+ 59 +
+
+ + +
+ 58 +
+
+ + +
+ 57 +
+
+ + +
+ 56 +
+
+ + +
+ 55 +
+
+ + +
+ 47 +
+
+ + +
+ 46 +
+
+ + +
+ 44 +
+
+ + +
+ 61 +
+
+ + +
+ 49 +
+
+ + +
+ 48 +
+
+ + +
+ 45 +
+
+ + +
+ 43 +
+
+ + +
+ 42 +
+
+
+
+
+ + + + + + + + + + + + + + +
+ -3 +
+
+ + +
+ -1.5 +
+
+ + +
+ -2 +
+
+ + +
+ -0.5 +
+
+ + +
+ -1 +
+
+ + +
+ 0.5 +
+
+ + +
+ 1.5 +
+
+ + +
+ 3 +
+
+ + +
+ 2 +
+
+ + +
+ 1 +
+
+ + +
+ 0 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + +
+ -4 +
+
+ + +
+ -2.5 +
+
+ + +
+ -3 +
+
+ + +
+ -1.5 +
+
+ + +
+ -2 +
+
+ + +
+ -0.5 +
+
+ + +
+ -1 +
+
+ + +
+ 0.5 +
+
+ + +
+ 1.5 +
+
+ + +
+ 2.5 +
+
+ + +
+ 4 +
+
+ + +
+ 3 +
+
+ + +
+ 2 +
+
+ + +
+ 1 +
+
+ + +
+ 0 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + +
+
+ + + + + + + + + + + + + + +
+
+ + + + + + + + + +
+ C +
+
+ + +
+ B +
+
+ + +
+ E +
+
+ + +
+ F +
+
+ + +
+ D +
+
+ + +
+ A +
+
+
+
+ , + "container":
+ + + + + + + + + +
+ C +
+
+ + +
+ B +
+
+ + +
+ E +
+
+ + +
+ F +
+
+ + +
+ D +
+
+ + +
+ A +
+
+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; + +exports[`BeautifulTree : Smart Layout > renders small tree, with R-L orientation 1`] = ` +{ + "asFragment": [Function], + "baseElement": +
+ + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + +
+ 48 +
+
+ + +
+ 49 +
+
+ + +
+ 45 +
+
+ + +
+ 43 +
+
+ + +
+ 46 +
+
+ + +
+ 50 +
+
+ + +
+ 51 +
+
+ + +
+ 47 +
+
+ + +
+ 44 +
+
+ + +
+ 52 +
+
+ + +
+ 42 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + +
+ 48 +
+
+ + +
+ 49 +
+
+ + +
+ 45 +
+
+ + +
+ 43 +
+
+ + +
+ 61 +
+
+ + +
+ 46 +
+
+ + +
+ 55 +
+
+ + +
+ 56 +
+
+ + +
+ 57 +
+
+ + +
+ 58 +
+
+ + +
+ 59 +
+
+ + +
+ 60 +
+
+ + +
+ 50 +
+
+ + +
+ 51 +
+
+ + +
+ 47 +
+
+ + +
+ 44 +
+
+ + +
+ 52 +
+
+ + +
+ 42 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + +
+ 52 +
+
+ + +
+ 51 +
+
+ + +
+ 50 +
+
+ + +
+ 60 +
+
+ + +
+ 59 +
+
+ + +
+ 58 +
+
+ + +
+ 57 +
+
+ + +
+ 56 +
+
+ + +
+ 55 +
+
+ + +
+ 47 +
+
+ + +
+ 46 +
+
+ + +
+ 44 +
+
+ + +
+ 61 +
+
+ + +
+ 49 +
+
+ + +
+ 48 +
+
+ + +
+ 45 +
+
+ + +
+ 43 +
+
+ + +
+ 42 +
+
+
+
+
+ + + + + + + + + + + + + + +
+ -3 +
+
+ + +
+ -1.5 +
+
+ + +
+ -2 +
+
+ + +
+ -0.5 +
+
+ + +
+ -1 +
+
+ + +
+ 0.5 +
+
+ + +
+ 1.5 +
+
+ + +
+ 3 +
+
+ + +
+ 2 +
+
+ + +
+ 1 +
+
+ + +
+ 0 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + +
+ -4 +
+
+ + +
+ -2.5 +
+
+ + +
+ -3 +
+
+ + +
+ -1.5 +
+
+ + +
+ -2 +
+
+ + +
+ -0.5 +
+
+ + +
+ -1 +
+
+ + +
+ 0.5 +
+
+ + +
+ 1.5 +
+
+ + +
+ 2.5 +
+
+ + +
+ 4 +
+
+ + +
+ 3 +
+
+ + +
+ 2 +
+
+ + +
+ 1 +
+
+ + +
+ 0 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + +
+
+ + + + + + + + + + + + + + +
+
+ + + + + + + + + +
+ C +
+
+ + +
+ B +
+
+ + +
+ E +
+
+ + +
+ F +
+
+ + +
+ D +
+
+ + +
+ A +
+
+
+
+
+ + + + + + + + + +
+ C +
+
+ + +
+ B +
+
+ + +
+ E +
+
+ + +
+ F +
+
+ + +
+ D +
+
+ + +
+ A +
+
+
+
+ , + "container":
+ + + + + + + + + +
+ C +
+
+ + +
+ B +
+
+ + +
+ E +
+
+ + +
+ F +
+
+ + +
+ D +
+
+ + +
+ A +
+
+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; + +exports[`BeautifulTree : Smart Layout > renders small tree, with T-D orientation 1`] = ` +{ + "asFragment": [Function], + "baseElement": +
+ + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + +
+ 48 +
+
+ + +
+ 49 +
+
+ + +
+ 45 +
+
+ + +
+ 43 +
+
+ + +
+ 46 +
+
+ + +
+ 50 +
+
+ + +
+ 51 +
+
+ + +
+ 47 +
+
+ + +
+ 44 +
+
+ + +
+ 52 +
+
+ + +
+ 42 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + +
+ 48 +
+
+ + +
+ 49 +
+
+ + +
+ 45 +
+
+ + +
+ 43 +
+
+ + +
+ 61 +
+
+ + +
+ 46 +
+
+ + +
+ 55 +
+
+ + +
+ 56 +
+
+ + +
+ 57 +
+
+ + +
+ 58 +
+
+ + +
+ 59 +
+
+ + +
+ 60 +
+
+ + +
+ 50 +
+
+ + +
+ 51 +
+
+ + +
+ 47 +
+
+ + +
+ 44 +
+
+ + +
+ 52 +
+
+ + +
+ 42 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + +
+ 52 +
+
+ + +
+ 51 +
+
+ + +
+ 50 +
+
+ + +
+ 60 +
+
+ + +
+ 59 +
+
+ + +
+ 58 +
+
+ + +
+ 57 +
+
+ + +
+ 56 +
+
+ + +
+ 55 +
+
+ + +
+ 47 +
+
+ + +
+ 46 +
+
+ + +
+ 44 +
+
+ + +
+ 61 +
+
+ + +
+ 49 +
+
+ + +
+ 48 +
+
+ + +
+ 45 +
+
+ + +
+ 43 +
+
+ + +
+ 42 +
+
+
+
+
+ + + + + + + + + + + + + + +
+ -3 +
+
+ + +
+ -1.5 +
+
+ + +
+ -2 +
+
+ + +
+ -0.5 +
+
+ + +
+ -1 +
+
+ + +
+ 0.5 +
+
+ + +
+ 1.5 +
+
+ + +
+ 3 +
+
+ + +
+ 2 +
+
+ + +
+ 1 +
+
+ + +
+ 0 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + +
+ -4 +
+
+ + +
+ -2.5 +
+
+ + +
+ -3 +
+
+ + +
+ -1.5 +
+
+ + +
+ -2 +
+
+ + +
+ -0.5 +
+
+ + +
+ -1 +
+
+ + +
+ 0.5 +
+
+ + +
+ 1.5 +
+
+ + +
+ 2.5 +
+
+ + +
+ 4 +
+
+ + +
+ 3 +
+
+ + +
+ 2 +
+
+ + +
+ 1 +
+
+ + +
+ 0 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + +
+
+ + + + + + + + + + + + + + +
+ , + "container":
+ + + + + + + + + + + + + + +
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; + exports[`BeautifulTree : Smart Layout > renders wide tree A, with rect shape, node content display, and dynamic css classes 1`] = ` { "asFragment": [Function], diff --git a/@beautiful-tree/react/src/treePosition.ts b/@beautiful-tree/react/src/treePosition.ts new file mode 100644 index 0000000..9759621 --- /dev/null +++ b/@beautiful-tree/react/src/treePosition.ts @@ -0,0 +1,175 @@ +import type { Edge, TreeWithLayout } from '@beautiful-tree/types' + +interface LineCoordinates { + x1: number + y1: number + x2: number + y2: number +} + +interface RectangleCoordinates { + x: number + y: number +} + +interface CircleCoordinates { + cx: number + cy: number +} + +type TreeMetaData = TreeWithLayout['meta'] + +export type Orientation = 'D-T' | 'L-R' | 'R-L' | 'T-D' + +export function coordinateCreators( + orientation: Orientation, + layoutProps: Readonly<{ + width: number + height: number + xCoef: number + yCoef: number + widthCenterShift: number + heightCenterShift: number + }>, +): { + lineCoordinateCreator: (edge: Readonly) => LineCoordinates + rectCoordinateCreator: (nm: TreeMetaData) => RectangleCoordinates + circleCoordinateCreator: (nm: TreeMetaData) => CircleCoordinates +} { + const { width, height, xCoef, yCoef, widthCenterShift, heightCenterShift } = + layoutProps + return { + lineCoordinateCreator: function (edge: Readonly): LineCoordinates { + switch (orientation) { + case 'D-T': { + return { + x1: (edge.start.x + 1) * xCoef, + y1: height - (edge.start.y + 1) * yCoef, + x2: (edge.end.x + 1) * xCoef, + y2: height - (edge.end.y + 1) * yCoef, + } + } + case 'L-R': { + return { + x1: (edge.start.y + 1) * yCoef, + y1: height - (edge.start.x + 1) * xCoef, + x2: (edge.end.y + 1) * yCoef, + y2: height - (edge.end.x + 1) * xCoef, + } + } + case 'R-L': { + return { + x1: width - (edge.start.y + 1) * yCoef, + y1: height - (edge.start.x + 1) * xCoef, + x2: width - (edge.end.y + 1) * yCoef, + y2: height - (edge.end.x + 1) * xCoef, + } + } + case 'T-D': { + return { + x1: (edge.start.x + 1) * xCoef, + y1: (edge.start.y + 1) * yCoef, + x2: (edge.end.x + 1) * xCoef, + y2: (edge.end.y + 1) * yCoef, + } + } + } + }, + + rectCoordinateCreator: function (nm: TreeMetaData): RectangleCoordinates { + switch (orientation) { + case 'D-T': { + return { + x: (nm.pos.x + 1) * xCoef - widthCenterShift, + y: height - (nm.pos.y + 1) * yCoef - heightCenterShift, + } + } + case 'L-R': { + return { + x: (nm.pos.y + 1) * yCoef - heightCenterShift, + y: height - (nm.pos.x + 1) * xCoef - widthCenterShift, + } + } + case 'R-L': { + return { + x: width - (nm.pos.y + 1) * yCoef - heightCenterShift, + y: height - (nm.pos.x + 1) * xCoef - widthCenterShift, + } + } + case 'T-D': { + return { + x: (nm.pos.x + 1) * xCoef - widthCenterShift, + y: (nm.pos.y + 1) * yCoef - heightCenterShift, + } + } + } + }, + + circleCoordinateCreator: function (nm: TreeMetaData): CircleCoordinates { + switch (orientation) { + case 'D-T': { + return { + cx: (nm.pos.x + 1) * xCoef, + cy: height - (nm.pos.y + 1) * yCoef, + } + } + case 'L-R': { + return { + cx: (nm.pos.y + 1) * yCoef, + cy: height - (nm.pos.x + 1) * xCoef, + } + } + case 'R-L': { + return { + cx: width - (nm.pos.y + 1) * yCoef, + cy: height - (nm.pos.x + 1) * xCoef, + } + } + case 'T-D': { + return { + cx: (nm.pos.x + 1) * xCoef, + cy: (nm.pos.y + 1) * yCoef, + } + } + } + }, + } +} + +export function computeAxesCoefAndNodeDimension( + orientation: Orientation, + layoutProps: Readonly<{ + width: number + height: number + hCoef: number + mX: number + mY: number + }>, +): { + xCoef: number + yCoef: number + maxNodeHeight: number + maxNodeWidth: number +} { + const { width, height, hCoef, mX, mY } = layoutProps + + let xCoef: number, yCoef: number, maxNodeHeight: number, maxNodeWidth: number + + if (orientation === 'L-R' || orientation === 'R-L') { + xCoef = height / (mY + 2) + yCoef = width / (mX + 2) + maxNodeWidth = yCoef * 0.5 + maxNodeHeight = Math.min(xCoef * 0.5, maxNodeWidth * hCoef) + } else { + xCoef = width / (mX + 2) + yCoef = height / (mY + 2) + maxNodeWidth = xCoef * 0.5 + maxNodeHeight = Math.min(yCoef * 0.5, maxNodeWidth * hCoef) + } + return { + xCoef, + yCoef, + maxNodeHeight, + maxNodeWidth, + } +}