@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.
Files changed (124) hide show
  1. package/LICENSE +8 -0
  2. package/README.md +3 -0
  3. package/dist/lib/browser/ExplorerArticle-IPAJQMAX.mjs +27 -0
  4. package/dist/lib/browser/ExplorerArticle-IPAJQMAX.mjs.map +7 -0
  5. package/dist/lib/browser/ExplorerMain-3KFXOEYO.mjs +33 -0
  6. package/dist/lib/browser/ExplorerMain-3KFXOEYO.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-7YEM64IQ.mjs +473 -0
  8. package/dist/lib/browser/chunk-7YEM64IQ.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-JIDPF2GF.mjs +27 -0
  10. package/dist/lib/browser/chunk-JIDPF2GF.mjs.map +7 -0
  11. package/dist/lib/browser/chunk-TL6ADY3P.mjs +21 -0
  12. package/dist/lib/browser/chunk-TL6ADY3P.mjs.map +7 -0
  13. package/dist/lib/browser/index.mjs +38151 -0
  14. package/dist/lib/browser/index.mjs.map +7 -0
  15. package/dist/lib/browser/meta.json +1 -0
  16. package/dist/lib/browser/meta.mjs +9 -0
  17. package/dist/lib/browser/meta.mjs.map +7 -0
  18. package/dist/lib/browser/types/index.mjs +10 -0
  19. package/dist/lib/browser/types/index.mjs.map +7 -0
  20. package/dist/lib/node/ExplorerArticle-PYOGBY3Z.cjs +53 -0
  21. package/dist/lib/node/ExplorerArticle-PYOGBY3Z.cjs.map +7 -0
  22. package/dist/lib/node/ExplorerMain-HGCLO5O4.cjs +59 -0
  23. package/dist/lib/node/ExplorerMain-HGCLO5O4.cjs.map +7 -0
  24. package/dist/lib/node/chunk-2GOPBQBC.cjs +494 -0
  25. package/dist/lib/node/chunk-2GOPBQBC.cjs.map +7 -0
  26. package/dist/lib/node/chunk-HYXFS3AG.cjs +45 -0
  27. package/dist/lib/node/chunk-HYXFS3AG.cjs.map +7 -0
  28. package/dist/lib/node/chunk-UJZYAOD2.cjs +54 -0
  29. package/dist/lib/node/chunk-UJZYAOD2.cjs.map +7 -0
  30. package/dist/lib/node/index.cjs +38158 -0
  31. package/dist/lib/node/index.cjs.map +7 -0
  32. package/dist/lib/node/meta.cjs +30 -0
  33. package/dist/lib/node/meta.cjs.map +7 -0
  34. package/dist/lib/node/meta.json +1 -0
  35. package/dist/lib/node/types/index.cjs +32 -0
  36. package/dist/lib/node/types/index.cjs.map +7 -0
  37. package/dist/types/src/ExplorerPlugin.d.ts +4 -0
  38. package/dist/types/src/ExplorerPlugin.d.ts.map +1 -0
  39. package/dist/types/src/components/Chart/Chart.d.ts +10 -0
  40. package/dist/types/src/components/Chart/Chart.d.ts.map +1 -0
  41. package/dist/types/src/components/Chart/Chart.stories.d.ts +11 -0
  42. package/dist/types/src/components/Chart/Chart.stories.d.ts.map +1 -0
  43. package/dist/types/src/components/Chart/index.d.ts +2 -0
  44. package/dist/types/src/components/Chart/index.d.ts.map +1 -0
  45. package/dist/types/src/components/ExplorerArticle.d.ts +7 -0
  46. package/dist/types/src/components/ExplorerArticle.d.ts.map +1 -0
  47. package/dist/types/src/components/ExplorerMain.d.ts +7 -0
  48. package/dist/types/src/components/ExplorerMain.d.ts.map +1 -0
  49. package/dist/types/src/components/Globe/Globe.d.ts +12 -0
  50. package/dist/types/src/components/Globe/Globe.d.ts.map +1 -0
  51. package/dist/types/src/components/Globe/Globe.stories.d.ts +12 -0
  52. package/dist/types/src/components/Globe/Globe.stories.d.ts.map +1 -0
  53. package/dist/types/src/components/Globe/index.d.ts +2 -0
  54. package/dist/types/src/components/Globe/index.d.ts.map +1 -0
  55. package/dist/types/src/components/Graph/Graph.d.ts +8 -0
  56. package/dist/types/src/components/Graph/Graph.d.ts.map +1 -0
  57. package/dist/types/src/components/Graph/Graph.stories.d.ts +14 -0
  58. package/dist/types/src/components/Graph/Graph.stories.d.ts.map +1 -0
  59. package/dist/types/src/components/Graph/graph-model.d.ts +33 -0
  60. package/dist/types/src/components/Graph/graph-model.d.ts.map +1 -0
  61. package/dist/types/src/components/Graph/index.d.ts +3 -0
  62. package/dist/types/src/components/Graph/index.d.ts.map +1 -0
  63. package/dist/types/src/components/Tree/Tree.d.ts +27 -0
  64. package/dist/types/src/components/Tree/Tree.d.ts.map +1 -0
  65. package/dist/types/src/components/Tree/Tree.stories.d.ts +29 -0
  66. package/dist/types/src/components/Tree/Tree.stories.d.ts.map +1 -0
  67. package/dist/types/src/components/Tree/index.d.ts +2 -0
  68. package/dist/types/src/components/Tree/index.d.ts.map +1 -0
  69. package/dist/types/src/components/Tree/layout/HierarchicalEdgeBundling.d.ts +5 -0
  70. package/dist/types/src/components/Tree/layout/HierarchicalEdgeBundling.d.ts.map +1 -0
  71. package/dist/types/src/components/Tree/layout/RadialTree.d.ts +4 -0
  72. package/dist/types/src/components/Tree/layout/RadialTree.d.ts.map +1 -0
  73. package/dist/types/src/components/Tree/layout/TidyTree.d.ts +4 -0
  74. package/dist/types/src/components/Tree/layout/TidyTree.d.ts.map +1 -0
  75. package/dist/types/src/components/Tree/layout/index.d.ts +5 -0
  76. package/dist/types/src/components/Tree/layout/index.d.ts.map +1 -0
  77. package/dist/types/src/components/Tree/types.d.ts +8 -0
  78. package/dist/types/src/components/Tree/types.d.ts.map +1 -0
  79. package/dist/types/src/components/index.d.ts +12 -0
  80. package/dist/types/src/components/index.d.ts.map +1 -0
  81. package/dist/types/src/components/plot.d.ts +12 -0
  82. package/dist/types/src/components/plot.d.ts.map +1 -0
  83. package/dist/types/src/index.d.ts +5 -0
  84. package/dist/types/src/index.d.ts.map +1 -0
  85. package/dist/types/src/meta.d.ts +15 -0
  86. package/dist/types/src/meta.d.ts.map +1 -0
  87. package/dist/types/src/translations.d.ts +12 -0
  88. package/dist/types/src/translations.d.ts.map +1 -0
  89. package/dist/types/src/types/index.d.ts +3 -0
  90. package/dist/types/src/types/index.d.ts.map +1 -0
  91. package/dist/types/src/types/types.d.ts +7 -0
  92. package/dist/types/src/types/types.d.ts.map +1 -0
  93. package/dist/types/src/types/view.d.ts +14 -0
  94. package/dist/types/src/types/view.d.ts.map +1 -0
  95. package/package.json +98 -0
  96. package/src/ExplorerPlugin.tsx +103 -0
  97. package/src/components/Chart/Chart.stories.tsx +46 -0
  98. package/src/components/Chart/Chart.tsx +54 -0
  99. package/src/components/Chart/index.ts +5 -0
  100. package/src/components/ExplorerArticle.tsx +28 -0
  101. package/src/components/ExplorerMain.tsx +34 -0
  102. package/src/components/Globe/Globe.stories.tsx +115 -0
  103. package/src/components/Globe/Globe.tsx +65 -0
  104. package/src/components/Globe/index.ts +5 -0
  105. package/src/components/Graph/Graph.stories.tsx +59 -0
  106. package/src/components/Graph/Graph.tsx +151 -0
  107. package/src/components/Graph/graph-model.ts +146 -0
  108. package/src/components/Graph/index.ts +7 -0
  109. package/src/components/Tree/Tree.stories.tsx +97 -0
  110. package/src/components/Tree/Tree.tsx +109 -0
  111. package/src/components/Tree/index.ts +5 -0
  112. package/src/components/Tree/layout/HierarchicalEdgeBundling.ts +164 -0
  113. package/src/components/Tree/layout/RadialTree.ts +96 -0
  114. package/src/components/Tree/layout/TidyTree.ts +102 -0
  115. package/src/components/Tree/layout/index.ts +9 -0
  116. package/src/components/Tree/types.ts +39 -0
  117. package/src/components/index.ts +14 -0
  118. package/src/components/plot.ts +15 -0
  119. package/src/index.ts +12 -0
  120. package/src/meta.tsx +19 -0
  121. package/src/translations.ts +18 -0
  122. package/src/types/index.ts +6 -0
  123. package/src/types/types.ts +27 -0
  124. package/src/types/view.ts +11 -0
