From dac19b8e1e86ac9afcd087b81b93e0d955c703c1 Mon Sep 17 00:00:00 2001 From: Mark Keller <7525285+keller-mark@users.noreply.github.com> Date: Sat, 3 Feb 2024 10:39:56 -0500 Subject: [PATCH] Different graphviz library (#57) * Different graphviz library * Changeset * Whitespace --- .changeset/cuddly-carpets-lay.md | 5 ++ .github/workflows/deploy.yml | 5 +- packages/graphviz-renderer/package.json | 2 +- packages/graphviz-renderer/src/index.js | 41 ++++++---- packages/graphviz-renderer/src/index.test.js | 78 ++++++++++++++++++++ pnpm-lock.yaml | 23 ++---- 6 files changed, 121 insertions(+), 33 deletions(-) create mode 100644 .changeset/cuddly-carpets-lay.md create mode 100644 packages/graphviz-renderer/src/index.test.js diff --git a/.changeset/cuddly-carpets-lay.md b/.changeset/cuddly-carpets-lay.md new file mode 100644 index 0000000..02fc6b5 --- /dev/null +++ b/.changeset/cuddly-carpets-lay.md @@ -0,0 +1,5 @@ +--- +"@use-coordination/graphviz-renderer": patch +--- + +Use more modern graphviz library. diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index ab90664..9e5c7fd 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -32,7 +32,10 @@ jobs: run_install: true - name: Install Playwright Browsers run: pnpm exec playwright install --with-deps - - run: pnpm run build && pnpm run build-json-schema + - run: | + pnpm run build + pnpm run build-json-schema + pnpm run bundle - run: pnpm exec playwright test - run: pnpm run changeset-status - name: Create Release Pull Request or Publish to NPM diff --git a/packages/graphviz-renderer/package.json b/packages/graphviz-renderer/package.json index a56c0ff..e13f8a9 100644 --- a/packages/graphviz-renderer/package.json +++ b/packages/graphviz-renderer/package.json @@ -27,6 +27,6 @@ "author": "", "license": "MIT", "dependencies": { - "graphviz": "^0.0.9" + "ts-graphviz": "^1.8.1" } } diff --git a/packages/graphviz-renderer/src/index.js b/packages/graphviz-renderer/src/index.js index 4af547e..1b66621 100644 --- a/packages/graphviz-renderer/src/index.js +++ b/packages/graphviz-renderer/src/index.js @@ -1,34 +1,43 @@ -import * as graphviz from 'graphviz'; +import { attribute as _, Digraph, Subgraph, Node, Edge, toDot } from 'ts-graphviz'; -const cScopeStyle = { "color": "green" }; -const cValueStyle = { "color": "red" }; -const viewStyle = { "color": "yellow" }; +const cScopeStyle = { [_.color]: "green" }; +const cValueStyle = { [_.color]: "red" }; +const viewStyle = { [_.color]: "yellow" }; function addCscopeNode(g, cType, cScope, cValue) { - const cScopeNode = g.addNode(`cType_${cType}_cScope_${cScope}`, { ...cScopeStyle, label: cScope }); - const cValueNode = g.addNode(`cType_${cType}_cScope_${cScope}_value`, { ...cValueStyle, label: cValue }); - g.addEdge(cScopeNode, cValueNode); - + const cScopeNode = new Node(`cType_${cType}_cScope_${cScope}`, { + ...cScopeStyle, + [_.label]: cScope, + }) + g.addNode(cScopeNode); + const cValueNode = new Node(`cType_${cType}_cScope_${cScope}_value`, { + ...cValueStyle, + [_.label]: JSON.stringify(cValue), + }); + g.addNode(cValueNode); + g.addEdge(new Edge([cScopeNode, cValueNode])); } function addViewNode(g, view) { - g.addNode(`view_${view}`, { ...viewStyle, label: view }); + g.addNode(new Node(`view_${view}`, { ...viewStyle, [_.label]: view })); } function addViewScopeEdge(g, view, cType, cScope) { - g.addEdge(`view_${view}`, `cType_${cType}_cScope_${cScope}`); + g.addEdge(new Edge([new Node(`view_${view}`), new Node(`cType_${cType}_cScope_${cScope}`)])); } // TODO: implement using TS export function toGraphviz(config) { - const g = graphviz.digraph("G"); - g.set("rankdir", "LR"); - + const g = new Digraph({ + [_.rankdir]: "LR", + }); // TODO: handle meta-coordination, multi-coordination, and multi-level coordination. Object.entries(config.coordinationSpace).forEach(([cType, cObj]) => { - const cTypeCluster = g.addCluster(`cluster_cType_${cType}`); - cTypeCluster.set("label", cType); + const cTypeCluster = new Subgraph(`cluster_cType_${cType}`, { + [_.label]: cType, + }); + g.addSubgraph(cTypeCluster); Object.entries(cObj).forEach(([cScope, cValue]) => { addCscopeNode(cTypeCluster, cType, cScope, cValue); @@ -43,5 +52,5 @@ export function toGraphviz(config) { }); }); - return g.to_dot(); + return toDot(g); } diff --git a/packages/graphviz-renderer/src/index.test.js b/packages/graphviz-renderer/src/index.test.js new file mode 100644 index 0000000..5b85267 --- /dev/null +++ b/packages/graphviz-renderer/src/index.test.js @@ -0,0 +1,78 @@ +import { describe, it, expect } from 'vitest'; +import { + toGraphviz +} from './index.js'; + +describe('Graphviz Rendering', () => { + describe('toGraphviz', () => { + it('works', () => { + const config = { + key: 1, + coordinationSpace: { + "barSelection": { + "A": [], + } + }, + viewCoordination: { + vegaLite: { + coordinationScopes: { + barSelection: "A", + }, + }, + d3: { + coordinationScopes: { + barSelection: "A", + }, + }, + visx: { + coordinationScopes: { + barSelection: "A", + }, + }, + plotly: { + coordinationScopes: { + barSelection: "A", + }, + }, + }, + }; + + const dot = toGraphviz(config); + expect(dot).toEqual(`digraph { + rankdir = "LR"; + "view_vegaLite" [ + color = "yellow"; + label = "vegaLite"; + ]; + "view_d3" [ + color = "yellow"; + label = "d3"; + ]; + "view_visx" [ + color = "yellow"; + label = "visx"; + ]; + "view_plotly" [ + color = "yellow"; + label = "plotly"; + ]; + subgraph "cluster_cType_barSelection" { + label = "barSelection"; + "cType_barSelection_cScope_A" [ + color = "green"; + label = "A"; + ]; + "cType_barSelection_cScope_A_value" [ + color = "red"; + label = "[]"; + ]; + "cType_barSelection_cScope_A" -> "cType_barSelection_cScope_A_value"; + } + "view_vegaLite" -> "cType_barSelection_cScope_A"; + "view_d3" -> "cType_barSelection_cScope_A"; + "view_visx" -> "cType_barSelection_cScope_A"; + "view_plotly" -> "cType_barSelection_cScope_A"; +}`); + }); + }); +}); \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 30d5865..4bb3d58 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -278,9 +278,9 @@ importers: packages/graphviz-renderer: dependencies: - graphviz: - specifier: ^0.0.9 - version: 0.0.9 + ts-graphviz: + specifier: ^1.8.1 + version: 1.8.1 packages/json-schema: dependencies: @@ -10464,13 +10464,6 @@ packages: resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} dev: true - /graphviz@0.0.9: - resolution: {integrity: sha512-SmoY2pOtcikmMCqCSy2NO1YsRfu9OO0wpTlOYW++giGjfX1a6gax/m1Fo8IdUd0/3H15cTOfR1SMKwohj4LKsg==} - engines: {node: '>=0.6.8'} - dependencies: - temp: 0.4.0 - dev: false - /gray-matter@4.0.3: resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} engines: {node: '>=6.0'} @@ -15666,11 +15659,6 @@ packages: engines: {node: '>=6'} dev: false - /temp@0.4.0: - resolution: {integrity: sha512-IsFisGgDKk7qzK9erMIkQe/XwiSUdac7z3wYOsjcLkhPBy3k1SlvLoIh2dAHIlEpgA971CgguMrx9z8fFg7tSA==} - engines: {'0': node >=0.4.0} - dev: false - /term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} @@ -15860,6 +15848,11 @@ packages: /trough@1.0.5: resolution: {integrity: sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==} + /ts-graphviz@1.8.1: + resolution: {integrity: sha512-54/fe5iu0Jb6X0pmDmzsA2UHLfyHjUEUwfHtZcEOR0fZ6Myf+dFoO6eNsyL8CBDMJ9u7WWEewduVaiaXlvjSVw==} + engines: {node: '>=14.16'} + dev: false + /tsconfig-paths@3.14.2: resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} dependencies: