@dxos/plugin-explorer 0.6.8-main.046e6cf
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +8 -0
- package/README.md +3 -0
- package/dist/lib/browser/ExplorerArticle-IPAJQMAX.mjs +27 -0
- package/dist/lib/browser/ExplorerArticle-IPAJQMAX.mjs.map +7 -0
- package/dist/lib/browser/ExplorerMain-3KFXOEYO.mjs +33 -0
- package/dist/lib/browser/ExplorerMain-3KFXOEYO.mjs.map +7 -0
- package/dist/lib/browser/chunk-7YEM64IQ.mjs +473 -0
- package/dist/lib/browser/chunk-7YEM64IQ.mjs.map +7 -0
- package/dist/lib/browser/chunk-JIDPF2GF.mjs +27 -0
- package/dist/lib/browser/chunk-JIDPF2GF.mjs.map +7 -0
- package/dist/lib/browser/chunk-TL6ADY3P.mjs +21 -0
- package/dist/lib/browser/chunk-TL6ADY3P.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +38151 -0
- package/dist/lib/browser/index.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -0
- package/dist/lib/browser/meta.mjs +9 -0
- package/dist/lib/browser/meta.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +10 -0
- package/dist/lib/browser/types/index.mjs.map +7 -0
- package/dist/lib/node/ExplorerArticle-PYOGBY3Z.cjs +53 -0
- package/dist/lib/node/ExplorerArticle-PYOGBY3Z.cjs.map +7 -0
- package/dist/lib/node/ExplorerMain-HGCLO5O4.cjs +59 -0
- package/dist/lib/node/ExplorerMain-HGCLO5O4.cjs.map +7 -0
- package/dist/lib/node/chunk-2GOPBQBC.cjs +494 -0
- package/dist/lib/node/chunk-2GOPBQBC.cjs.map +7 -0
- package/dist/lib/node/chunk-HYXFS3AG.cjs +45 -0
- package/dist/lib/node/chunk-HYXFS3AG.cjs.map +7 -0
- package/dist/lib/node/chunk-UJZYAOD2.cjs +54 -0
- package/dist/lib/node/chunk-UJZYAOD2.cjs.map +7 -0
- package/dist/lib/node/index.cjs +38158 -0
- package/dist/lib/node/index.cjs.map +7 -0
- package/dist/lib/node/meta.cjs +30 -0
- package/dist/lib/node/meta.cjs.map +7 -0
- package/dist/lib/node/meta.json +1 -0
- package/dist/lib/node/types/index.cjs +32 -0
- package/dist/lib/node/types/index.cjs.map +7 -0
- package/dist/types/src/ExplorerPlugin.d.ts +4 -0
- package/dist/types/src/ExplorerPlugin.d.ts.map +1 -0
- package/dist/types/src/components/Chart/Chart.d.ts +10 -0
- package/dist/types/src/components/Chart/Chart.d.ts.map +1 -0
- package/dist/types/src/components/Chart/Chart.stories.d.ts +11 -0
- package/dist/types/src/components/Chart/Chart.stories.d.ts.map +1 -0
- package/dist/types/src/components/Chart/index.d.ts +2 -0
- package/dist/types/src/components/Chart/index.d.ts.map +1 -0
- package/dist/types/src/components/ExplorerArticle.d.ts +7 -0
- package/dist/types/src/components/ExplorerArticle.d.ts.map +1 -0
- package/dist/types/src/components/ExplorerMain.d.ts +7 -0
- package/dist/types/src/components/ExplorerMain.d.ts.map +1 -0
- package/dist/types/src/components/Globe/Globe.d.ts +12 -0
- package/dist/types/src/components/Globe/Globe.d.ts.map +1 -0
- package/dist/types/src/components/Globe/Globe.stories.d.ts +12 -0
- package/dist/types/src/components/Globe/Globe.stories.d.ts.map +1 -0
- package/dist/types/src/components/Globe/index.d.ts +2 -0
- package/dist/types/src/components/Globe/index.d.ts.map +1 -0
- package/dist/types/src/components/Graph/Graph.d.ts +8 -0
- package/dist/types/src/components/Graph/Graph.d.ts.map +1 -0
- package/dist/types/src/components/Graph/Graph.stories.d.ts +14 -0
- package/dist/types/src/components/Graph/Graph.stories.d.ts.map +1 -0
- package/dist/types/src/components/Graph/graph-model.d.ts +33 -0
- package/dist/types/src/components/Graph/graph-model.d.ts.map +1 -0
- package/dist/types/src/components/Graph/index.d.ts +3 -0
- package/dist/types/src/components/Graph/index.d.ts.map +1 -0
- package/dist/types/src/components/Tree/Tree.d.ts +27 -0
- package/dist/types/src/components/Tree/Tree.d.ts.map +1 -0
- package/dist/types/src/components/Tree/Tree.stories.d.ts +29 -0
- package/dist/types/src/components/Tree/Tree.stories.d.ts.map +1 -0
- package/dist/types/src/components/Tree/index.d.ts +2 -0
- package/dist/types/src/components/Tree/index.d.ts.map +1 -0
- package/dist/types/src/components/Tree/layout/HierarchicalEdgeBundling.d.ts +5 -0
- package/dist/types/src/components/Tree/layout/HierarchicalEdgeBundling.d.ts.map +1 -0
- package/dist/types/src/components/Tree/layout/RadialTree.d.ts +4 -0
- package/dist/types/src/components/Tree/layout/RadialTree.d.ts.map +1 -0
- package/dist/types/src/components/Tree/layout/TidyTree.d.ts +4 -0
- package/dist/types/src/components/Tree/layout/TidyTree.d.ts.map +1 -0
- package/dist/types/src/components/Tree/layout/index.d.ts +5 -0
- package/dist/types/src/components/Tree/layout/index.d.ts.map +1 -0
- package/dist/types/src/components/Tree/types.d.ts +8 -0
- package/dist/types/src/components/Tree/types.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +12 -0
- package/dist/types/src/components/index.d.ts.map +1 -0
- package/dist/types/src/components/plot.d.ts +12 -0
- package/dist/types/src/components/plot.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +5 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/meta.d.ts +15 -0
- package/dist/types/src/meta.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +12 -0
- package/dist/types/src/translations.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +3 -0
- package/dist/types/src/types/index.d.ts.map +1 -0
- package/dist/types/src/types/types.d.ts +7 -0
- package/dist/types/src/types/types.d.ts.map +1 -0
- package/dist/types/src/types/view.d.ts +14 -0
- package/dist/types/src/types/view.d.ts.map +1 -0
- package/package.json +98 -0
- package/src/ExplorerPlugin.tsx +103 -0
- package/src/components/Chart/Chart.stories.tsx +46 -0
- package/src/components/Chart/Chart.tsx +54 -0
- package/src/components/Chart/index.ts +5 -0
- package/src/components/ExplorerArticle.tsx +28 -0
- package/src/components/ExplorerMain.tsx +34 -0
- package/src/components/Globe/Globe.stories.tsx +115 -0
- package/src/components/Globe/Globe.tsx +65 -0
- package/src/components/Globe/index.ts +5 -0
- package/src/components/Graph/Graph.stories.tsx +59 -0
- package/src/components/Graph/Graph.tsx +151 -0
- package/src/components/Graph/graph-model.ts +146 -0
- package/src/components/Graph/index.ts +7 -0
- package/src/components/Tree/Tree.stories.tsx +97 -0
- package/src/components/Tree/Tree.tsx +109 -0
- package/src/components/Tree/index.ts +5 -0
- package/src/components/Tree/layout/HierarchicalEdgeBundling.ts +164 -0
- package/src/components/Tree/layout/RadialTree.ts +96 -0
- package/src/components/Tree/layout/TidyTree.ts +102 -0
- package/src/components/Tree/layout/index.ts +9 -0
- package/src/components/Tree/types.ts +39 -0
- package/src/components/index.ts +14 -0
- package/src/components/plot.ts +15 -0
- package/src/index.ts +12 -0
- package/src/meta.tsx +19 -0
- package/src/translations.ts +18 -0
- package/src/types/index.ts +6 -0
- package/src/types/types.ts +27 -0
- package/src/types/view.ts +11 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
Copyright (c) 2022 DXOS
|
|
3
|
+
|
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
5
|
+
|
|
6
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
7
|
+
|
|
8
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Graph
|
|
3
|
+
} from "./chunk-7YEM64IQ.mjs";
|
|
4
|
+
|
|
5
|
+
// packages/plugins/experimental/plugin-explorer/src/components/ExplorerArticle.tsx
|
|
6
|
+
import React from "react";
|
|
7
|
+
import { useGlobalSearch } from "@dxos/plugin-search";
|
|
8
|
+
import { getSpace } from "@dxos/react-client/echo";
|
|
9
|
+
var ExplorerArticle = ({ view }) => {
|
|
10
|
+
const space = getSpace(view);
|
|
11
|
+
const { match } = useGlobalSearch();
|
|
12
|
+
if (!space) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
return /* @__PURE__ */ React.createElement("div", {
|
|
16
|
+
role: "none",
|
|
17
|
+
className: "row-span-2 overflow-auto"
|
|
18
|
+
}, /* @__PURE__ */ React.createElement(Graph, {
|
|
19
|
+
space,
|
|
20
|
+
match
|
|
21
|
+
}));
|
|
22
|
+
};
|
|
23
|
+
var ExplorerArticle_default = ExplorerArticle;
|
|
24
|
+
export {
|
|
25
|
+
ExplorerArticle_default as default
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=ExplorerArticle-IPAJQMAX.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/components/ExplorerArticle.tsx"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport React from 'react';\n\nimport { useGlobalSearch } from '@dxos/plugin-search';\nimport { getSpace } from '@dxos/react-client/echo';\n\nimport { Graph } from './Graph';\nimport { type ViewType } from '../types';\n\nconst ExplorerArticle = ({ view }: { view: ViewType }) => {\n const space = getSpace(view);\n const { match } = useGlobalSearch();\n\n if (!space) {\n return null;\n }\n\n return (\n <div role='none' className='row-span-2 overflow-auto'>\n <Graph space={space} match={match} />\n </div>\n );\n};\n\nexport default ExplorerArticle;\n"],
|
|
5
|
+
"mappings": ";;;;;AAIA,OAAOA,WAAW;AAElB,SAASC,uBAAuB;AAChC,SAASC,gBAAgB;AAKzB,IAAMC,kBAAkB,CAAC,EAAEC,KAAI,MAAsB;AACnD,QAAMC,QAAQC,SAASF,IAAAA;AACvB,QAAM,EAAEG,MAAK,IAAKC,gBAAAA;AAElB,MAAI,CAACH,OAAO;AACV,WAAO;EACT;AAEA,SACE,sBAAA,cAACI,OAAAA;IAAIC,MAAK;IAAOC,WAAU;KACzB,sBAAA,cAACC,OAAAA;IAAMP;IAAcE;;AAG3B;AAEA,IAAA,0BAAeJ;",
|
|
6
|
+
"names": ["React", "useGlobalSearch", "getSpace", "ExplorerArticle", "view", "space", "getSpace", "match", "useGlobalSearch", "div", "role", "className", "Graph"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Graph
|
|
3
|
+
} from "./chunk-7YEM64IQ.mjs";
|
|
4
|
+
|
|
5
|
+
// packages/plugins/experimental/plugin-explorer/src/components/ExplorerMain.tsx
|
|
6
|
+
import React from "react";
|
|
7
|
+
import { useGlobalSearch } from "@dxos/plugin-search";
|
|
8
|
+
import { getSpace } from "@dxos/react-client/echo";
|
|
9
|
+
import { Main } from "@dxos/react-ui";
|
|
10
|
+
import { baseSurface, topbarBlockPaddingStart, fixedInsetFlexLayout, bottombarBlockPaddingEnd } from "@dxos/react-ui-theme";
|
|
11
|
+
var ExplorerMain = ({ view }) => {
|
|
12
|
+
const space = getSpace(view);
|
|
13
|
+
const { match } = useGlobalSearch();
|
|
14
|
+
if (!space) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
return /* @__PURE__ */ React.createElement(Main.Content, {
|
|
18
|
+
classNames: [
|
|
19
|
+
baseSurface,
|
|
20
|
+
fixedInsetFlexLayout,
|
|
21
|
+
topbarBlockPaddingStart,
|
|
22
|
+
bottombarBlockPaddingEnd
|
|
23
|
+
]
|
|
24
|
+
}, /* @__PURE__ */ React.createElement(Graph, {
|
|
25
|
+
space,
|
|
26
|
+
match
|
|
27
|
+
}));
|
|
28
|
+
};
|
|
29
|
+
var ExplorerMain_default = ExplorerMain;
|
|
30
|
+
export {
|
|
31
|
+
ExplorerMain_default as default
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=ExplorerMain-3KFXOEYO.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/components/ExplorerMain.tsx"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport React from 'react';\n\nimport { useGlobalSearch } from '@dxos/plugin-search';\nimport { getSpace } from '@dxos/react-client/echo';\nimport { Main } from '@dxos/react-ui';\nimport {\n baseSurface,\n topbarBlockPaddingStart,\n fixedInsetFlexLayout,\n bottombarBlockPaddingEnd,\n} from '@dxos/react-ui-theme';\n\nimport { Graph } from './Graph';\nimport { type ViewType } from '../types';\n\nconst ExplorerMain = ({ view }: { view: ViewType }) => {\n const space = getSpace(view);\n const { match } = useGlobalSearch();\n if (!space) {\n return null;\n }\n\n return (\n <Main.Content classNames={[baseSurface, fixedInsetFlexLayout, topbarBlockPaddingStart, bottombarBlockPaddingEnd]}>\n <Graph space={space} match={match} />\n </Main.Content>\n );\n};\n\nexport default ExplorerMain;\n"],
|
|
5
|
+
"mappings": ";;;;;AAIA,OAAOA,WAAW;AAElB,SAASC,uBAAuB;AAChC,SAASC,gBAAgB;AACzB,SAASC,YAAY;AACrB,SACEC,aACAC,yBACAC,sBACAC,gCACK;AAKP,IAAMC,eAAe,CAAC,EAAEC,KAAI,MAAsB;AAChD,QAAMC,QAAQC,SAASF,IAAAA;AACvB,QAAM,EAAEG,MAAK,IAAKC,gBAAAA;AAClB,MAAI,CAACH,OAAO;AACV,WAAO;EACT;AAEA,SACE,sBAAA,cAACI,KAAKC,SAAO;IAACC,YAAY;MAACC;MAAaC;MAAsBC;MAAyBC;;KACrF,sBAAA,cAACC,OAAAA;IAAMX;IAAcE;;AAG3B;AAEA,IAAA,uBAAeJ;",
|
|
6
|
+
"names": ["React", "useGlobalSearch", "getSpace", "Main", "baseSurface", "topbarBlockPaddingStart", "fixedInsetFlexLayout", "bottombarBlockPaddingEnd", "ExplorerMain", "view", "space", "getSpace", "match", "useGlobalSearch", "Main", "Content", "classNames", "baseSurface", "fixedInsetFlexLayout", "topbarBlockPaddingStart", "bottombarBlockPaddingEnd", "Graph"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
// packages/plugins/experimental/plugin-explorer/src/components/Graph/graph-model.ts
|
|
2
|
+
import { AST, DynamicSchema, getSchema, getType, ReferenceAnnotationId, SchemaValidator, StoredSchema } from "@dxos/echo-schema";
|
|
3
|
+
import { GraphModel } from "@dxos/gem-spore";
|
|
4
|
+
import { log } from "@dxos/log";
|
|
5
|
+
import { CollectionType } from "@dxos/plugin-space/types";
|
|
6
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-explorer/src/components/Graph/graph-model.ts";
|
|
7
|
+
var SpaceGraphModel = class extends GraphModel {
|
|
8
|
+
constructor(_options = {}) {
|
|
9
|
+
super();
|
|
10
|
+
this._options = _options;
|
|
11
|
+
this._graph = {
|
|
12
|
+
nodes: [],
|
|
13
|
+
links: []
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
get graph() {
|
|
17
|
+
return this._graph;
|
|
18
|
+
}
|
|
19
|
+
get objects() {
|
|
20
|
+
return this._objects ?? [];
|
|
21
|
+
}
|
|
22
|
+
open(space, objectId) {
|
|
23
|
+
if (!this._subscription) {
|
|
24
|
+
const query = space.db.query((object) => !(object instanceof CollectionType));
|
|
25
|
+
this._subscription = query.subscribe(({ objects }) => {
|
|
26
|
+
this._objects = objects;
|
|
27
|
+
this._graph.nodes = objects.map((object) => {
|
|
28
|
+
if (object instanceof StoredSchema) {
|
|
29
|
+
const effectSchema = space.db.schema.getSchemaById(object.id);
|
|
30
|
+
return {
|
|
31
|
+
type: "schema",
|
|
32
|
+
id: object.id,
|
|
33
|
+
schema: effectSchema.schema
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
type: "echo-object",
|
|
38
|
+
id: object.id,
|
|
39
|
+
object
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
this._graph.links = objects.reduce((links, object) => {
|
|
43
|
+
const objectSchema = getSchema(object);
|
|
44
|
+
const typename = getType(object)?.objectId;
|
|
45
|
+
if (objectSchema == null || typename == null) {
|
|
46
|
+
log.info("no schema for object:", {
|
|
47
|
+
id: object.id.slice(0, 8)
|
|
48
|
+
}, {
|
|
49
|
+
F: __dxlog_file,
|
|
50
|
+
L: 81,
|
|
51
|
+
S: this,
|
|
52
|
+
C: (f, a) => f(...a)
|
|
53
|
+
});
|
|
54
|
+
return links;
|
|
55
|
+
}
|
|
56
|
+
if (!(objectSchema instanceof DynamicSchema)) {
|
|
57
|
+
const idx = objects.findIndex((obj) => obj.id === typename);
|
|
58
|
+
if (idx === -1) {
|
|
59
|
+
this._graph.nodes.push({
|
|
60
|
+
id: typename,
|
|
61
|
+
type: "schema",
|
|
62
|
+
schema: objectSchema
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (this._options.schema) {
|
|
67
|
+
links.push({
|
|
68
|
+
id: `${object.id}-${typename}`,
|
|
69
|
+
source: object.id,
|
|
70
|
+
target: typename
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
AST.getPropertySignatures(objectSchema.ast).forEach((prop) => {
|
|
74
|
+
if (!SchemaValidator.hasTypeAnnotation(objectSchema, prop.name.toString(), ReferenceAnnotationId)) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const value = object[String(prop.name)];
|
|
78
|
+
if (value) {
|
|
79
|
+
const refs = Array.isArray(value) ? value : [
|
|
80
|
+
value
|
|
81
|
+
];
|
|
82
|
+
for (const ref of refs) {
|
|
83
|
+
if (objects.findIndex((obj) => obj.id === ref.id) !== -1) {
|
|
84
|
+
links.push({
|
|
85
|
+
id: `${object.id}-${String(prop.name)}-${ref.id}`,
|
|
86
|
+
source: object.id,
|
|
87
|
+
target: ref.id
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
return links;
|
|
94
|
+
}, []);
|
|
95
|
+
this.triggerUpdate();
|
|
96
|
+
}, {
|
|
97
|
+
fire: true
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
this.setSelected(objectId);
|
|
101
|
+
return this;
|
|
102
|
+
}
|
|
103
|
+
close() {
|
|
104
|
+
if (this._subscription) {
|
|
105
|
+
this._subscription();
|
|
106
|
+
this._subscription = void 0;
|
|
107
|
+
}
|
|
108
|
+
return this;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// packages/plugins/experimental/plugin-explorer/src/components/Tree/Tree.tsx
|
|
113
|
+
import React2, { useEffect as useEffect2, useMemo as useMemo2, useState as useState2 } from "react";
|
|
114
|
+
import { useResizeDetector } from "react-resize-detector";
|
|
115
|
+
import { createSvgContext as createSvgContext2, SVG as SVG2, SVGContextProvider as SVGContextProvider2 } from "@dxos/gem-core";
|
|
116
|
+
|
|
117
|
+
// packages/plugins/experimental/plugin-explorer/src/components/Tree/layout/HierarchicalEdgeBundling.ts
|
|
118
|
+
import * as d3 from "d3";
|
|
119
|
+
var HierarchicalEdgeBundling = (s, data, options) => {
|
|
120
|
+
const svg = d3.select(s);
|
|
121
|
+
svg.selectAll("*").remove();
|
|
122
|
+
const { radius = 600, padding = 100, slots: slots2 } = options;
|
|
123
|
+
const root = d3.hierarchy(flatten(data));
|
|
124
|
+
const tree3 = d3.cluster().size([
|
|
125
|
+
2 * Math.PI,
|
|
126
|
+
radius - padding
|
|
127
|
+
]);
|
|
128
|
+
const layout = tree3(addLinks(root));
|
|
129
|
+
const node = svg.append("g").selectAll().data(layout.leaves()).join("g").attr("transform", (d) => `rotate(${d.x * (180 / Math.PI) - 90}) translate(${d.y},0)`).append("text").attr("class", slots2?.text ?? "").attr("dy", "0.31em").attr("x", (d) => d.x < Math.PI ? 6 : -6).attr("text-anchor", (d) => d.x < Math.PI ? "start" : "end").attr("transform", (d) => d.x >= Math.PI ? "rotate(180)" : null).call((text) => text.text((d) => d.data.id.slice(0, 8)));
|
|
130
|
+
const line = d3.lineRadial().curve(d3.curveBundle.beta(0.85)).radius((d) => d.y).angle((d) => d.x);
|
|
131
|
+
const links = svg.append("g").selectAll().data(layout.leaves().flatMap((leaf) => leaf.outgoing)).join("path").style("mix-blend-mode", "multiply").attr("class", slots2?.path ?? "").attr("d", ([i, o]) => {
|
|
132
|
+
return line(i.path(o));
|
|
133
|
+
}).each(function(d) {
|
|
134
|
+
d.path = this;
|
|
135
|
+
});
|
|
136
|
+
};
|
|
137
|
+
var addLinks = (root) => {
|
|
138
|
+
const nodes = new Map(root.descendants().map((d) => [
|
|
139
|
+
d.data.id,
|
|
140
|
+
d
|
|
141
|
+
]));
|
|
142
|
+
const parents = root.descendants().reduce((map, d) => {
|
|
143
|
+
if (d.children?.length) {
|
|
144
|
+
map.set(d.data.id, d);
|
|
145
|
+
}
|
|
146
|
+
return map;
|
|
147
|
+
}, /* @__PURE__ */ new Map());
|
|
148
|
+
for (const d of root.leaves()) {
|
|
149
|
+
const parent = parents.get(d.data.id);
|
|
150
|
+
if (parent) {
|
|
151
|
+
d.outgoing = parent.data.children?.slice(1).map((child) => {
|
|
152
|
+
return [
|
|
153
|
+
d,
|
|
154
|
+
nodes.get(child.id)
|
|
155
|
+
];
|
|
156
|
+
}) ?? [];
|
|
157
|
+
} else {
|
|
158
|
+
d.outgoing = [];
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return root;
|
|
162
|
+
};
|
|
163
|
+
var flatten = (node) => {
|
|
164
|
+
const clone = {
|
|
165
|
+
id: node.id
|
|
166
|
+
};
|
|
167
|
+
if (node.children?.length) {
|
|
168
|
+
const children = node.children.map((child) => flatten(child));
|
|
169
|
+
clone.children = [
|
|
170
|
+
{
|
|
171
|
+
id: node.id
|
|
172
|
+
},
|
|
173
|
+
...children
|
|
174
|
+
];
|
|
175
|
+
}
|
|
176
|
+
return clone;
|
|
177
|
+
};
|
|
178
|
+
var HierarchicalEdgeBundling_default = HierarchicalEdgeBundling;
|
|
179
|
+
|
|
180
|
+
// packages/plugins/experimental/plugin-explorer/src/components/Tree/layout/RadialTree.ts
|
|
181
|
+
import * as d32 from "d3";
|
|
182
|
+
var RadialTree = (s, data, options) => {
|
|
183
|
+
const svg = d32.select(s);
|
|
184
|
+
svg.selectAll("*").remove();
|
|
185
|
+
const { label, radius = 400, r = 4, slots: slots2 } = options;
|
|
186
|
+
const arc = 2 * Math.PI;
|
|
187
|
+
const root = d32.hierarchy(data);
|
|
188
|
+
const descendants = root.descendants();
|
|
189
|
+
const getLabel = label === null ? null : descendants.map((d) => label(d.data));
|
|
190
|
+
const layout = d32.tree().size([
|
|
191
|
+
arc,
|
|
192
|
+
radius
|
|
193
|
+
]).separation((a, b) => (a.parent === b.parent ? 1 : 2) / a.depth);
|
|
194
|
+
layout(root);
|
|
195
|
+
svg.append("g").selectAll("path").data(root.links()).join("path").attr("class", slots2?.path ?? "").attr("d", d32.linkRadial().angle((d) => d.x + Math.PI / 2).radius((d) => d.y));
|
|
196
|
+
const node = svg.append("g").selectAll("a").data(root.descendants()).join("a").attr("transform", (d) => `rotate(${d.x * 180 / Math.PI}) translate(${d.y},0)`);
|
|
197
|
+
node.append("circle").attr("class", slots2?.node ?? "").attr("r", r);
|
|
198
|
+
if (getLabel) {
|
|
199
|
+
node.append("text").attr("transform", (d) => `rotate(${d.x >= Math.PI ? 180 : 0})`).attr("dy", "0.32em").attr("x", (d) => d.x < Math.PI === !d.children ? 6 : -6).attr("text-anchor", (d) => d.x < Math.PI === !d.children ? "start" : "end").attr("class", slots2?.text ?? "").text((d, i) => getLabel[i]);
|
|
200
|
+
}
|
|
201
|
+
return svg.node();
|
|
202
|
+
};
|
|
203
|
+
var RadialTree_default = RadialTree;
|
|
204
|
+
|
|
205
|
+
// packages/plugins/experimental/plugin-explorer/src/components/Tree/layout/TidyTree.ts
|
|
206
|
+
import * as d33 from "d3";
|
|
207
|
+
var TidyTree = (s, data, options) => {
|
|
208
|
+
const svg = d33.select(s);
|
|
209
|
+
svg.selectAll("*").remove();
|
|
210
|
+
const { label, width, height, r = 4, padding = 4, margin = 60, slots: slots2 } = options;
|
|
211
|
+
const root = d33.hierarchy(data);
|
|
212
|
+
const descendants = root.descendants();
|
|
213
|
+
const getLabel = label == null ? null : descendants.map((d) => label(d.data));
|
|
214
|
+
const dx = 16;
|
|
215
|
+
const dy = width / (root.height + padding);
|
|
216
|
+
const layout = d33.tree().nodeSize([
|
|
217
|
+
dx,
|
|
218
|
+
dy
|
|
219
|
+
]);
|
|
220
|
+
layout(root);
|
|
221
|
+
let x0 = Infinity;
|
|
222
|
+
let x1 = -x0;
|
|
223
|
+
let y0 = Infinity;
|
|
224
|
+
let y1 = -y0;
|
|
225
|
+
root.each((d) => {
|
|
226
|
+
if (d.x > x1) {
|
|
227
|
+
x1 = d.x;
|
|
228
|
+
}
|
|
229
|
+
if (d.x < x0) {
|
|
230
|
+
x0 = d.x;
|
|
231
|
+
}
|
|
232
|
+
if (d.y > y1) {
|
|
233
|
+
y1 = d.y;
|
|
234
|
+
}
|
|
235
|
+
if (d.y < y0) {
|
|
236
|
+
y0 = d.y;
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
const sx = Math.min(2, Math.max(1, (height - margin * 2) / (x1 - x0)));
|
|
240
|
+
const oy = -(width - (y1 - y0)) / 2;
|
|
241
|
+
svg.append("g").selectAll("path").data(root.links()).join("path").attr("class", slots2?.path ?? "").attr("d", d33.link(d33.curveBumpX).x((d) => d.y + oy).y((d) => d.x * sx));
|
|
242
|
+
const node = svg.append("g").selectAll("a").data(root.descendants()).join("a").attr("transform", (d) => `translate(${d.y + oy},${d.x * sx})`);
|
|
243
|
+
node.append("circle").attr("class", slots2?.node ?? "").attr("r", r);
|
|
244
|
+
if (getLabel) {
|
|
245
|
+
node.append("text").attr("dy", "0.32em").attr("x", (d) => d.children ? -6 : 6).attr("text-anchor", (d) => d.children ? "end" : "start").attr("class", slots2?.text ?? "").text((d, i) => getLabel[i]);
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
var TidyTree_default = TidyTree;
|
|
249
|
+
|
|
250
|
+
// packages/plugins/experimental/plugin-explorer/src/components/Tree/types.ts
|
|
251
|
+
var mapGraphToTreeData = (model, maxDepth = 8) => {
|
|
252
|
+
const mapNode = (node, depth = 0) => {
|
|
253
|
+
const treeNode = {
|
|
254
|
+
id: model.idAccessor(node),
|
|
255
|
+
label: model.idAccessor(node).slice(0, 8)
|
|
256
|
+
};
|
|
257
|
+
const links = model.graph.links.filter((link2) => link2.source === treeNode.id);
|
|
258
|
+
if (depth < maxDepth) {
|
|
259
|
+
treeNode.children = links.map((link2) => mapNode(model.graph.nodes.find((node2) => model.idAccessor(node2) === link2.target), depth + 1));
|
|
260
|
+
}
|
|
261
|
+
return treeNode;
|
|
262
|
+
};
|
|
263
|
+
let data;
|
|
264
|
+
if (model.selected) {
|
|
265
|
+
const node = model.graph.nodes.find((node2) => model.idAccessor(node2) === model.selected);
|
|
266
|
+
if (node) {
|
|
267
|
+
data = mapNode(node);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return data;
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
// packages/plugins/experimental/plugin-explorer/src/components/Graph/Graph.tsx
|
|
274
|
+
import React, { useEffect, useMemo, useRef, useState } from "react";
|
|
275
|
+
import { getType as getType2 } from "@dxos/echo-schema";
|
|
276
|
+
import { createSvgContext, darkGridStyles, defaultGridStyles, Grid, SVG, SVGContextProvider, Zoom } from "@dxos/gem-core";
|
|
277
|
+
import { Graph as GraphComponent, GraphForceProjector, Markers } from "@dxos/gem-spore";
|
|
278
|
+
import { filterObjectsSync } from "@dxos/plugin-search";
|
|
279
|
+
import { useThemeContext } from "@dxos/react-ui";
|
|
280
|
+
import { mx } from "@dxos/react-ui-theme";
|
|
281
|
+
var slots = {};
|
|
282
|
+
var colors = [
|
|
283
|
+
"[&>circle]:!fill-black-300 [&>circle]:!stroke-black-600",
|
|
284
|
+
"[&>circle]:!fill-slate-300 [&>circle]:!stroke-slate-600",
|
|
285
|
+
"[&>circle]:!fill-green-300 [&>circle]:!stroke-green-600",
|
|
286
|
+
"[&>circle]:!fill-sky-300 [&>circle]:!stroke-sky-600",
|
|
287
|
+
"[&>circle]:!fill-cyan-300 [&>circle]:!stroke-cyan-600",
|
|
288
|
+
"[&>circle]:!fill-rose-300 [&>circle]:!stroke-rose-600",
|
|
289
|
+
"[&>circle]:!fill-purple-300 [&>circle]:!stroke-purple-600",
|
|
290
|
+
"[&>circle]:!fill-orange-300 [&>circle]:!stroke-orange-600",
|
|
291
|
+
"[&>circle]:!fill-teal-300 [&>circle]:!stroke-teal-600",
|
|
292
|
+
"[&>circle]:!fill-indigo-300 [&>circle]:!stroke-indigo-600"
|
|
293
|
+
];
|
|
294
|
+
var Graph = ({ space, match }) => {
|
|
295
|
+
const model = useMemo(() => space ? new SpaceGraphModel({
|
|
296
|
+
schema: true
|
|
297
|
+
}).open(space) : void 0, [
|
|
298
|
+
space
|
|
299
|
+
]);
|
|
300
|
+
const [selected, setSelected] = useState();
|
|
301
|
+
const { themeMode } = useThemeContext();
|
|
302
|
+
const context = createSvgContext();
|
|
303
|
+
const projector = useMemo(() => new GraphForceProjector(context, {
|
|
304
|
+
forces: {
|
|
305
|
+
manyBody: {
|
|
306
|
+
strength: -100
|
|
307
|
+
},
|
|
308
|
+
link: {
|
|
309
|
+
distance: 180
|
|
310
|
+
},
|
|
311
|
+
radial: {
|
|
312
|
+
radius: 200,
|
|
313
|
+
strength: 0.05
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
attributes: {
|
|
317
|
+
radius: (node) => node.data?.type === "schema" ? 24 : 12
|
|
318
|
+
}
|
|
319
|
+
}), []);
|
|
320
|
+
const filteredRef = useRef();
|
|
321
|
+
filteredRef.current = filterObjectsSync(model?.objects ?? [], match);
|
|
322
|
+
useEffect(() => {
|
|
323
|
+
void projector.start();
|
|
324
|
+
}, [
|
|
325
|
+
match
|
|
326
|
+
]);
|
|
327
|
+
const [colorMap] = useState(/* @__PURE__ */ new Map());
|
|
328
|
+
if (!model) {
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
if (selected) {
|
|
332
|
+
return /* @__PURE__ */ React.createElement(Tree, {
|
|
333
|
+
space,
|
|
334
|
+
selected,
|
|
335
|
+
variant: "tidy",
|
|
336
|
+
onNodeClick: () => setSelected(void 0)
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
return /* @__PURE__ */ React.createElement(SVGContextProvider, {
|
|
340
|
+
context
|
|
341
|
+
}, /* @__PURE__ */ React.createElement(SVG, {
|
|
342
|
+
className: slots?.root?.className
|
|
343
|
+
}, /* @__PURE__ */ React.createElement(Markers, {
|
|
344
|
+
arrowSize: 6
|
|
345
|
+
}), /* @__PURE__ */ React.createElement(Grid, {
|
|
346
|
+
className: slots?.grid?.className ?? themeMode === "dark" ? darkGridStyles : defaultGridStyles
|
|
347
|
+
}), /* @__PURE__ */ React.createElement(Zoom, {
|
|
348
|
+
extent: [
|
|
349
|
+
1 / 2,
|
|
350
|
+
4
|
|
351
|
+
]
|
|
352
|
+
}, /* @__PURE__ */ React.createElement(GraphComponent, {
|
|
353
|
+
model,
|
|
354
|
+
projector,
|
|
355
|
+
drag: true,
|
|
356
|
+
arrows: true,
|
|
357
|
+
onSelect: (node) => setSelected(node?.data?.id),
|
|
358
|
+
labels: {
|
|
359
|
+
text: (node) => {
|
|
360
|
+
if (filteredRef.current?.length && !filteredRef.current.some((object) => object.id === node.data?.id)) {
|
|
361
|
+
return void 0;
|
|
362
|
+
}
|
|
363
|
+
return node.data?.label ?? node.data?.title ?? node.data?.name ?? node.data?.id.slice(0, 8);
|
|
364
|
+
}
|
|
365
|
+
},
|
|
366
|
+
attributes: {
|
|
367
|
+
node: (node) => {
|
|
368
|
+
let className;
|
|
369
|
+
if (node.data) {
|
|
370
|
+
const typename = getType2(node.data)?.objectId;
|
|
371
|
+
if (typename) {
|
|
372
|
+
className = colorMap.get(typename);
|
|
373
|
+
if (!className) {
|
|
374
|
+
className = colors[colorMap.size % colors.length];
|
|
375
|
+
colorMap.set(typename, className);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
const selected2 = filteredRef.current?.some((object) => object.id === node.data?.id);
|
|
380
|
+
return {
|
|
381
|
+
class: mx(filteredRef.current?.length ? selected2 ? [
|
|
382
|
+
className
|
|
383
|
+
] : "[&>text]:!fill-neutral-300" : [
|
|
384
|
+
"[&>text]:!fill-neutral-700",
|
|
385
|
+
className
|
|
386
|
+
])
|
|
387
|
+
};
|
|
388
|
+
},
|
|
389
|
+
link: () => ({
|
|
390
|
+
class: "[&>path]:!stroke-neutral-300"
|
|
391
|
+
})
|
|
392
|
+
}
|
|
393
|
+
}))));
|
|
394
|
+
};
|
|
395
|
+
|
|
396
|
+
// packages/plugins/experimental/plugin-explorer/src/components/Tree/Tree.tsx
|
|
397
|
+
var defaultTreeLayoutSlots = {
|
|
398
|
+
node: "fill-blue-600",
|
|
399
|
+
path: "fill-none stroke-blue-400 stroke-[0.5px]",
|
|
400
|
+
text: "stroke-[0.5px] stroke-neutral-700 text-xs"
|
|
401
|
+
};
|
|
402
|
+
var renderers = /* @__PURE__ */ new Map([
|
|
403
|
+
[
|
|
404
|
+
"tidy",
|
|
405
|
+
TidyTree_default
|
|
406
|
+
],
|
|
407
|
+
[
|
|
408
|
+
"radial",
|
|
409
|
+
RadialTree_default
|
|
410
|
+
],
|
|
411
|
+
[
|
|
412
|
+
"edge",
|
|
413
|
+
HierarchicalEdgeBundling_default
|
|
414
|
+
]
|
|
415
|
+
]);
|
|
416
|
+
var Tree = ({ space, selected, variant = "tidy", onNodeClick }) => {
|
|
417
|
+
const model = useMemo2(() => space ? new SpaceGraphModel().open(space, selected) : void 0, [
|
|
418
|
+
space,
|
|
419
|
+
selected
|
|
420
|
+
]);
|
|
421
|
+
const [tree3, setTree] = useState2();
|
|
422
|
+
useEffect2(() => {
|
|
423
|
+
return model?.subscribe(() => {
|
|
424
|
+
const tree4 = mapGraphToTreeData(model);
|
|
425
|
+
setTree(tree4);
|
|
426
|
+
}, true);
|
|
427
|
+
}, [
|
|
428
|
+
model
|
|
429
|
+
]);
|
|
430
|
+
const context = createSvgContext2();
|
|
431
|
+
const { ref, width = 0, height = 0 } = useResizeDetector();
|
|
432
|
+
useEffect2(() => {
|
|
433
|
+
if (width && height) {
|
|
434
|
+
const size = Math.min(width, height);
|
|
435
|
+
const radius = size * 0.4;
|
|
436
|
+
const options = {
|
|
437
|
+
// TODO(burdon): Type.
|
|
438
|
+
label: (d) => d.label ?? d.id,
|
|
439
|
+
width,
|
|
440
|
+
height,
|
|
441
|
+
radius,
|
|
442
|
+
marginLeft: (width - radius * 2) / 2,
|
|
443
|
+
marginRight: (width - radius * 2) / 2,
|
|
444
|
+
marginTop: (height - radius * 2) / 2,
|
|
445
|
+
marginBottom: (height - radius * 2) / 2,
|
|
446
|
+
slots: defaultTreeLayoutSlots
|
|
447
|
+
};
|
|
448
|
+
if (tree3) {
|
|
449
|
+
const renderer = renderers.get(variant);
|
|
450
|
+
renderer?.(context.ref.current, tree3, options);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}, [
|
|
454
|
+
tree3,
|
|
455
|
+
width,
|
|
456
|
+
height
|
|
457
|
+
]);
|
|
458
|
+
return /* @__PURE__ */ React2.createElement("div", {
|
|
459
|
+
ref,
|
|
460
|
+
className: "flex grow overflow-hidden",
|
|
461
|
+
onClick: () => onNodeClick?.()
|
|
462
|
+
}, /* @__PURE__ */ React2.createElement(SVGContextProvider2, {
|
|
463
|
+
context
|
|
464
|
+
}, /* @__PURE__ */ React2.createElement(SVG2, null)));
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
export {
|
|
468
|
+
SpaceGraphModel,
|
|
469
|
+
defaultTreeLayoutSlots,
|
|
470
|
+
Tree,
|
|
471
|
+
Graph
|
|
472
|
+
};
|
|
473
|
+
//# sourceMappingURL=chunk-7YEM64IQ.mjs.map
|