@@ -0,0 +1,96 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ // Copyright 2022 Observable, Inc.
4
+ //
5
+
6
+ import * as d3 from 'd3';
7
+
8
+ import { type TreeOptions } from '../Tree';
9
+
10
+ // Released under the ISC license.
11
+ // https://observablehq.com/@d3/radial-tree
12
+ // https://observablehq.com/@d3/tree
13
+ const RadialTree = (s: SVGSVGElement, data: any, options: TreeOptions) => {
14
+ const svg = d3.select(s);
15
+ svg.selectAll('*').remove();
16
+
17
+ const {
18
+ label, // given a node d, returns the display name
19
+ radius = 400,
20
+ r = 4, // radius of nodes
21
+ slots,
22
+ } = options;
23
+
24
+ const arc = 2 * Math.PI;
25
+
26
+ const root = d3.hierarchy(data);
27
+
28
+ // Sort the nodes.
29
+ // if (sort) {
30
+ // root.sort(sort);
31
+ // }
32
+
33
+ // Compute labels and titles.
34
+ const descendants = root.descendants();
35
+ const getLabel = label === null ? null : descendants.map((d) => label(d.data));
36
+
37
+ // Compute the layout.
38
+ const layout = d3
39
+ .tree()
40
+ .size([arc, radius])
41
+ .separation((a: any, b: any) => (a.parent === b.parent ? 1 : 2) / a.depth);
42
+ layout(root);
43
+
44
+ // Links.
45
+ svg
46
+ .append('g')
47
+ .selectAll('path')
48
+ .data(root.links())
49
+ .join('path')
50
+ .attr('class', slots?.path ?? '')
51
+ .attr(
52
+ 'd',
53
+ d3
54
+ .linkRadial()
55
+ .angle((d: any) => d.x + Math.PI / 2)
56
+ .radius((d: any) => d.y) as any,
57
+ );
58
+
59
+ // Nodes.
60
+ const node = svg
61
+ .append('g')
62
+ .selectAll('a')
63
+ .data(root.descendants())
64
+ .join('a')
65
+ // .attr('xlink:href', link == null ? null : (d) => link(d.data, d))
66
+ // .attr('target', link == null ? null : linkTarget)
67
+ .attr('transform', (d: any) => `rotate(${(d.x * 180) / Math.PI}) translate(${d.y},0)`);
68
+
69
+ node
70
+ .append('circle')
71
+ .attr('class', slots?.node ?? '')
72
+ .attr('r', r);
73
+
74
+ // if (title != null) {
75
+ // node.append('title').text((d) => title(d.data, d));
76
+ // }
77
+
78
+ // Text.
79
+ if (getLabel) {
80
+ node
81
+ .append('text')
82
+ .attr('transform', (d: any) => `rotate(${d.x >= Math.PI ? 180 : 0})`)
83
+ .attr('dy', '0.32em')
84
+ // eslint-disable-next-line no-mixed-operators
85
+ .attr('x', (d: any) => (d.x < Math.PI === !d.children ? 6 : -6))
86
+ // eslint-disable-next-line no-mixed-operators
87
+ .attr('text-anchor', (d: any) => (d.x < Math.PI === !d.children ? 'start' : 'end'))
88
+ // .attr('paint-order', 'stroke')
89
+ .attr('class', slots?.text ?? '')
90
+ .text((d, i) => getLabel[i]);
91
+ }
92
+
93
+ return svg.node();
94
+ };
95
+
96
+ export default RadialTree;
@@ -0,0 +1,102 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ // Copyright 2021 Observable, Inc.
4
+ //
5
+
6
+ import * as d3 from 'd3';
7
+
8
+ import { type TreeOptions } from '../Tree';
9
+
10
+ // Released under the ISC license.
11
+ // https://observablehq.com/@d3/tree
12
+ const TidyTree = (s: SVGSVGElement, data: any, options: TreeOptions) => {
13
+ const svg = d3.select(s);
14
+ svg.selectAll('*').remove();
15
+
16
+ const { label, width, height, r = 4, padding = 4, margin = 60, slots } = options;
17
+
18
+ const root = d3.hierarchy(data);
19
+
20
+ // Compute labels and titles.
21
+ const descendants = root.descendants();
22
+ const getLabel = label == null ? null : descendants.map((d) => label(d.data));
23
+
24
+ // Compute the layout.
25
+ const dx = 16;
26
+ const dy = width / (root.height + padding);
27
+ const layout = d3.tree().nodeSize([dx, dy]);
28
+ layout(root);
29
+
30
+ // Center the tree.
31
+ let x0 = Infinity;
32
+ let x1 = -x0;
33
+ let y0 = Infinity;
34
+ let y1 = -y0;
35
+ root.each((d: any) => {
36
+ if (d.x > x1) {
37
+ x1 = d.x;
38
+ }
39
+ if (d.x < x0) {
40
+ x0 = d.x;
41
+ }
42
+ if (d.y > y1) {
43
+ y1 = d.y;
44
+ }
45
+ if (d.y < y0) {
46
+ y0 = d.y;
47
+ }
48
+ });
49
+
50
+ // TODO(burdon): Option to expand.
51
+ // NOTE: x and y are flipped.
52
+ const sx = Math.min(2, Math.max(1, (height - margin * 2) / (x1 - x0)));
53
+ const oy = -(width - (y1 - y0)) / 2;
54
+
55
+ // Links.
56
+ svg
57
+ .append('g')
58
+ .selectAll('path')
59
+ .data(root.links())
60
+ .join('path')
61
+ .attr('class', slots?.path ?? '')
62
+ .attr(
63
+ 'd',
64
+ d3
65
+ .link(d3.curveBumpX)
66
+ .x((d: any) => d.y + oy)
67
+ .y((d: any) => d.x * sx) as any,
68
+ );
69
+
70
+ // Nodes.
71
+ const node = svg
72
+ .append('g')
73
+ .selectAll('a')
74
+ .data(root.descendants())
75
+ .join('a')
76
+ // .attr('xlink:href', link == null ? null : (d) => link(d.data, d))
77
+ // .attr('target', link == null ? null : linkTarget)
78
+ .attr('transform', (d: any) => `translate(${d.y + oy},${d.x * sx})`);
79
+
80
+ node
81
+ .append('circle')
82
+ .attr('class', slots?.node ?? '')
83
+ .attr('r', r);
84
+
85
+ // if (title != null) {
86
+ // node.append('title').text((d) => title(d.data, d));
87
+ // }
88
+
89
+ if (getLabel) {
90
+ node
91
+ .append('text')
92
+
93
+ .attr('dy', '0.32em')
94
+ .attr('x', (d) => (d.children ? -6 : 6))
95
+ .attr('text-anchor', (d) => (d.children ? 'end' : 'start'))
96
+ // .attr('paint-order', 'stroke')
97
+ .attr('class', slots?.text ?? '')
98
+ .text((d, i) => getLabel[i]);
99
+ }
100
+ };
101
+
102
+ export default TidyTree;
@@ -0,0 +1,9 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import HierarchicalEdgeBundling from './HierarchicalEdgeBundling';
6
+ import RadialTree from './RadialTree';
7
+ import TidyTree from './TidyTree';
8
+
9
+ export { HierarchicalEdgeBundling, RadialTree, TidyTree };
@@ -0,0 +1,39 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import type { GraphModel } from '@dxos/gem-spore';
6
+
7
+ export type TreeNode = {
8
+ id: string;
9
+ label?: string;
10
+ children?: TreeNode[];
11
+ };
12
+
13
+ export const mapGraphToTreeData = <N>(model: GraphModel<N>, maxDepth = 8): TreeNode | undefined => {
14
+ const mapNode = (node: N, depth = 0): TreeNode => {
15
+ const treeNode: TreeNode = {
16
+ id: model.idAccessor(node),
17
+ label: model.idAccessor(node).slice(0, 8),
18
+ };
19
+
20
+ const links = model.graph.links.filter((link) => link.source === treeNode.id);
21
+ if (depth < maxDepth) {
22
+ treeNode.children = links.map((link) =>
23
+ mapNode(model.graph.nodes.find((node) => model.idAccessor(node) === link.target)!, depth + 1),
24
+ );
25
+ }
26
+
27
+ return treeNode;
28
+ };
29
+
30
+ let data: TreeNode | undefined;
31
+ if (model.selected) {
32
+ const node = model.graph.nodes.find((node) => model.idAccessor(node) === model.selected);
33
+ if (node) {
34
+ data = mapNode(node);
35
+ }
36
+ }
37
+
38
+ return data;
39
+ };
@@ -0,0 +1,14 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ // Lazily load components for content surfaces.
8
+ export const ExplorerMain = React.lazy(() => import('./ExplorerMain'));
9
+ export const ExplorerArticle = React.lazy(() => import('./ExplorerArticle'));
10
+
11
+ export * from './Chart';
12
+ export * from './Globe';
13
+ export * from './Graph';
14
+ export * from './Tree';
@@ -0,0 +1,15 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import type { ChannelValueSpec } from '@observablehq/plot';
6
+
7
+ export type Point = { x: number; y: number };
8
+ export type GeoLocation = { lat: number; lng: number };
9
+
10
+ export type Accessor<T> = (object: any) => T;
11
+
12
+ export const createAdapter = <T extends Record<string, any>>(
13
+ prop: string,
14
+ accessor: Accessor<T> | undefined,
15
+ ): ChannelValueSpec => (accessor ? { transform: (values) => values.map((value) => accessor(value)[prop]) } : prop);
package/src/index.ts ADDED
@@ -0,0 +1,12 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { ExplorerPlugin } from './ExplorerPlugin';
6
+
7
+ export default ExplorerPlugin;
8
+
9
+ // TODO(burdon): Factor out.
10
+ export * from './components';
11
+
12
+ export * from './ExplorerPlugin';
package/src/meta.tsx ADDED
@@ -0,0 +1,19 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { Graph, type IconProps } from '@phosphor-icons/react';
6
+ import React from 'react';
7
+
8
+ import { pluginMeta } from '@dxos/app-framework';
9
+
10
+ export const EXPLORER_PLUGIN = 'dxos.org/plugin/explorer';
11
+
12
+ export default pluginMeta({
13
+ id: EXPLORER_PLUGIN,
14
+ name: 'Explorer',
15
+ description: 'Explore the ECHO hypergraph.',
16
+ tags: ['experimental'],
17
+ iconComponent: (props: IconProps) => <Graph {...props} />,
18
+ iconSymbol: 'ph--graph--regular',
19
+ });
@@ -0,0 +1,18 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { EXPLORER_PLUGIN } from './meta';
6
+
7
+ export default [
8
+ {
9
+ 'en-US': {
10
+ [EXPLORER_PLUGIN]: {
11
+ 'plugin name': 'Explorer',
12
+ 'object title label': 'Title',
13
+ 'object title placeholder': 'New explorer',
14
+ 'create object label': 'Create explorer',
15
+ },
16
+ },
17
+ },
18
+ ];
@@ -0,0 +1,6 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ export * from './view';
6
+ export * from './types';
@@ -0,0 +1,27 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import type {
6
+ GraphBuilderProvides,
7
+ IntentResolverProvides,
8
+ MetadataRecordsProvides,
9
+ SurfaceProvides,
10
+ TranslationsProvides,
11
+ } from '@dxos/app-framework';
12
+ import { type SchemaProvides } from '@dxos/plugin-client';
13
+
14
+ import { EXPLORER_PLUGIN } from '../meta';
15
+
16
+ const EXPLORER_ACTION = `${EXPLORER_PLUGIN}/action`;
17
+
18
+ export enum ExplorerAction {
19
+ CREATE = `${EXPLORER_ACTION}/create`,
20
+ }
21
+
22
+ export type ExplorerPluginProvides = SurfaceProvides &
23
+ IntentResolverProvides &
24
+ GraphBuilderProvides &
25
+ MetadataRecordsProvides &
26
+ TranslationsProvides &
27
+ SchemaProvides;
@@ -0,0 +1,11 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { S, TypedObject } from '@dxos/echo-schema';
6
+
7
+ // TODO(burdon): Standardize views?
8
+ export class ViewType extends TypedObject({ typename: 'dxos.org/type/View', version: '0.1.0' })({
9
+ name: S.optional(S.String),
10
+ type: S.String,
11
+ }) {}