Skip to content

Commit

Permalink
fix(graph): Tweak previous refactor to ensure backward compatibility
Browse files Browse the repository at this point in the history
Signed-off-by: Gordon Smith <[email protected]>
  • Loading branch information
GordonSmith committed Nov 10, 2022
1 parent b5b4cf9 commit 0c86fbb
Show file tree
Hide file tree
Showing 15 changed files with 117 additions and 136 deletions.
2 changes: 1 addition & 1 deletion packages/graph/src/__tests__/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { Test5 as Test } from "./test5";
export { Test4 as Test } from "./test4";
16 changes: 9 additions & 7 deletions packages/graph/src/graph2/dataGraph.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { PropertyExt, publish, Widget } from "@hpcc-js/common";
import { CentroidVertex3, IVertex3, SubgraphProps, Vertex3 } from "@hpcc-js/react";
import { Vertex3, CentroidVertex3, Vertex3Props, EdgeProps, SubgraphProps } from "@hpcc-js/react";
import { compare2 } from "@hpcc-js/util";
import { Graph2 } from "./graph";
import { HierarchyBase } from "./layouts/placeholders";
import { BasicEdgeProps } from "./edge";

// Backward compatibility layer ---
export type IVertex3 = Vertex3Props;

export function toJsonObj<T>(row, columns): T {
const retVal: T = {} as T;
Expand Down Expand Up @@ -206,9 +208,9 @@ export class DataGraph extends Graph2 {
this._prevVertices = vertices;
}

protected _prevEdges: readonly BasicEdgeProps[] = [];
protected _masterEdges: BasicEdgeProps[] = [];
private _masterEdgesMap: { [key: string]: BasicEdgeProps } = {};
protected _prevEdges: readonly EdgeProps<IVertex3>[] = [];
protected _masterEdges: EdgeProps<IVertex3>[] = [];
private _masterEdgesMap: { [key: string]: EdgeProps<IVertex3> } = {};
mergeEdges() {
const columns = this.edgeColumns();
const idIdx = this.indexOf(columns, this.edgeIDColumn(), "id");
Expand All @@ -217,7 +219,7 @@ export class DataGraph extends Graph2 {
const labelIdx = this.indexOf(columns, this.edgeLabelColumn(), "label");
const weightIdx = this.indexOf(columns, this.edgeWeightColumn(), "weight");
const colorIdx = this.indexOf(columns, this.edgeColorColumn(), "color");
const edges: BasicEdgeProps[] = this.edges().map((e): BasicEdgeProps => {
const edges: EdgeProps<IVertex3>[] = this.edges().map((e): EdgeProps<IVertex3> => {
const source = this._masterVerticesMap["" + e[sourceIdx]];
if (!source) console.error(`Invalid edge source entity "${e[sourceIdx]}" does not exist.`);
const target = this._masterVerticesMap["" + e[targetIdx]];
Expand All @@ -227,7 +229,7 @@ export class DataGraph extends Graph2 {
source,
target,
weight: +e[weightIdx] || 1,
color: e[colorIdx] as string,
stroke: e[colorIdx] as string,
label: labelIdx >= 0 ? ("" + e[labelIdx]) : "",
origData: toJsonObj(e, columns),
labelPos: [0, 0],
Expand Down
30 changes: 0 additions & 30 deletions packages/graph/src/graph2/edge.tsx

This file was deleted.

16 changes: 12 additions & 4 deletions packages/graph/src/graph2/graph.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import { React, Subgraph, SubgraphProps, Vertex, VertexProps } from "@hpcc-js/react";
import { BasicEdge, BasicEdgeProps } from "./edge";
import { React, Subgraph, SubgraphProps, Vertex, VertexProps, Edge, EdgeProps } from "@hpcc-js/react";
// import { IVertexEdgeProps, VertexEdge } from "./edge";
import { GraphReactT } from "./graphReactT";
import { GraphDataProps, HierarchyBase } from "./graphT";

export class Graph2 extends GraphReactT<SubgraphProps, VertexProps, BasicEdgeProps> {
// Backward compatibility layer ---
export type ISubgraph = SubgraphProps;
export type IVertex = VertexProps;
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> {

constructor() {
super(Subgraph, Vertex, BasicEdge);
super(Subgraph, Vertex, Edge);
this._reactCentroidRenderer = Vertex;
this._reactVertexRenderer2 = Vertex;
super.vertexRenderer((props) => {
Expand Down
6 changes: 3 additions & 3 deletions packages/graph/src/graph2/graphReactT.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { render, React, SubgraphProps, VertexProps } from "@hpcc-js/react";
import { EdgeProps, GraphT, RendererT } from "./graphT";
import { render, React, SubgraphProps, VertexProps, EdgeProps } from "@hpcc-js/react";
import { GraphT, RendererT } from "./graphT";

function adapter<T>(reactRenderer: React.FunctionComponent<T>): RendererT<T> {
return (props: T, element: SVGGElement) => render(reactRenderer, props, element);
}

export class GraphReactT<SG extends SubgraphProps, V extends VertexProps, E extends EdgeProps> extends GraphT<SG, V, E> {
export class GraphReactT<SG extends SubgraphProps, V extends VertexProps, E extends EdgeProps<V>> extends GraphT<SG, V, E> {

constructor(subgraphRenderer: React.FunctionComponent<SG>, vertexRenderer: React.FunctionComponent<V>, edgeRenderer: React.FunctionComponent<E>) {
super(adapter(subgraphRenderer), adapter(vertexRenderer), adapter(edgeRenderer));
Expand Down
46 changes: 23 additions & 23 deletions packages/graph/src/graph2/graphT.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import "d3-transition";
import { interpolatePath as d3InterpolatePath } from "d3-interpolate-path";
import { Circle, Dagre, ForceDirected, ForceDirectedAnimated, Graphviz, ILayout, Null } from "./layouts/index";
import { Options as FDOptions } from "./layouts/forceDirectedWorker";
import type { VertexProps, EdgeProps, IGraphData2, HierarchyBase, SubgraphProps } from "./layouts/placeholders";
import type { VertexBaseProps, EdgeBaseProps, GraphDataProps, HierarchyBase, SubgraphBaseProps } from "./layouts/placeholders";
import { EdgePlaceholder, SubgraphPlaceholder, VertexPlaceholder, isEdgePlaceholder } from "./layouts/placeholders";
import { Engine, graphviz as gvWorker } from "./layouts/graphvizWorker";
import { Tree, RadialTree, Dendrogram, RadialDendrogram } from "./layouts/tree";
Expand All @@ -18,25 +18,25 @@ let scriptDir = (globalThis?.document?.currentScript as HTMLScriptElement)?.src
scriptDir = scriptDir.substring(0, scriptDir.replace(/[?#].*/, "").lastIndexOf("/") + 1);

export {
IGraphData2,
SubgraphProps,
VertexProps,
EdgeProps,
GraphDataProps,
SubgraphBaseProps,
VertexBaseProps,
EdgeBaseProps,
HierarchyBase
};

type GraphLayoutType = "Hierarchy" | "DOT" | "Tree" | "Dendrogram" | "RadialTree" | "RadialDendrogram" | "ForceDirected" | "ForceDirected2" | "ForceDirectedHybrid" | "Neato" | "FDP" | "Circle" | "TwoPI" | "Circo" | "None";
const GraphLayoutTypeSet = ["Hierarchy", "DOT", "Tree", "Dendrogram", "RadialTree", "RadialDendrogram", "ForceDirected", "ForceDirected2", "ForceDirectedHybrid", "Neato", "FDP", "Circle", "TwoPI", "Circo", "None"];

function dragStart<V extends VertexProps>(n: VertexPlaceholder<V>) {
function dragStart<V extends VertexBaseProps>(n: VertexPlaceholder<V>) {
n.fx = n.sx = n.x;
n.fy = n.sy = n.y;
}
function dragTick(n: VertexPlaceholder<VertexProps>, d: VertexPlaceholder<VertexProps>) {
function dragTick(n: VertexPlaceholder<VertexBaseProps>, d: VertexPlaceholder<VertexBaseProps>) {
n.fx = n.sx + d.fx - d.sx;
n.fy = n.sy + d.fy - d.sy;
}
function dragEnd<V extends VertexProps>(n: VertexPlaceholder<V>) {
function dragEnd<V extends VertexBaseProps>(n: VertexPlaceholder<V>) {
n.x = n.fx;
n.y = n.fy;
n.fx = n.sx = undefined;
Expand All @@ -45,7 +45,7 @@ function dragEnd<V extends VertexProps>(n: VertexPlaceholder<V>) {

export type RendererT<T> = (props: T, element: SVGGElement) => void;

export class GraphT<SG extends SubgraphProps, V extends VertexProps, E extends EdgeProps> extends SVGZoomWidget {
export class GraphT<SG extends SubgraphBaseProps, V extends VertexBaseProps, E extends EdgeBaseProps<V>> extends SVGZoomWidget {

protected _centroidFilter: SVGGlowFilter;

Expand All @@ -63,11 +63,11 @@ export class GraphT<SG extends SubgraphProps, V extends VertexProps, E extends E
private _toggleD = new ToggleButton().faChar("fa-sitemap fa-rotate-270").tooltip("Dendrogram").on("click", () => this.layoutClick("Dendrogram"));
private _toggleRD = new ToggleButton().faChar("fa-asterisk").tooltip("Radial Dendrogram").on("click", () => this.layoutClick("RadialDendrogram"));

protected _graphData = new GraphCollection<VertexPlaceholder<V>, EdgePlaceholder<E, V>, SubgraphPlaceholder<SG>>()
protected _graphData = new GraphCollection<VertexPlaceholder<V>, EdgePlaceholder<V, E>, SubgraphPlaceholder<SG>>()
.idFunc(d => d.id)
.sourceFunc(e => e.source.id)
.targetFunc(e => e.target.id)
.updateFunc((b: VertexPlaceholder<V> | EdgePlaceholder<E, V> | SubgraphPlaceholder<SG>, a: VertexPlaceholder<V> | EdgePlaceholder<E, V> | SubgraphPlaceholder<SG>) => {
.updateFunc((b: VertexPlaceholder<V> | EdgePlaceholder<V, E> | SubgraphPlaceholder<SG>, a: VertexPlaceholder<V> | EdgePlaceholder<V, E> | SubgraphPlaceholder<SG>) => {
b.props = a.props;
if (isEdgePlaceholder(a) && isEdgePlaceholder(b)) {
b.source = a.source;
Expand Down Expand Up @@ -259,15 +259,15 @@ export class GraphT<SG extends SubgraphProps, V extends VertexProps, E extends E
return this;
}

private _origData: IGraphData2<SG, V, E> = {
private _origData: GraphDataProps<SG, V, E> = {
subgraphs: [],
vertices: [],
edges: [],
hierarchy: []
};
data(): IGraphData2<SG, V, E>;
data(_: IGraphData2<SG, V, E>, merge?: boolean): this;
data(_?: IGraphData2<SG, V, E>, merge?: boolean): IGraphData2<SG, V, E> | this {
data(): GraphDataProps<SG, V, E>;
data(_: GraphDataProps<SG, V, E>, merge?: boolean): this;
data(_?: GraphDataProps<SG, V, E>, merge?: boolean): GraphDataProps<SG, V, E> | this {
if (_ === void 0) return this._origData;
this._origData = _;

Expand Down Expand Up @@ -325,7 +325,7 @@ export class GraphT<SG extends SubgraphProps, V extends VertexProps, E extends E
return this;
}

graphData(): GraphCollection<VertexPlaceholder<V>, EdgePlaceholder<E, V>> {
graphData(): GraphCollection<VertexPlaceholder<V>, EdgePlaceholder<V, E>> {
return this._graphData;
}

Expand Down Expand Up @@ -509,7 +509,7 @@ export class GraphT<SG extends SubgraphProps, V extends VertexProps, E extends E

highlightEdges(edgeMap?: { [id: string]: boolean }) {
const context = this;
const edgeElements = this._edgeG.selectAll<SVGGElement, EdgePlaceholder<E, V>>(".graphEdge");
const edgeElements = this._edgeG.selectAll<SVGGElement, EdgePlaceholder<V, E>>(".graphEdge");
edgeElements
.classed("graphEdge-highlighted", d => !edgeMap || edgeMap[d.id])
.style("stroke-width", function (o) {
Expand Down Expand Up @@ -543,7 +543,7 @@ export class GraphT<SG extends SubgraphProps, V extends VertexProps, E extends E
}
}

highlightEdge(_element, d?: EdgePlaceholder<E, V>) {
highlightEdge(_element, d?: EdgePlaceholder<V, E>) {
if (this.highlightOnMouseOverEdge()) {
if (d) {
const vertices = {};
Expand Down Expand Up @@ -577,7 +577,7 @@ export class GraphT<SG extends SubgraphProps, V extends VertexProps, E extends E
return this;
}

moveEdgePlaceholder(ep: EdgePlaceholder<E, V>, transition: boolean): this {
moveEdgePlaceholder(ep: EdgePlaceholder<V, E>, transition: boolean): this {
const edgeLayout = {
...this._layoutAlgo.edgePath(ep, this.edgeArcDepth())
};
Expand All @@ -594,7 +594,7 @@ export class GraphT<SG extends SubgraphProps, V extends VertexProps, E extends E
path: pathInterpolator(t),
labelPos: labelPosInterpolator(t),
strokeWidth: ep.props.strokeWidth ?? context.edgeStrokeWidth(),
color: ep.props.color ?? context.edgeColor()
color: ep.props.stroke ?? context.edgeColor()
};
context._edgeRenderer({ ...edgeLayout, ...ep.props, ...updated }, ep.element.node());
};
Expand All @@ -605,7 +605,7 @@ export class GraphT<SG extends SubgraphProps, V extends VertexProps, E extends E

moveVertexPlaceholder(vp: VertexPlaceholder<V>, transition: boolean, moveNeighbours: boolean): this {
const { x, y } = this.projectPlacholder(vp);
vp.element && (transition ? vp.element.transition().duration(this.transitionDuration()) as unknown as Selection<SVGPathElement, EdgePlaceholder<E, V>, SVGGElement, any> : vp.element)
vp.element && (transition ? vp.element.transition().duration(this.transitionDuration()) as unknown as Selection<SVGPathElement, EdgePlaceholder<V, E>, SVGGElement, any> : vp.element)
.attr("transform", `translate(${x} ${y})`)
;
if (moveNeighbours) {
Expand Down Expand Up @@ -695,7 +695,7 @@ export class GraphT<SG extends SubgraphProps, V extends VertexProps, E extends E
updateEdges(): this {
const context = this;
this._edgeG.selectAll(".graphEdge")
.data(this._graphData.allEdges(), (d: EdgePlaceholder<E, V>) => d.id)
.data(this._graphData.allEdges(), (d: EdgePlaceholder<V, E>) => d.id)
.join(
enter => enter.append("g")
.attr("class", "graphEdge")
Expand Down Expand Up @@ -1168,7 +1168,7 @@ export class GraphT<SG extends SubgraphProps, V extends VertexProps, E extends E
}
GraphT.prototype._class += " graph_GraphT";

export interface GraphT<SG extends SubgraphProps = any, V extends VertexProps = any, E extends EdgeProps = any> {
export interface GraphT<SG extends SubgraphBaseProps = any, V extends VertexBaseProps = any, E extends EdgeBaseProps<V> = any> {
allowDragging(): boolean;
allowDragging(_: boolean): this;
dragSingleNeighbors(): boolean;
Expand Down
1 change: 0 additions & 1 deletion packages/graph/src/graph2/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ export * from "./dataGraph";
export * from "./sankeyGraph";
export * from "./subgraph";
export * from "./vertex";
export * from "./edge";
30 changes: 15 additions & 15 deletions packages/graph/src/graph2/layouts/placeholders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export interface BaseProps {
origData?: any;
}

export interface VertexProps extends BaseProps {
export interface VertexBaseProps extends BaseProps {
text: string;
categoryID?: string;
centroid?: boolean;
Expand All @@ -14,40 +14,40 @@ export interface VertexProps extends BaseProps {
annotationIDs?: string[];
}

export interface SubgraphProps extends BaseProps {
export interface SubgraphBaseProps extends BaseProps {
text: string;
width?: number;
height?: number;
}

export type Point = [number, number];

export interface EdgeProps extends BaseProps {
source: VertexProps;
target: VertexProps;
export interface EdgeBaseProps<V extends VertexBaseProps = VertexBaseProps> extends BaseProps {
source: V;
target: V;
label?: string;
labelPos?: Point;
weight?: number;
strokeDasharray?: string;
strokeWidth?: number;
color?: string;
stroke?: string;
fontFamily?: string;
}

export interface HierarchyBase<SG extends SubgraphProps, V extends VertexProps> {
export interface HierarchyBase<SG extends SubgraphBaseProps, V extends VertexBaseProps> {
id: string | number;
parent: SG;
child: SG | V;
}

export interface IGraphData2<SG extends SubgraphProps, V extends VertexProps, E extends EdgeProps> {
export interface GraphDataProps<SG extends SubgraphBaseProps, V extends VertexBaseProps, E extends EdgeBaseProps<V>> {
subgraphs?: SG[];
vertices: V[];
edges: E[];
hierarchy?: HierarchyBase<SG, V>[];
}

export interface SubgraphPlaceholder<SG extends SubgraphProps = SubgraphProps> {
export interface SubgraphPlaceholder<SG extends SubgraphBaseProps = SubgraphBaseProps> {
id: string | number;
element?: Selection<SVGGElement, SubgraphPlaceholder<SG>, SVGGElement, any>;
props: SG;
Expand All @@ -57,7 +57,7 @@ export interface SubgraphPlaceholder<SG extends SubgraphProps = SubgraphProps> {
y?: number; // The node’s current y-position
}

export interface VertexPlaceholder<V extends VertexProps = VertexProps> {
export interface VertexPlaceholder<V extends VertexBaseProps = VertexBaseProps> {
id: string | number;
element?: Selection<SVGGElement, VertexPlaceholder<V>, SVGGElement, any>;
props: V;
Expand All @@ -82,11 +82,11 @@ export interface VertexPlaceholder<V extends VertexProps = VertexProps> {
lng?: number;
}

export interface EdgePlaceholder<E extends EdgeProps = EdgeProps, V extends VertexProps = VertexProps> {
export interface EdgePlaceholder<V extends VertexBaseProps = VertexBaseProps, E extends EdgeBaseProps<V> = EdgeBaseProps<V>> {
id: string | number;
element?: Selection<SVGGElement, EdgePlaceholder<E, V>, SVGGElement, any>;
elementPath?: Selection<SVGPathElement, EdgePlaceholder<E, V>, SVGGElement, any>;
elementText?: Selection<SVGTextElement, EdgePlaceholder<E, V>, SVGGElement, any>;
element?: Selection<SVGGElement, EdgePlaceholder<V, E>, SVGGElement, any>;
elementPath?: Selection<SVGPathElement, EdgePlaceholder<V, E>, SVGGElement, any>;
elementText?: Selection<SVGTextElement, EdgePlaceholder<V, E>, SVGGElement, any>;
props: E;
source: VertexPlaceholder<V>; // The link’s source node
target: VertexPlaceholder<V>; // The link’s target node
Expand All @@ -98,6 +98,6 @@ export interface EdgePlaceholder<E extends EdgeProps = EdgeProps, V extends Vert
points?: Array<[number, number]>;
}

export function isEdgePlaceholder<E extends EdgeProps = EdgeProps, V extends VertexProps = VertexProps>(item): item is EdgePlaceholder<E, V> {
export function isEdgePlaceholder<V extends VertexBaseProps = VertexBaseProps, E extends EdgeBaseProps<V> = EdgeBaseProps<V>>(item): item is EdgePlaceholder<V, E> {
return item.id !== undefined && item.props !== undefined && item.source !== undefined && item.target !== undefined;
}
Loading

0 comments on commit 0c86fbb

Please sign in to comment.