Skip to content

Commit fc25423

Browse files
committed
Add matrix and arc diagram
* matrix and arc options for networkFrame * decorate generated lines/points with rIndex, oIndex, xIndex, yIndex, lineIndex where appropriate
1 parent 554b78d commit fc25423

File tree

6 files changed

+275
-26
lines changed

6 files changed

+275
-26
lines changed

src/components/NetworkFrame.js

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,12 @@ import {
3030
drawEdges,
3131
topologicalSort,
3232
hierarchicalRectNodeGenerator,
33+
matrixNodeGenerator,
3334
radialRectNodeGenerator,
3435
chordNodeGenerator,
3536
chordEdgeGenerator,
37+
matrixEdgeGenerator,
38+
arcEdgeGenerator,
3639
sankeyNodeGenerator,
3740
wordcloudNodeGenerator,
3841
circleNodeGenerator,
@@ -182,7 +185,7 @@ const customEdgeHashMutate = {
182185
}
183186
*/
184187

185-
function determineNodeIcon(baseCustomNodeIcon, networkSettings, size) {
188+
function determineNodeIcon(baseCustomNodeIcon, networkSettings, size, nodes) {
186189
if (baseCustomNodeIcon) return baseCustomNodeIcon
187190

188191
const center = [size[0] / 2, size[1] / 2]
@@ -206,12 +209,14 @@ function determineNodeIcon(baseCustomNodeIcon, networkSettings, size) {
206209
return chordNodeGenerator(size)
207210
case "dagre":
208211
return hierarchicalRectNodeGenerator
212+
case "matrix":
213+
return matrixNodeGenerator(size, nodes, networkSettings)
209214
}
210215

211216
return circleNodeGenerator
212217
}
213218

214-
function determineEdgeIcon(baseCustomEdgeIcon, networkSettings, size, graph) {
219+
function determineEdgeIcon({ baseCustomEdgeIcon, networkSettings, size, graph, nodes }) {
215220
if (baseCustomEdgeIcon) return baseCustomEdgeIcon
216221
switch (networkSettings.type) {
217222
case "partition":
@@ -224,6 +229,10 @@ function determineEdgeIcon(baseCustomEdgeIcon, networkSettings, size, graph) {
224229
return () => null
225230
case "chord":
226231
return chordEdgeGenerator(size)
232+
case "matrix":
233+
return matrixEdgeGenerator(size, nodes)
234+
case "arc":
235+
return arcEdgeGenerator(size)
227236
case "dagre":
228237
if (graph) return dagreEdgeGenerator(graph.graph().rankdir)
229238
}
@@ -633,18 +642,6 @@ class NetworkFrame extends React.Component<Props, State> {
633642
margin
634643
})
635644

636-
const customNodeIcon = determineNodeIcon(
637-
baseCustomNodeIcon,
638-
networkSettings,
639-
adjustedSize
640-
)
641-
const customEdgeIcon = determineEdgeIcon(
642-
baseCustomEdgeIcon,
643-
networkSettings,
644-
adjustedSize,
645-
graph
646-
)
647-
648645
networkSettings.graphSettings.nodes = nodes
649646
networkSettings.graphSettings.edges = edges
650647

@@ -858,6 +855,22 @@ class NetworkFrame extends React.Component<Props, State> {
858855
})
859856
}
860857

858+
const customNodeIcon = determineNodeIcon(
859+
baseCustomNodeIcon,
860+
networkSettings,
861+
adjustedSize,
862+
projectedNodes
863+
)
864+
865+
const customEdgeIcon = determineEdgeIcon(
866+
{ baseCustomEdgeIcon,
867+
networkSettings,
868+
size: adjustedSize,
869+
nodes: projectedNodes,
870+
graph }
871+
)
872+
873+
861874
if (
862875
(networkSettings.type === "sankey" ||
863876
networkSettings.type === "flowchart") &&
@@ -1327,6 +1340,34 @@ class NetworkFrame extends React.Component<Props, State> {
13271340
node.y = resetY(node.y)
13281341
})
13291342
})
1343+
} else if (networkSettings.type === "matrix") {
1344+
1345+
if (networkSettings.sort) {
1346+
projectedNodes = projectedNodes.sort(networkSettings.sort)
1347+
}
1348+
1349+
const gridSize = Math.min(...adjustedSize)
1350+
1351+
const stepSize = gridSize / (projectedNodes.length + 1)
1352+
1353+
projectedNodes.forEach((node, index) => {
1354+
node.x = 0
1355+
node.y = (index + 1) * stepSize
1356+
})
1357+
1358+
} else if (networkSettings.type === "arc") {
1359+
1360+
if (networkSettings.sort) {
1361+
projectedNodes = projectedNodes.sort(networkSettings.sort)
1362+
}
1363+
1364+
const stepSize = adjustedSize[0] / (projectedNodes.length + 2)
1365+
1366+
projectedNodes.forEach((node, index) => {
1367+
node.x = (index + 1) * stepSize
1368+
node.y = adjustedSize[1] / 2
1369+
})
1370+
13301371
} else if (typeof networkSettings.type === "function") {
13311372
networkSettings.type({
13321373
nodes: projectedNodes,
@@ -1341,7 +1382,7 @@ class NetworkFrame extends React.Component<Props, State> {
13411382

13421383
this.state.graphSettings.nodes = currentProps.nodes
13431384
this.state.graphSettings.edges = currentProps.edges
1344-
}
1385+
}
13451386

13461387
//filter out user-defined nodes
13471388
projectedNodes = projectedNodes.filter(filterRenderedNodes)
@@ -1383,6 +1424,7 @@ class NetworkFrame extends React.Component<Props, State> {
13831424
}
13841425
if (
13851426
networkSettings.zoom !== false &&
1427+
networkSettings.type !== "matrix" &&
13861428
networkSettings.type !== "wordcloud" &&
13871429
networkSettings.type !== "chord" &&
13881430
networkSettings.type !== "sankey" &&
@@ -1812,7 +1854,7 @@ class NetworkFrame extends React.Component<Props, State> {
18121854
downloadFields,
18131855
download,
18141856
additionalDefs,
1815-
renderOrder
1857+
renderOrder = this.state.graphSettings && this.state.graphSettings.type === "matrix" ? [ "nodes", "edges" ] : ["edges", "nodes"]
18161858
} = this.props
18171859
const {
18181860
backgroundGraphics,

src/components/data/dataFunctions.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,12 @@ export const calculateDataExtent = ({
116116
projectedLines: Array<Object> = [],
117117
projectedAreas: Array<Object> = []
118118
if (points) {
119-
xAccessor.forEach(actualXAccessor => {
120-
yAccessor.forEach(actualYAccessor => {
119+
xAccessor.forEach((actualXAccessor, xIndex) => {
120+
yAccessor.forEach((actualYAccessor, yIndex) => {
121121
points.forEach((d, i) => {
122122
const x = actualXAccessor(d, i)
123123
const y = actualYAccessor(d, i)
124-
const projectedPoint = { x, y, data: d }
124+
const projectedPoint = { x, y, data: d, xIndex, yIndex }
125125
if (Array.isArray(y)) {
126126
projectedPoint[projectedYBottom] = Math.min(...y)
127127
projectedPoint[projectedYTop] = Math.max(...y)

src/components/svg/frameFunctions.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,15 +217,17 @@ export function keyAndObjectifyBarData({
217217
rAccessor: Array<Function> | Function
218218
}): Array<Object> {
219219
const decoratedData = []
220-
oAccessor.forEach(actualOAccessor => {
221-
rAccessor.forEach(actualRAccessor => {
220+
oAccessor.forEach((actualOAccessor, oIndex) => {
221+
rAccessor.forEach((actualRAccessor, rIndex) => {
222222
;(data || []).forEach(d => {
223223
const appliedKey = renderKey(d, decoratedData.length)
224224
if (typeof d !== "object") {
225225
const expandedData = { value: d, renderKey: appliedKey }
226226
decoratedData.push({
227227
data: expandedData,
228228
value: actualRAccessor(expandedData),
229+
rIndex,
230+
oIndex,
229231
column:
230232
(appliedKey !== undefined &&
231233
appliedKey.toString &&
@@ -237,6 +239,8 @@ export function keyAndObjectifyBarData({
237239
decoratedData.push({
238240
renderKey: appliedKey,
239241
data: d,
242+
rIndex,
243+
oIndex,
240244
value: actualRAccessor(d),
241245
column: actualOAccessor(d)
242246
})

src/components/svg/lineDrawing.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,11 @@ export const projectLineData = ({
119119
}
120120
const projectedLine: Array<Object> = []
121121

122-
lineDataAccessor.forEach(actualLineAccessor => {
123-
xAccessor.forEach(actualXAccessor => {
124-
yAccessor.forEach(actualYAccessor => {
122+
lineDataAccessor.forEach((actualLineAccessor, lineIndex) => {
123+
xAccessor.forEach((actualXAccessor, xIndex) => {
124+
yAccessor.forEach((actualYAccessor, yIndex) => {
125125
data.forEach((d: Object) => {
126-
const originalLineData = { ...d }
126+
const originalLineData = { ...d, xIndex, yIndex, lineIndex }
127127

128128
originalLineData.data = actualLineAccessor(d).map((p, q) => {
129129
const originalCoords = {}

0 commit comments

Comments
 (0)