From aeac4f2695bf103578b87062544afd5813a404c8 Mon Sep 17 00:00:00 2001 From: Stuart Hendren Date: Sun, 12 Mar 2023 18:22:10 +0000 Subject: [PATCH] feat: add a flag to layout on change The layout on change flag controll if the layout should be run when data is added or removed. This is on by default but turned off if a node is dragged. --- apps/docs/src/Graph.stories.tsx | 2 +- apps/docs/src/GraphToolbar.stories.tsx | 1 + package-lock.json | 2 +- packages/graph/src/graph/LayoutModel.test.ts | 5 ++ packages/graph/src/graph/LayoutModel.ts | 20 ++++++-- .../GraphDebugControl/GraphDebugControl.tsx | 23 ++++++++- .../GraphToolbar/GraphToolbar.test.tsx | 5 ++ .../components/GraphToolbar/GraphToolbar.tsx | 13 ++++- .../components/GraphToolbar/ReLayout.test.tsx | 24 +++++++++ .../src/components/GraphToolbar/ReLayout.tsx | 50 +++++++++++++++++++ .../graph/renderer/CytoscapeRenderer.test.tsx | 4 +- .../src/graph/renderer/CytoscapeRenderer.tsx | 17 +++++++ 12 files changed, 154 insertions(+), 12 deletions(-) create mode 100644 packages/react/src/components/GraphToolbar/ReLayout.test.tsx create mode 100644 packages/react/src/components/GraphToolbar/ReLayout.tsx diff --git a/apps/docs/src/Graph.stories.tsx b/apps/docs/src/Graph.stories.tsx index e6a2c19..9e1f040 100644 --- a/apps/docs/src/Graph.stories.tsx +++ b/apps/docs/src/Graph.stories.tsx @@ -1,7 +1,7 @@ import { Box, Column } from '@committed/components' +import { cytoscapeRenderer, Graph, GraphDebugControl } from '@committed/components-graph' import { Meta } from '@storybook/react' import React, { useState } from 'react' -import { Graph, cytoscapeRenderer, GraphDebugControl,} from '@committed/components-graph' import { exampleModel } from './StoryUtil' export default { diff --git a/apps/docs/src/GraphToolbar.stories.tsx b/apps/docs/src/GraphToolbar.stories.tsx index 2cbb71f..7767033 100644 --- a/apps/docs/src/GraphToolbar.stories.tsx +++ b/apps/docs/src/GraphToolbar.stories.tsx @@ -16,6 +16,7 @@ function isFunction( const empty = { zoom: false, layout: false, + relayout: false, refit: false, hide: false, size: false, diff --git a/package-lock.json b/package-lock.json index bfa9d1f..fdc53a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41106,7 +41106,7 @@ "@committed/components": "^8.1.3", "@committed/components-graph": "*", "@committed/config": "*", - "@faker-js/faker": "*", + "@faker-js/faker": "^7.6.0", "@storybook/addon-docs": "^6.5.12", "@storybook/addon-essentials": "^6.5.12", "@storybook/addons": "^6.5.12", diff --git a/packages/graph/src/graph/LayoutModel.test.ts b/packages/graph/src/graph/LayoutModel.test.ts index 0b0c1ee..c2740eb 100644 --- a/packages/graph/src/graph/LayoutModel.test.ts +++ b/packages/graph/src/graph/LayoutModel.test.ts @@ -43,3 +43,8 @@ it('Validating an validated layout does nothing', () => { const model = layoutModel.setLayout('grid').validate() expect(model.validate()).toBe(model) }) + +it('Changing the onChange does not invalidate the layout', () => { + expect(layoutModel.setOnChange(false).isDirty()).toBe(false) + expect(layoutModel.setOnChange(true).isDirty()).toBe(false) +}) diff --git a/packages/graph/src/graph/LayoutModel.ts b/packages/graph/src/graph/LayoutModel.ts index 9589887..fad528f 100644 --- a/packages/graph/src/graph/LayoutModel.ts +++ b/packages/graph/src/graph/LayoutModel.ts @@ -2,14 +2,16 @@ import { CustomGraphLayout, GraphLayout, PresetGraphLayout } from './types' export class LayoutModel { private readonly layout: GraphLayout + private readonly onChange: boolean private readonly invalidated: boolean static createDefault(): LayoutModel { - return new LayoutModel('force-directed', true) + return new LayoutModel('force-directed', true, true) } - constructor(layout: GraphLayout, invalidated = true) { + constructor(layout: GraphLayout, onChange = true, invalidated = true) { this.layout = layout + this.onChange = onChange this.invalidated = invalidated } @@ -21,11 +23,15 @@ export class LayoutModel { return this.invalidated } + isOnChange(): boolean { + return this.onChange + } + validate(): LayoutModel { if (!this.invalidated) { return this } else { - return new LayoutModel(this.layout, false) + return new LayoutModel(this.layout, this.onChange, false) } } @@ -33,12 +39,16 @@ export class LayoutModel { if (this.invalidated) { return this } else { - return new LayoutModel(this.layout, true) + return new LayoutModel(this.layout, this.onChange, true) } } setLayout(layout: GraphLayout): LayoutModel { - return new LayoutModel(layout, true) + return new LayoutModel(layout, this.onChange, true) + } + + setOnChange(onChange: boolean): LayoutModel { + return new LayoutModel(this.layout, onChange, false) } /** diff --git a/packages/react/src/components/GraphDebugControl/GraphDebugControl.tsx b/packages/react/src/components/GraphDebugControl/GraphDebugControl.tsx index 3e7b959..c8f81fb 100644 --- a/packages/react/src/components/GraphDebugControl/GraphDebugControl.tsx +++ b/packages/react/src/components/GraphDebugControl/GraphDebugControl.tsx @@ -1,7 +1,14 @@ -import { Box, Button, Flex, Select, SelectItem } from '@committed/components' +import { + Box, + Button, + Checkbox, + Flex, + Select, + SelectItem, +} from '@committed/components' import { Generator, GraphModel, PresetGraphLayout } from '@committed/graph' -import { defaultLayouts } from '../../graph' import React from 'react' +import { defaultLayouts } from '../../graph' const { addRandomNode, addRandomEdge, removeRandomNode, removeRandomEdge } = Generator @@ -44,6 +51,18 @@ export const GraphDebugControl: React.FC = ({ + + onChange( + GraphModel.applyLayout( + model, + model.getCurrentLayout().setOnChange(checked) + ) + ) + } + />