Skip to content

Commit

Permalink
feat: Add lit-html enabled graph
Browse files Browse the repository at this point in the history
Signed-off-by: Gordon Smith <GordonJSmith@gmail.com>
  • Loading branch information
GordonSmith committed Jan 23, 2025
1 parent 348b5e0 commit d9f5bbc
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 35 deletions.
117 changes: 117 additions & 0 deletions packages/graph/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
}

#placeholder,
#placeholder1,
#placeholder2 {
width: 100%;
height: 500px;
Expand All @@ -29,6 +30,86 @@
</head>

<body onresize="doResize()">
<h1>ESM Quick Test</h1>
<div id="placeholder1"></div>
<script type="module">
import { GraphHtmlT, svg } from "./src/index.ts";

import "@hpcc-js/common/font-awesome/css/font-awesome.min.css";

const nodeCount = 500;

const categories = [
{ id: 0, imageChar: "fa-user" },
{ id: 1, imageChar: "fa-home" }
];

const Subgraph = ({ text = "" }) => {
return svg`<h1>${text}</h1>`;
};

const Vertex = ({
categoryID = "",
text = ""
}) => {
return svg`\
<use href="#${categoryID}"></use>
<g transform="translate(0 26.666666666666668)">
<rect x="-12.7470703125" y="-10.5" rx="0" ry="0" width="25.494140625" height="21" fill="whitesmoke" stroke="lightgray" stroke-width="1"></rect><g transform="translate(0 1)" />
<g transform="translate(0 -1)">
<text font-family="monospace" font-size="10px" text-anchor="middle" dominant-baseline="middle" fill="black">${text}</text>
</g>
</g>`;
};

const Edge = ({
path = "",
strokeWidth = 1
}) => {
return svg`<path d="${path}" style="stroke-width:${strokeWidth}px"></path>`;
};

new GraphHtmlT(Subgraph, Vertex, Edge)
.categories(categories)
.data(createData())
.target("placeholder1")
.layout("ForceDirected")
.applyScaleOnLayout(true)
.allowDragging(false)
.render()
;

function createData() {
const rawData = {
"nodes": Array.from({ length: nodeCount }, (_, i) => {
return { "name": i + 1, "type": "number" }
}),
"links": Array.from({ length: nodeCount }, (_, i) => {
return { "source": Math.floor(Math.sqrt(i)), "target": i };
}).slice(1)
};
const vertices = rawData.nodes.map(function (node, idx) {
return {
categoryID: 0,
id: idx,
text: "" + node.name,
textFontFamily: "monospace"
};
});
return {
vertices: vertices,
edges: rawData.links.map(function (link, idx) {
return {
id: idx,
source: vertices[link.source],
target: vertices[link.target],
label: link.name,
fontFamily: "monospace"
};
}),
};
}
</script>
<h1>ESM Quick Test</h1>
<div id="placeholder2"></div>
<script type="module">
Expand Down Expand Up @@ -120,6 +201,42 @@ <h1>ESM Quick Test</h1>
.render()
;
</script>
<div id="placeholder"></div>
<script type="module">
import { SankeyGraph } from "./src/index.ts";

import "@hpcc-js/common/font-awesome/css/font-awesome.min.css";

