Skip to content

Commit

Permalink
Fixed #219 of upstream. Can now render multiple graphs at the same time.
Browse files Browse the repository at this point in the history
  • Loading branch information
ajbogh committed Jul 17, 2020
1 parent 9701747 commit 94bd652
Show file tree
Hide file tree
Showing 17 changed files with 514 additions and 646 deletions.
61 changes: 35 additions & 26 deletions __tests__/components/edge.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,18 +252,20 @@ describe('Edge component', () => {
return rect;
});

document.querySelector = jest.fn().mockImplementation(selector => {
return {
getBoundingClientRect: boundingClientRectMock,
};
});
const viewWrapperElem = {
querySelector: jest.fn().mockImplementation(selector => {
return {
getBoundingClientRect: boundingClientRectMock,
};
}),
};

const size = Edge.getArrowSize();
const size = Edge.getArrowSize(viewWrapperElem);

expect(document.querySelector).toHaveBeenCalledWith('defs>marker>.arrow');
expect(viewWrapperElem.querySelector).toHaveBeenCalledWith(
'defs>marker>.arrow'
);
expect(size).toEqual(rect);

document.querySelector.mockRestore();
});
});

Expand All @@ -280,23 +282,24 @@ describe('Edge component', () => {
Edge.getEdgePathElement(fakeEdge, viewWrapperElem);

expect(viewWrapperElem.querySelector).toHaveBeenCalledWith(
'#edge-fake1-fake2-container>.edge-container>.edge>.edge-path'
"[id='edge-fake1-fake2-container']>.edge-container>.edge>.edge-path"
);
});

it('returns the edge element from the document', () => {
document.querySelector = jest.fn();
const viewWrapperElem = {
querySelector: jest.fn(),
};
const fakeEdge = {
source: 'fake1',
target: 'fake2',
};

Edge.getEdgePathElement(fakeEdge);
Edge.getEdgePathElement(fakeEdge, viewWrapperElem);

expect(document.querySelector).toHaveBeenCalledWith(
'#edge-fake1-fake2-container>.edge-container>.edge>.edge-path'
expect(viewWrapperElem.querySelector).toHaveBeenCalledWith(
"[id='edge-fake1-fake2-container']>.edge-container>.edge>.edge-path"
);
document.querySelector.mockRestore();
});
});

Expand Down Expand Up @@ -744,7 +747,7 @@ describe('Edge component', () => {
}),
};

document.getElementById = jest.fn().mockImplementation(() => {
viewWrapperElem.querySelector = jest.fn().mockImplementation(() => {
return node;
});

Expand All @@ -758,10 +761,10 @@ describe('Edge component', () => {
);
const expected = defaultExpected;

expect(document.getElementById).toHaveBeenCalledWith('node-test2');
expect(viewWrapperElem.querySelector).toHaveBeenCalledWith(
"[id='node-test2']"
);
expect(JSON.stringify(result)).toEqual(JSON.stringify(expected));

document.getElementById.mockRestore();
});

it('returns a default response when there is no xlinkHref', () => {
Expand All @@ -776,7 +779,7 @@ describe('Edge component', () => {
}),
};

document.getElementById = jest.fn().mockImplementation(() => {
viewWrapperElem.querySelector = jest.fn().mockImplementation(() => {
return node;
});

Expand All @@ -790,14 +793,14 @@ describe('Edge component', () => {
);
const expected = defaultExpected;

expect(document.getElementById).toHaveBeenCalledWith('node-test2');
expect(viewWrapperElem.querySelector).toHaveBeenCalledWith(
"[id='node-test2']"
);
expect(trgNode.getAttributeNS).toHaveBeenCalledWith(
'http://www.w3.org/1999/xlink',
'href'
);
expect(JSON.stringify(result)).toEqual(JSON.stringify(expected));

document.getElementById.mockRestore();
});

it('gets a response for a rect element', () => {
Expand All @@ -812,7 +815,15 @@ describe('Edge component', () => {
}),
};

document.getElementById = jest.fn().mockImplementation(() => {
let callNumber = 0;

viewWrapperElem.querySelector = jest.fn().mockImplementation(() => {
if (callNumber === 1) {
return rectElement;
}

callNumber = 1;

return node;
});

Expand All @@ -834,8 +845,6 @@ describe('Edge component', () => {
};

expect(JSON.stringify(result)).toEqual(JSON.stringify(expected));

document.getElementById.mockRestore();
});
});
});
62 changes: 54 additions & 8 deletions __tests__/components/graph-view.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,16 @@ describe('GraphView component', () => {
target: 'b',
};

const querySelectorResponse = undefined;

instance.viewWrapper = {
current: {
querySelector: jest.fn().mockImplementation(selector => {
return querySelectorResponse;
}),
},
};

// using Date.getTime to make this a unique edge
instance.renderEdge(`test-${new Date().getTime()}`, element, edge);

Expand All @@ -347,17 +357,23 @@ describe('GraphView component', () => {
const container = document.createElement('g');

container.id = 'test-container';
jest.spyOn(document, 'getElementById').mockReturnValue(container);
const edge = {
source: 'a',
target: 'b',
};

instance.viewWrapper = {
current: {
querySelector: jest.fn().mockImplementation(selector => {
return container;
}),
},
};

instance.renderEdge('test', element, edge);

expect(instance.entities.appendChild).not.toHaveBeenCalled();
expect(ReactDOM.render).toHaveBeenCalledWith(element, container);
document.getElementById.mockRestore();
});
});

