Improves visualization data serializers and implements typescript declaration file extraction.

This commit is contained in:
Henning Dieterichs
2020-08-22 14:12:57 +02:00
parent b46c7155b2
commit 1911a8092e
22 changed files with 240 additions and 118 deletions

View File

@@ -10,7 +10,7 @@
"dependencies": {
"@blueprintjs/core": "^3.23.1",
"@hediet/std": "^0.6.0",
"@hediet/semantic-json": "^0.3.11",
"@hediet/semantic-json": "^0.3.14",
"blueprintjs": "^0.0.8",
"classnames": "^2.2.6",
"mobx": "^5.15.4",
@@ -21,7 +21,7 @@
"messagepack": "^1.1.10",
"base64-js": "^1.3.1",
"lzma": "^2.3.2",
"@hediet/monaco-editor-react": "^0.1.0"
"@hediet/monaco-editor-react": "^0.1.1"
},
"devDependencies": {
"gh-pages": "^2.2.0",

View File

@@ -0,0 +1,15 @@
import { TypeScriptTypeGenerator } from "@hediet/semantic-json";
import { writeFileSync } from "fs";
import { globalVisualizationFactory } from "@hediet/visualization-core";
import "./src/index";
const t = new TypeScriptTypeGenerator();
const tp = t.getType(globalVisualizationFactory.getSerializer());
const src = `export type KnownVisualizationData = ${tp};\n\n\n${[
...t.definitions.values(),
]
.map(v => v.getDefinitionSource({ exported: true }) + `\n\n`)
.join("")}`;
writeFileSync("./out.ts", src, { encoding: "utf-8" });

View File

@@ -21,7 +21,7 @@
"types": "./dist/index.d.ts",
"dependencies": {
"@hediet/std": "^0.6.0",
"@hediet/semantic-json": "^0.3.11",
"@hediet/semantic-json": "^0.3.14",
"classnames": "^2.2.6",
"mobx": "^5.15.4",
"mobx-react": "^6.1.8",
@@ -39,7 +39,7 @@
"@finos/perspective-viewer": "^0.5.2",
"@finos/perspective-viewer-d3fc": "^0.5.2",
"@finos/perspective-viewer-datagrid": "^0.5.2",
"@hediet/monaco-editor-react": "^0.1.0"
"@hediet/monaco-editor-react": "^0.1.1"
},
"peerDependencies": {
"@hediet/visualization-core": "^0.1.0"

View File

@@ -19,7 +19,7 @@ import {
} from "@hediet/visualization-core";
import { createTreeViewModelFromTreeNodeData } from "../tree-visualizer";
import { AstTree, NodeInfo } from "./AstVisualizer";
import React from "react";
import * as React from "react";
import LineColumn from "line-column";
import * as monacoTypes from "monaco-editor";
import { getLoadedMonaco } from "@hediet/monaco-editor-react";
@@ -54,7 +54,7 @@ export const sAstTreeNode: Serializer<AstTreeNode> = sLazy(() =>
{ inclusive: true }
)
),
}).defineAs(visualizationNs("TreeNodeItem"))
}).defineAs(visualizationNs("AstTreeNodeItem"))
),
segment: sOptionalProp(sString()),
isMarked: sOptionalProp(sBoolean()),
@@ -62,7 +62,7 @@ export const sAstTreeNode: Serializer<AstTreeNode> = sLazy(() =>
start: sNumber(),
length: sNumber(),
}),
}).defineAs(visualizationNs("TreeNode"))
}).defineAs(visualizationNs("AstTreeNode"))
);
export const sAstTree = sOpenObject({
@@ -74,7 +74,7 @@ export const sAstTree = sOpenObject({
root: sAstTreeNode,
text: sString(),
fileName: sOptionalProp(sString()),
});
}).defineAs(visualizationNs("AstTreeVisualizationData"));
export const astVisualizer = createVisualizer({
id: "ast",

View File

@@ -1,4 +1,4 @@
import React from "react";
import * as React from "react";
import { sOpenObject, sLiteral, sString } from "@hediet/semantic-json";
import { GraphvizDotViewer } from "./GraphvizDotVisualizer";
import {
@@ -6,6 +6,7 @@ import {
globalVisualizationFactory,
createVisualizer,
} from "@hediet/visualization-core";
import { visualizationNs } from "../../../consts";
export const graphvizDotVisualizer = createVisualizer({
id: "graphviz-dot",
@@ -15,7 +16,7 @@ export const graphvizDotVisualizer = createVisualizer({
dotGraph: sLiteral(true),
}),
text: sString(),
}),
}).defineAs(visualizationNs("GraphvizDotVisualizationData")),
getVisualization: (data, self) =>
new ReactVisualization(self, { priority: 1500 }, () => (
<GraphvizDotViewer dotCode={data.text} />

View File

@@ -1,4 +1,4 @@
import React from "react";
import * as React from "react";
import { GraphvizGraphViewer } from "./GraphvizGraphVisualizer";
import { sGraph } from "../sGraph";
import {

View File

@@ -32,4 +32,4 @@ export const sGraph = sOpenObject({
kind: sOpenObject({ graph: sLiteral(true) }),
nodes: sArrayOf(sGraphNode),
edges: sArrayOf(sGraphEdge),
}).defineAs(visualizationNs("Graph"));
}).defineAs(visualizationNs("GraphVisualizationData"));

View File

@@ -1,4 +1,4 @@
import React from "react";
import * as React from "react";
import {
sOpenObject,
sLiteral,
@@ -14,15 +14,18 @@ import {
ReactVisualization,
globalVisualizationFactory,
} from "@hediet/visualization-core";
import { visualizationNs } from "../../consts";
export const sGrid = sOpenObject({
kind: sOpenObject({
array: sLiteral(true),
grid: sLiteral(true),
}),
columnLabels: sArrayOf(
sOpenObject({
label: sOptionalProp(sString(), {}),
})
columnLabels: sOptionalProp(
sArrayOf(
sOpenObject({
label: sOptionalProp(sString(), {}),
})
)
),
rows: sArrayOf(
sOpenObject({
@@ -55,7 +58,7 @@ export const sGrid = sOpenObject({
),
{}
),
});
}).defineAs(visualizationNs("GridVisualizationData"));
export const gridVisualizer = createVisualizer({
id: "grid",

View File

@@ -1,5 +1,5 @@
import { sOpenObject, sLiteral, sString, sProp } from "@hediet/semantic-json";
import React from "react";
import * as React from "react";
import {
createVisualizer,
ReactVisualization,
@@ -8,6 +8,7 @@ import {
import { SvgViewer } from "../svg-visualizer/SvgViewer";
import { Observer, observer, disposeOnUnmount } from "mobx-react";
import { observable, autorun } from "mobx";
import { visualizationNs } from "../../consts";
export const imageVisualizer = createVisualizer({
id: "image",
@@ -16,8 +17,10 @@ export const imageVisualizer = createVisualizer({
kind: sOpenObject({
imagePng: sLiteral(true),
}),
base64Data: sProp( sString(), { description: "The base 64 encoded PNG representation of the image" }),
}),
base64Data: sProp(sString(), {
description: "The base 64 encoded PNG representation of the image",
}),
}).defineAs(visualizationNs("ImageVisualizationData")),
getVisualization: (data, self) =>
new ReactVisualization(self, { priority: 1000 }, () => {
return <ImageViewer base64Data={data.base64Data} />;

View File

@@ -1,4 +1,4 @@
import React from "react";
import * as React from "react";
import { observer, disposeOnUnmount } from "mobx-react";
import { observable, autorun } from "mobx";
import * as monacoTypes from "monaco-editor";

View File

@@ -5,13 +5,14 @@ import {
sOptionalProp,
sProp,
} from "@hediet/semantic-json";
import React from "react";
import * as React from "react";
import { getLanguageId, MonacoEditor } from "./MonacoEditor";
import {
createVisualizer,
ReactVisualization,
globalVisualizationFactory,
} from "@hediet/visualization-core";
import { visualizationNs } from "../../consts";
export const monacoTextVisualizer = createVisualizer({
id: "monaco-text",
@@ -20,12 +21,12 @@ export const monacoTextVisualizer = createVisualizer({
kind: sOpenObject({
text: sLiteral(true),
}),
text: sProp( sString(), { description: "The text to show" }),
text: sProp(sString(), { description: "The text to show" }),
fileName: sOptionalProp(sString(), {
description:
"An optional filename that might be used for chosing a syntax highlighter",
}),
}),
}).defineAs(visualizationNs("MonacoTextVisualizationData")),
getVisualization: (data, self) =>
new ReactVisualization(self, { priority: 500 }, theme => {
let id = "text";

View File

@@ -0,0 +1,35 @@
import * as React from "react";
import "@finos/perspective-viewer";
import "@finos/perspective-viewer-datagrid";
import "@finos/perspective-viewer-d3fc";
import "@finos/perspective-viewer/themes/all-themes.css";
import { HTMLPerspectiveViewerElement } from "@finos/perspective-viewer";
export class PerspectiveDataViewer extends React.Component<
{ data: object[] } & React.HTMLAttributes<HTMLDivElement>
> {
private readonly nodeRef = React.createRef<HTMLPerspectiveViewerElement>();
componentDidUpdate() {
this.nodeRef.current!.load(this.props.data);
}
componentDidMount() {
setTimeout(() => {
// TODO: Why timeout?
// It does not work without it.
this.nodeRef.current!.load(this.props.data);
this.nodeRef.current!.toggleConfig();
});
}
render() {
return (
<perspective-viewer
class={this.props.className}
style={this.props.style}
ref={this.nodeRef}
/>
);
}
}

View File

@@ -1,25 +1,27 @@
import React from "react";
import { sOpenObject, sLiteral, sArrayOf, sAny } from "@hediet/semantic-json";
import * as React from "react";
import { sOpenObject, sLiteral, sArrayOf, sProp } from "@hediet/semantic-json";
import { toJS } from "mobx";
import "@finos/perspective-viewer";
import "@finos/perspective-viewer-datagrid";
import "@finos/perspective-viewer-d3fc";
import "@finos/perspective-viewer/themes/all-themes.css";
import { HTMLPerspectiveViewerElement } from "@finos/perspective-viewer";
import {
createVisualizer,
ReactVisualization,
globalVisualizationFactory,
} from "@hediet/visualization-core";
import { makeLazyLoadable } from "../../utils/LazyLoadable";
import { visualizationNs } from "../../consts";
export const sTable = sOpenObject({
kind: sOpenObject({
table: sLiteral(true),
}),
rows: sArrayOf(
sAny() // object
),
});
rows: sProp(sArrayOf(sOpenObject({})), {
description:
"An array of objects. The properties of the objects are used as columns.",
}),
}).defineAs(visualizationNs("TableVisualizationData"));
const PerspectiveDataViewerLazyLoadable = makeLazyLoadable(
async () => (await import("./PerspectiveDataViewer")).PerspectiveDataViewer
);
export const perspectiveTableVisualizer = createVisualizer({
id: "perspective-table",
@@ -27,7 +29,7 @@ export const perspectiveTableVisualizer = createVisualizer({
serializer: sTable,
getVisualization: (data, self) =>
new ReactVisualization(self, { priority: 1000 }, theme => (
<PerspectiveDataViewer
<PerspectiveDataViewerLazyLoadable
className={
{
light: "perspective-viewer-material",
@@ -43,34 +45,4 @@ export const perspectiveTableVisualizer = createVisualizer({
)),
});
class PerspectiveDataViewer extends React.Component<
{ data: object[] } & React.HTMLAttributes<HTMLDivElement>
> {
private readonly nodeRef = React.createRef<HTMLPerspectiveViewerElement>();
componentDidUpdate() {
this.nodeRef.current!.load(this.props.data);
}
componentDidMount() {
setTimeout(() => {
// TODO: Why timeout?
// It does not work without it.
this.nodeRef.current!.load(this.props.data);
this.nodeRef.current!.toggleConfig();
});
}
render() {
return (
<perspective-viewer
class={this.props.className}
style={this.props.style}
ref={this.nodeRef}
/>
);
}
}
globalVisualizationFactory.addVisualizer(perspectiveTableVisualizer);

View File

@@ -6,6 +6,10 @@ import {
sOptionalProp,
sAny,
sProp,
sString,
sUnion,
sNumber,
sNull,
} from "@hediet/semantic-json";
import { makeLazyLoadable } from "../../utils/LazyLoadable";
import {
@@ -13,11 +17,15 @@ import {
ReactVisualization,
globalVisualizationFactory,
} from "@hediet/visualization-core";
import { visualizationNs } from "../../consts";
const PlotlyViewerLazyLoadable = makeLazyLoadable(
async () => (await import("./PlotlyViewer")).PlotlyViewer
);
const sDatum = sUnion([sString(), sNumber(), sNull()]);
const sDatumArr = sUnion([sArrayOf(sDatum), sArrayOf(sArrayOf(sDatum))]);
//const x: Plotly.Data;
export const plotlyVisualizer = createVisualizer({
id: "plotly",
name: "plotly",
@@ -25,15 +33,83 @@ export const plotlyVisualizer = createVisualizer({
kind: sOpenObject({
plotly: sLiteral(true),
}),
data: sProp(sArrayOf(sOpenObject()), {
description:
"Expecting Plotly.Data[] (https://github.com/DefinitelyTyped/DefinitelyTyped/blob/795ce172038dbafcb9cba030d637d733a7eea19c/types/plotly.js/index.d.ts#L1036)",
}),
layout: sOptionalProp(sOpenObject(), {
description:
"Expecting Partial<Plotly.Layout> (https://github.com/DefinitelyTyped/DefinitelyTyped/blob/795ce172038dbafcb9cba030d637d733a7eea19c/types/plotly.js/index.d.ts#L329)",
}),
}),
data: sProp(
sArrayOf(
sOpenObject({
text: sOptionalProp(
sUnion([sString(), sArrayOf(sString())])
),
xaxis: sOptionalProp(sString()),
yaxis: sOptionalProp(sString()),
x: sOptionalProp(sDatumArr),
y: sOptionalProp(sDatumArr),
z: sOptionalProp(sDatumArr),
type: sOptionalProp(
sUnion([
sLiteral("bar"),
sLiteral("box"),
sLiteral("candlestick"),
sLiteral("choropleth"),
sLiteral("contour"),
sLiteral("heatmap"),
sLiteral("histogram"),
sLiteral("indicator"),
sLiteral("mesh3d"),
sLiteral("ohlc"),
sLiteral("parcoords"),
sLiteral("pie"),
sLiteral("pointcloud"),
sLiteral("scatter"),
sLiteral("scatter3d"),
sLiteral("scattergeo"),
sLiteral("scattergl"),
sLiteral("scatterpolar"),
sLiteral("scatterternary"),
sLiteral("sunburst"),
sLiteral("surface"),
sLiteral("treemap"),
sLiteral("waterfall"),
sLiteral("funnel"),
sLiteral("funnelarea"),
sLiteral("scattermapbox"),
])
),
mode: sOptionalProp(
sUnion([
sLiteral("lines"),
sLiteral("markers"),
sLiteral("text"),
sLiteral("lines+markers"),
sLiteral("text+markers"),
sLiteral("text+lines"),
sLiteral("text+lines+markers"),
sLiteral("none"),
sLiteral("gauge"),
sLiteral("number"),
sLiteral("delta"),
sLiteral("number+delta"),
sLiteral("gauge+number"),
sLiteral("gauge+number+delta"),
sLiteral("gauge+delta"),
])
),
})
),
{
description:
"Expecting Plotly.Data[] (https://github.com/DefinitelyTyped/DefinitelyTyped/blob/795ce172038dbafcb9cba030d637d733a7eea19c/types/plotly.js/index.d.ts#L1036)",
}
),
layout: sOptionalProp(
sOpenObject({
title: sOptionalProp(sString()),
}),
{
description:
"Expecting Partial<Plotly.Layout> (https://github.com/DefinitelyTyped/DefinitelyTyped/blob/795ce172038dbafcb9cba030d637d733a7eea19c/types/plotly.js/index.d.ts#L329)",
}
),
}).defineAs(visualizationNs("PlotlyVisualizationData")),
getVisualization: (data, self) =>
new ReactVisualization(self, { priority: 1000 }, theme => (
<PlotlyViewerLazyLoadable

View File

@@ -1,10 +1,11 @@
import { sOpenObject, sLiteral, sString } from "@hediet/semantic-json";
import React from "react";
import * as React from "react";
import {
createVisualizer,
ReactVisualization,
globalVisualizationFactory,
} from "@hediet/visualization-core";
import { visualizationNs } from "../../consts";
export const simpleTextVisualizer = createVisualizer({
id: "simple-text",
@@ -14,7 +15,7 @@ export const simpleTextVisualizer = createVisualizer({
text: sLiteral(true),
}),
text: sString(),
}),
}).defineAs(visualizationNs("SimpleTextVisualizationData")),
getVisualization: (data, self) =>
new ReactVisualization(self, { priority: 100 }, () => (
<pre

View File

@@ -1,16 +1,19 @@
import { sAny } from "@hediet/semantic-json";
import React from "react";
import { sAny, sOpenObject } from "@hediet/semantic-json";
import * as React from "react";
import {
createVisualizer,
ReactVisualization,
globalVisualizationFactory,
} from "@hediet/visualization-core";
import { MonacoEditor } from "../monaco-text-visualizer/MonacoEditor";
import { visualizationNs } from "../../consts";
export const sourceVisualizer = createVisualizer({
id: "source",
name: "JSON Source",
serializer: sAny(),
serializer: sOpenObject({
kind: sOpenObject({}),
}).defineAs(visualizationNs("SourceVisualizationData")),
getVisualization: (data, self) =>
new ReactVisualization(self, { priority: -100 }, theme => (
<MonacoEditor

View File

@@ -1,4 +1,4 @@
import React from "react";
import * as React from "react";
import { sOpenObject, sLiteral, sString, sProp } from "@hediet/semantic-json";
import { SvgViewer } from "./SvgViewer";
import {
@@ -15,8 +15,8 @@ export const svgVisualizer = createVisualizer({
kind: sOpenObject({
svg: sLiteral(true),
}),
text: sProp( sString(), { description: "The svg content" }),
}).defineAs(visualizationNs("SvgData")),
text: sProp(sString(), { description: "The svg content" }),
}).defineAs(visualizationNs("SvgVisualizationData")),
getVisualization: (data, self) =>
new ReactVisualization(self, { priority: 1500 }, () => (
<SvgViewer svgContent={data.text} />

View File

@@ -38,27 +38,39 @@ export interface Item {
const sTreeNode: Serializer<TreeNode> = sLazy(() =>
sOpenObject({
children: sProp(sArrayOf(sTreeNode), { description: "The children of this tree-node" }),
items: sProp(sArrayOf(
sOpenObject({
text: sProp(sString(), { description: "The text to show" }),
emphasis: sOptionalProp(
sUnion(
[
sLiteral("style1"),
sLiteral("style2"),
sLiteral("style3"),
sString(),
],
{ inclusive: true }
), {
description: "The style of the text"
}
),
}).defineAs(visualizationNs("TreeNodeItem"))
), { description: "The parts that make up the text of this item" }),
segment: sOptionalProp(sString(), { description: "If a node is selected, the concatenation of all segment values from root to the selected node is shown to the user." }),
isMarked: sOptionalProp(sBoolean(), { description: "Marked nodes are highlighted and scrolled into view on every visualization update." }),
children: sProp(sArrayOf(sTreeNode), {
description: "The children of this tree-node",
}),
items: sProp(
sArrayOf(
sOpenObject({
text: sProp(sString(), { description: "The text to show" }),
emphasis: sOptionalProp(
sUnion(
[
sLiteral("style1"),
sLiteral("style2"),
sLiteral("style3"),
sString(),
],
{ inclusive: true }
),
{
description: "The style of the text",
}
),
}).defineAs(visualizationNs("TreeNodeItem"))
),
{ description: "The parts that make up the text of this item" }
),
segment: sOptionalProp(sString(), {
description:
"If a node is selected, the concatenation of all segment values from root to the selected node is shown to the user.",
}),
isMarked: sOptionalProp(sBoolean(), {
description:
"Marked nodes are highlighted and scrolled into view on every visualization update.",
}),
}).defineAs(visualizationNs("TreeNode"))
);
@@ -67,7 +79,7 @@ const sTree = sOpenObject({
tree: sLiteral(true),
}),
root: sTreeNode,
}).defineAs(visualizationNs("TreeData"));
}).defineAs(visualizationNs("TreeVisualizationData"));
export const treeVisualizer = createVisualizer({
id: "tree",

View File

@@ -1,7 +1,7 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "es2020",
"module": "CommonJS",
"moduleResolution": "node",
"strict": true,
"outDir": "dist",

View File

@@ -28,7 +28,7 @@
"types": "./dist/index.d.ts",
"dependencies": {
"@hediet/std": "^0.6.0",
"@hediet/semantic-json": "^0.3.11",
"@hediet/semantic-json": "^0.3.14",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-measure": "^2.3.0"

View File

@@ -1,7 +1,7 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "es2020",
"module": "CommonJS",
"moduleResolution": "node",
"strict": true,
"outDir": "dist",

View File

@@ -306,15 +306,15 @@
tslib "^1.9.3"
ws "^6.1.2"
"@hediet/monaco-editor-react@^0.1.0":
version "0.1.0"
resolved "https://registry.yarnpkg.com/@hediet/monaco-editor-react/-/monaco-editor-react-0.1.0.tgz#b00dfa28e2ffa09ecc748e35f4befc0e887947f2"
integrity sha512-EFAmKW1u9ks2iqTP63qqLPUezKMAnK+UvZrvoRmUMCpRRxG9uduYGPQfASaHcIQYzOqzWaVKvCQN5wQQ+lSxIQ==
"@hediet/monaco-editor-react@^0.1.1":
version "0.1.1"
resolved "https://registry.yarnpkg.com/@hediet/monaco-editor-react/-/monaco-editor-react-0.1.1.tgz#041f805aeb188403c7876f0f364d2a429e706031"
integrity sha512-0DZZfLcFNuc3Wrn+2eztnRloCBe6GV8zIrGT3LPdZlWYEigJT+Qh7ANvRHF0tCS5YPAFGQNZJcfzKbBfqRGo4w==
"@hediet/semantic-json@^0.3.11":
version "0.3.11"
resolved "https://registry.yarnpkg.com/@hediet/semantic-json/-/semantic-json-0.3.11.tgz#9420a89d30645ba333dfd4f3f2c120f973297ee2"
integrity sha512-KKw6ZcYHiyfhanNmln/WlG4KvZnMi/Ojy8O6HB6sqfDC5XCcNYjccUMMtaX23F/Hox0dWJPFqXYs54KJAA5itg==
"@hediet/semantic-json@^0.3.14":
version "0.3.14"
resolved "https://registry.yarnpkg.com/@hediet/semantic-json/-/semantic-json-0.3.14.tgz#876bd5c4b646c134641ad17e9ef352595fb163e7"
integrity sha512-u2QGfT98RNrcQjqRHwFUy+TU8+sLneBOYvHHNbkHyYNokqi8kCpE9LReTygGT+6SfMtydTWN6JT9L2ffxrvV6w==
"@hediet/std@^0.6.0":
version "0.6.0"