new SankeyGraph()
.target("placeholder")
.vertexColumns(["category", "id", "label"])
.vertices([
[0, 0, "Year 1"],
[0, 1, "Year 2"],
[0, 2, "Year 3"],
[0, 3, "Year 4"],
[1, 4, "Math"],
[1, 5, "English"],
[1, 6, "Geometry"],
[1, 7, "Science"],
])
.edgeColumns(["source", "target", "weight"])
.edges([
[0, 4, 1],
[1, 4, 1],
[2, 4, 1],
[3, 4, 1],
[0, 5, 1],
[1, 5, 1],
[2, 6, 1],
[3, 6, 1],
[1, 7, 1],
[2, 7, 1],
[3, 7, 1],
])
.render()
;
</script>
<script>
function doResize() {
window.__widget?.resize()?.render();
Expand Down
3 changes: 2 additions & 1 deletion packages/graph/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@
"d3-shape": "^1",
"d3-tile": "^1",
"d3-transition": "^1",
"dagre": "0.8.5"
"dagre": "0.8.5",
"lit-html": "3.2.1"
},
"peerDependencies": {},
"repository": {
Expand Down
4 changes: 2 additions & 2 deletions packages/graph/src/graph2/dataGraph.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { PropertyExt, Widget } from "@hpcc-js/common";
import { Vertex3, CentroidVertex3, Vertex3Props, EdgeProps, SubgraphProps } from "@hpcc-js/react";
import { compare2 } from "@hpcc-js/util";
import { Graph2 } from "./graph.ts";
import { GraphReact } from "./graphReact.ts";
import { HierarchyBase } from "./layouts/placeholders.ts";

// Backward compatibility layer ---
Expand Down Expand Up @@ -40,7 +40,7 @@ export interface AnnotationColumn {
AnnotationColumn.prototype.publish("columnID", "", "set", "Annotation column (boolean)", function (this: AnnotationColumn) { return this._owner.vertexColumns(); });
AnnotationColumn.prototype.publish("annotationID", "", "string", "Annotation ID");

export class DataGraph extends Graph2 {
export class DataGraph extends GraphReact {

constructor() {
super();
Expand Down
23 changes: 11 additions & 12 deletions packages/graph/src/graph2/graph.css
Original file line number Diff line number Diff line change
@@ -1,34 +1,33 @@
.graph_Graph2 .graphVertex {
.graph_GraphT .graphVertex {
cursor: pointer;
}


.graph_Graph2 .allowDragging .graphVertex {
.graph_GraphT .allowDragging .graphVertex {
cursor: pointer;
}

.graph_Graph2 .allowDragging .graphVertex.grabbed {
.graph_GraphT .allowDragging .graphVertex.grabbed {
cursor: grabbing;
}

.graph_Graph2 .graphEdge {
.graph_GraphT .graphEdge {
stroke: darkgray;
fill: none;
}

.graph_Graph2 .graphEdge > text {
.graph_GraphT .graphEdge>text {
stroke: none;
fill: black;
}

.graph_Graph2 .graphEdge.hide-text > text {
.graph_GraphT .graphEdge.hide-text>text {
display: none;
}

.graph_Graph2 g.selected rect {
stroke:red !important;
.graph_GraphT g.selected rect {
stroke: red !important;
}

.graph_Graph2 g.selected circle {
stroke:red !important;
}
.graph_GraphT g.selected circle {
stroke: red !important;
}
22 changes: 22 additions & 0 deletions packages/graph/src/graph2/graphHtmlT.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { html, svg, render, HTMLTemplateResult, SVGTemplateResult } from "lit-html";
import { EdgeBaseProps, GraphT, RendererT, SubgraphBaseProps, VertexBaseProps } from "./graphT.ts";

export { html, svg };

type TemplateResult = HTMLTemplateResult | SVGTemplateResult;

export type Component<T> = (props: T) => TemplateResult;

export function adapter<T>(component: Component<T>): RendererT<T> {
return (props: T, element: SVGGElement) => {
render(component(props), element as any);
};
}

export class GraphHtmlT<SG extends SubgraphBaseProps, V extends VertexBaseProps, E extends EdgeBaseProps<V>> extends GraphT<SG, V, E> {

constructor(subgraphRenderer: Component<SG>, vertexRenderer: Component<V>, edgeRenderer: Component<E>) {
super(adapter(subgraphRenderer), adapter(vertexRenderer), adapter(edgeRenderer));
}
}
GraphHtmlT.prototype._class += " graph_GraphHtmlT";
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export type IEdge = EdgeProps;
export type IHierarchy = HierarchyBase<ISubgraph, IVertex>;
export type IGraphData2 = GraphDataProps<ISubgraph, IVertex, IEdge>;

export class Graph2 extends GraphReactT<ISubgraph, IVertex, IEdge> {
export class GraphReact extends GraphReactT<ISubgraph, IVertex, IEdge> {

constructor() {
super(Subgraph, Vertex, Edge);
Expand Down Expand Up @@ -76,9 +76,9 @@ export class Graph2 extends GraphReactT<ISubgraph, IVertex, IEdge> {
this._centroidFilter.update(this.centroidColor());
}
}
Graph2.prototype._class += " graph_Graph2";
GraphReact.prototype._class += " graph_React";

export interface Graph2 {
export interface GraphReact {
vertexTextHeight(): number;
vertexTextHeight(_: number): this;
vertexTextPadding(): number;
Expand Down Expand Up @@ -114,21 +114,22 @@ export interface Graph2 {
centroidLabelFontFamily(_: string): this;
}

Graph2.prototype.publish("vertexTextHeight", 10, "number", "Vertex Text Height");
Graph2.prototype.publish("vertexTextPadding", 4, "number", "Vertex Text Padding");
Graph2.prototype.publish("vertexIconHeight", 50, "number", "Vertex Icon Height");
Graph2.prototype.publish("vertexIconPadding", 10, "number", "Vertex Icon Padding");
Graph2.prototype.publish("vertexIconStrokeWidth", 0, "number", "Vertex Icon Stroke Width");
Graph2.prototype.publish("vertexIconFontFamily", "FontAwesome", "string", "Vertex Icon Font Family");
Graph2.prototype.publish("vertexLabelFontFamily", "Verdana", "string", "Vertex Label Font Family");
GraphReact.prototype.publish("vertexTextHeight", 10, "number", "Vertex Text Height");
GraphReact.prototype.publish("vertexTextPadding", 4, "number", "Vertex Text Padding");
GraphReact.prototype.publish("vertexIconHeight", 50, "number", "Vertex Icon Height");
GraphReact.prototype.publish("vertexIconPadding", 10, "number", "Vertex Icon Padding");
GraphReact.prototype.publish("vertexIconStrokeWidth", 0, "number", "Vertex Icon Stroke Width");
GraphReact.prototype.publish("vertexIconFontFamily", "FontAwesome", "string", "Vertex Icon Font Family");
GraphReact.prototype.publish("vertexLabelFontFamily", "Verdana", "string", "Vertex Label Font Family");

Graph2.prototype.publish("centroidColor", "#00A000", "html-color", "Centroid Glow Color");
Graph2.prototype.publish("centroidScale", 1, "number", "Centroid Scale");
Graph2.prototype.publish("centroidTextHeight", 12, "number", "Centroid Text Height");
Graph2.prototype.publish("centroidTextPadding", 4, "number", "Centroid Text Padding");
Graph2.prototype.publish("centroidIconHeight", 50, "number", "Centroid Icon Height");
Graph2.prototype.publish("centroidIconPadding", 10, "number", "Centroid Icon Padding");
Graph2.prototype.publish("centroidIconStrokeWidth", 4, "number", "Centroid Icon Stroke Width");
Graph2.prototype.publish("centroidIconFontFamily", "FontAwesome", "string", "Centroid Icon Font Family");
Graph2.prototype.publish("centroidLabelFontFamily", "Verdana", "string", "Centroid Label Font Family");
GraphReact.prototype.publish("centroidColor", "#00A000", "html-color", "Centroid Glow Color");
GraphReact.prototype.publish("centroidScale", 1, "number", "Centroid Scale");
GraphReact.prototype.publish("centroidTextHeight", 12, "number", "Centroid Text Height");
GraphReact.prototype.publish("centroidTextPadding", 4, "number", "Centroid Text Padding");
GraphReact.prototype.publish("centroidIconHeight", 50, "number", "Centroid Icon Height");
GraphReact.prototype.publish("centroidIconPadding", 10, "number", "Centroid Icon Padding");
GraphReact.prototype.publish("centroidIconStrokeWidth", 4, "number", "Centroid Icon Stroke Width");
GraphReact.prototype.publish("centroidIconFontFamily", "FontAwesome", "string", "Centroid Icon Font Family");
GraphReact.prototype.publish("centroidLabelFontFamily", "Verdana", "string", "Centroid Label Font Family");

export const Graph2 = GraphReact;
3 changes: 2 additions & 1 deletion packages/graph/src/graph2/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export * from "./graphT.ts";
export * from "./graphReactT.ts";
export * from "./graph.ts";
export * from "./graphReact.ts";
export * from "./graphHtmlT.ts";
export * from "./dataGraph.ts";
export * from "./sankeyGraph.ts";
export * from "./subgraph.tsx";
Expand Down

0 comments on commit d9f5bbc

Please sign in to comment.