Expand Down Expand Up @@ -565,6 +581,16 @@ describe('GraphView component', () => {
it('appends a node element into the entities element', () => {
const element = document.createElement('g');

const querySelectorResponse = undefined;

instance.viewWrapper = {
current: {
querySelector: jest.fn().mockImplementation(selector => {
return querySelectorResponse;
}),
},
};

instance.renderNode('test', element);

expect(instance.entities.appendChild).toHaveBeenCalled();
Expand All @@ -575,12 +601,19 @@ describe('GraphView component', () => {
const container = document.createElement('g');

container.id = 'test-container';
jest.spyOn(document, 'getElementById').mockReturnValue(container);

instance.viewWrapper = {
current: {
querySelector: jest.fn().mockImplementation(selector => {
return container;
}),
},
};

instance.renderNode('test', element);

expect(instance.entities.appendChild).not.toHaveBeenCalled();
expect(ReactDOM.render).toHaveBeenCalledWith(element, container);
document.getElementById.mockRestore();
});
});

Expand Down Expand Up @@ -861,6 +894,14 @@ describe('GraphView component', () => {
});

it('handles the zoom event when a node is not hovered nor an edge is being dragged', () => {
instance.viewWrapper = {
current: {
querySelector: jest.fn().mockImplementation(selector => {
return {};
}),
},
};

instance.handleZoom(event);
expect(instance.renderGraphControls).toHaveBeenCalled();
expect(instance.dragEdge).not.toHaveBeenCalled();
Expand All @@ -885,6 +926,14 @@ describe('GraphView component', () => {
});

it('zooms when a node is hovered', () => {
instance.viewWrapper = {
current: {
querySelector: jest.fn().mockImplementation(selector => {
return {};
}),
},
};

output.setState({
hoveredNode: {},
});
Expand All @@ -907,10 +956,7 @@ describe('GraphView component', () => {
instance.selectedView = d3.select(document.createElement('g'));
mouse = jest.fn().mockReturnValue([5, 15]);
output.setProps({
nodes: [
{ id: 'a', x: 5, y: 10 },
{ id: 'b', x: 10, y: 20 },
],
nodes: [{ id: 'a', x: 5, y: 10 }, { id: 'b', x: 10, y: 20 }],
});
output.setState({
draggedEdge,
Expand Down
25 changes: 12 additions & 13 deletions src/components/edge.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,7 @@ class Edge extends React.Component<IEdgeProps> {
})(srcTrgDataArray);
}

static getArrowSize(
viewWrapperElem: HTMLDivElement | HTMLDocument = document
) {
static getArrowSize(viewWrapperElem: HTMLDivElement) {
const defEndArrowElement: any = viewWrapperElem.querySelector(
`defs>marker>.arrow`
);
Expand All @@ -106,12 +104,9 @@ class Edge extends React.Component<IEdgeProps> {
return size;
}

static getEdgePathElement(
edge: IEdge,
viewWrapperElem: HTMLDivElement | HTMLDocument = document
) {
static getEdgePathElement(edge: IEdge, viewWrapperElem: HTMLDivElement) {
return viewWrapperElem.querySelector(
`#edge-${edge.source}-${edge.target}-container>.edge-container>.edge>.edge-path`
`[id='edge-${edge.source}-${edge.target}-container']>.edge-container>.edge>.edge-path`
);
}

Expand Down Expand Up @@ -162,7 +157,7 @@ class Edge extends React.Component<IEdgeProps> {
src: any,
trg: any,
includesArrow: boolean,
viewWrapperElem: HTMLDivElement | HTMLDocument = document
viewWrapperElem: HTMLDivElement
) {
const response = Edge.getDefaultIntersectResponse();
const arrowSize = Edge.getArrowSize(viewWrapperElem);
Expand Down Expand Up @@ -262,7 +257,7 @@ class Edge extends React.Component<IEdgeProps> {
src: any,
trg: any,
includesArrow?: boolean = true,
viewWrapperElem: HTMLDivElement | HTMLDocument = document
viewWrapperElem: HTMLDivElement
) {
const response = Edge.getDefaultIntersectResponse();
const arrowSize = Edge.getArrowSize(viewWrapperElem);
Expand Down Expand Up @@ -366,7 +361,7 @@ class Edge extends React.Component<IEdgeProps> {
src: any,
trg: any,
includesArrow?: boolean = true,
viewWrapperElem: HTMLDivElement | HTMLDocument = document
viewWrapperElem: HTMLDivElement
) {
const response = Edge.getDefaultIntersectResponse();
const arrowSize = Edge.getArrowSize(viewWrapperElem);
Expand Down Expand Up @@ -426,7 +421,7 @@ class Edge extends React.Component<IEdgeProps> {
trg: any,
nodeKey: string,
includesArrow?: boolean = true,
viewWrapperElem?: HTMLDivElement = document
viewWrapperElem: React.RefObject<HTMLDivElement>
) {
let response = Edge.getDefaultIntersectResponse();

Expand All @@ -437,7 +432,11 @@ class Edge extends React.Component<IEdgeProps> {
// Note: document.getElementById is by far the fastest way to get a node.
// compare 2.82ms for querySelector('#node-a2 use.node') vs
// 0.31ms and 99us for document.getElementById()
const nodeElem = document.getElementById(`node-${trg[nodeKey]}`);
// Although it doesn't allow multiple graphs.
// We can use viewWrapperElem to scope the querySelector to a smaller set of elements to improve the speed
const nodeElem = viewWrapperElem.querySelector(
`[id='node-${trg[nodeKey]}']`
);

if (!nodeElem) {
return response;
Expand Down
Loading

0 comments on commit 94bd652

Please sign in to comment.