Skip to content

Commit 20eb68f

Browse files
committed
Linework improvements
1 parent d9f2376 commit 20eb68f

File tree

5 files changed

+73
-59
lines changed

5 files changed

+73
-59
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ When it completes, load `file:///path-to-your-checkout/react-workflow-viz/index.
2222
## Changelog
2323
_Side Note -_ Is there a way to auto-generate a `CHANGELOG.md` file out of releases' content?
2424

25+
#### 2020-03-13
26+
- Improvements in path plotting - do not diverge into separate paths unless necessary.
27+
- Demo updates.
28+
2529
#### 2020-01-21
2630
- Important glitch fixes, including typo and intersection counting.
2731
- PROTOTYPE / NOT ENABLED: Reuse horizontal edge segments (to reduce # of lines; noise) if:

gulpfile.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,7 @@ function doWatchScss(done){
162162
"./src/styles.scss",
163163
"./dist/react-workflow-viz.min.css",
164164
"--watch",
165-
"--recursive",
166-
"--source-map",
167-
"--source-map-embed"
165+
"--recursive"
168166
], { stdio: "inherit" });
169167

170168
subP.on("close", (code)=>{

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@hms-dbmi-bgm/react-workflow-viz",
3-
"version": "0.1.2",
3+
"version": "0.1.3",
44
"description": "React component for visualizing CWL-like workflows and provenance graphs.",
55
"main": "./dist/react-workflow-viz.min.js",
66
"unpkg": "./dist/react-workflow-viz.min.js",

src/components/EdgesLayer.js

Lines changed: 64 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export function traceEdges(
7979

8080
function assembleSegments(segmentQ, subdivisionsUsed = 4){
8181

82-
const usedSegments = new Map(); // (segment, [source, target])
82+
const usedSegments = new Map(); // (segment, [[source, target], ...])
8383
const segmentQLen = segmentQ.length;
8484

8585
/**
@@ -102,7 +102,7 @@ export function traceEdges(
102102
let closestSegmentDiff = Infinity;
103103
let closestSegmentIdx = -1;
104104
let currSegment = null, currSegmentY = 0, currExistingSegmentNodes = null, currDiff = null;
105-
let i, j, prevEdge, prevVs, multiplier = 1, intersections = 0;
105+
let i, j, prevEdge, prevVs, multiplier = 1, intersections = 0, willDiverge = false;
106106
for (i = 0; i < segmentQLen; i++){
107107
currSegment = segmentQ[i];
108108
currSegmentY = currSegment[0][1];
@@ -114,19 +114,24 @@ export function traceEdges(
114114
// Skip used segments unless (going to same target node) or (from same source node and on same Y coord).
115115
currExistingSegmentNodes = usedSegments.get(currSegment);
116116
if (currExistingSegmentNodes){
117-
continue;
118-
// Use below for experiment with converging / shared path for common source/target nodes.
119-
// if (!(currExistingSegmentNodes[1] === target || (currExistingSegmentNodes[0] === source && currSegmentY === prevYCoord))){
117+
willDiverge = _.every(currExistingSegmentNodes, function([ exSrc, exTgt ]){ return exSrc === source; });
118+
// if (!(
119+
// willDiverge || // (below) Gets a little confusing if converge esp in order/grouping. `currSegmentY === prevYCoord` addresses this somewhat.
120+
// (_.every(currExistingSegmentNodes, function([ exSrc, exTgt ]){ return exTgt === target; }) && currSegmentY === prevYCoord)
121+
// )) {
120122
// continue;
121123
// }
124+
if (!willDiverge) {
125+
continue;
126+
}
122127
}
123128

124129
//currDiff = Math.abs(yCoordMedian - currSegmentY);
125130
if (currSegmentY > upperY){
126131
currDiff = currSegmentY - upperY;
127132
} else if (currSegmentY < lowerY){
128133
currDiff = lowerY - currSegmentY;
129-
} else if (currExistingSegmentNodes) {
134+
} else if (willDiverge) {
130135
currDiff = -0.01;
131136
} else {
132137
//{
@@ -136,53 +141,56 @@ export function traceEdges(
136141
currDiff = Math.abs(prevYCoord - currSegmentY) * 0.01;
137142
}
138143

139-
// Check for intersections, add to score
140-
intersections = 0;
141-
for (j = 0; j < prevEdgesLen; j++){
142-
prevEdge = previousEdges[j];
143-
if (Array.isArray(prevEdge.vertices)){
144-
prevVs = prevEdge.vertices;
145-
multiplier = 2;
146-
} else {
147-
prevVs = [
148-
[ prevEdge.source.x + columnWidth, prevEdge.source.y ],
149-
[ prevEdge.target.x, prevEdge.target.y ]
150-
];
151-
multiplier = 1;
152-
}
153-
154-
prevVs.reduce(function(prevV, v){
155-
if (!prevV) return v; // First V
144+
// Check for intersections, add to score (unless reusing existing segment)
145+
if (!currExistingSegmentNodes) {
146+
intersections = 0;
147+
for (j = 0; j < prevEdgesLen; j++){
148+
prevEdge = previousEdges[j];
149+
if (Array.isArray(prevEdge.vertices)){
150+
prevVs = prevEdge.vertices;
151+
multiplier = 2;
152+
} else {
153+
prevVs = [
154+
[ prevEdge.source.x + columnWidth, prevEdge.source.y ],
155+
[ prevEdge.target.x, prevEdge.target.y ]
156+
];
157+
multiplier = 1;
158+
}
156159

157-
if (!(prevV[0] + nodeEdgeLedgeWidths[0] < startXForCol && v[0] >= startXForCol - nodeEdgeLedgeWidths[0])){
160+
prevVs.reduce(function(prevV, v){
161+
if (!prevV) return v; // First V
162+
163+
if (!(prevV[0] + nodeEdgeLedgeWidths[0] < startXForCol && v[0] >= startXForCol - nodeEdgeLedgeWidths[0])){
164+
return v;
165+
}
166+
// if (source.name === "chromsize" && columnIdx === 2) {
167+
// console.log('TTTX\n', v, '\n', prevV, '\n', columnIdx, intersections);
168+
// }
169+
if (
170+
(v[1] > currSegmentY && prevV[1] < prevYCoord) ||
171+
(v[1] < currSegmentY && prevV[1] > prevYCoord)
172+
) {
173+
// Boost 'any' intersections
174+
// Multiplier allows us to try to avoid intersecting
175+
// bigger lines moreso than smaller ones
176+
if (intersections === 0) intersections += 2 * multiplier;
177+
intersections += multiplier;
178+
//if (startXForCol> 1400 && startXForCol < 1600){
179+
// console.log('X', v[0], v[1], '<-', prevV[0], prevV[1]);
180+
//}
181+
}
158182
return v;
159-
}
160-
// if (source.name === "chromsize" && columnIdx === 2) {
161-
// console.log('TTTX\n', v, '\n', prevV, '\n', columnIdx, intersections);
162-
// }
163-
if (
164-
(v[1] > currSegmentY && prevV[1] < prevYCoord) ||
165-
(v[1] < currSegmentY && prevV[1] > prevYCoord)
166-
) {
167-
// Boost 'any' intersections
168-
// Multiplier allows us to try to avoid intersecting
169-
// bigger lines moreso than smaller ones
170-
if (intersections === 0) intersections += 2 * multiplier;
171-
intersections += multiplier;
172-
//if (startXForCol> 1400 && startXForCol < 1600){
173-
// console.log('X', v[0], v[1], '<-', prevV[0], prevV[1]);
174-
//}
175-
}
176-
return v;
177-
}, null);
183+
}, null);
178184

179-
}
185+
}
186+
187+
// if (source.name === "chromsize" && columnIdx === 2) {
188+
// console.log('TTT', previousEdges.slice(), columnIdx, currSegmentY, intersections);
189+
// }
180190

181-
// if (source.name === "chromsize" && columnIdx === 2) {
182-
// console.log('TTT', previousEdges.slice(), columnIdx, currSegmentY, intersections);
183-
// }
191+
currDiff += (intersections * (rowSpacing * 0.8));
184192

185-
currDiff += (intersections * (rowSpacing * 0.8));
193+
} // end intersection checking
186194

187195
//if (startXForCol> 1400 && startXForCol < 1600){
188196
// console.log('INT', currDiff, currSegmentY, intersections, prevYCoord);
@@ -201,8 +209,10 @@ export function traceEdges(
201209
}
202210

203211
const bestSegment = segmentQ[closestSegmentIdx];
204-
if (!usedSegments.get(bestSegment)){
205-
usedSegments.set(bestSegment, [ source, target ]);
212+
if (currExistingSegmentNodes) {
213+
currExistingSegmentNodes.push([ source, target ]);
214+
} else {
215+
usedSegments.set(bestSegment, [[ source, target ]]);
206216
}
207217
return bestSegment;
208218
}
@@ -246,12 +256,14 @@ export function traceEdges(
246256
const { column: sourceCol, x: sourceX, y: sourceY } = source;
247257
const { column: targetCol, x: targetX, y: targetY } = target;
248258
const columnDiff = targetCol - sourceCol;
259+
249260
if (columnDiff <= 0){
250261
// Shouldn't happen I don't think except if file is re-used/generated or some other unexpected condition.
251262
console.error("Target column is greater than source column", source, target);
252263
resultEdges.push(edge);
253264
return; // Skip tracing it.
254265
}
266+
255267
if (columnDiff === 1){
256268
resultEdges.push(edge);
257269
return; // Doesn't need to go around obstacles, skip.
@@ -274,8 +286,8 @@ export function traceEdges(
274286
throw new Error("Could not find viable path for edge");
275287
}
276288
const [ [ bsX, bsY ], [ beX, beY ] ] = bestSegment;
277-
// const origSrcTrg = usedSegments.get(bestSegment);
278-
// const isReusedSource = origSrcTrg[0] === source && origSrcTrg[1] !== target;
289+
//const origSrcTrg = usedSegments.get(bestSegment);
290+
//const isReusedSource = origSrcTrg[0] === source && origSrcTrg[1] !== target;
279291
vertices.push([ bsX - nodeEdgeLedgeWidths[0], bsY ]);
280292
vertices.push([ beX + nodeEdgeLedgeWidths[1], beY ]);
281293
prevY = beY;

src/styles.scss

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ $workflow-node-color-type-global-context: #ffb3b3 !default;
470470
path {
471471
pointer-events: all;
472472
stroke: #888;
473-
stroke: rgba(58,58,58,0.75);
473+
// stroke: rgba(58,58,58,0.75);
474474
fill: none;
475475
stroke-width: 1px;
476476
stroke-width: 1.5px;
@@ -486,8 +486,8 @@ $workflow-node-color-type-global-context: #ffb3b3 !default;
486486

487487
&.disabled:not([data-edge-selected="true"]):not([data-edge-related="true"]) {
488488
stroke-width: 1px;
489-
//stroke: #bbb;
490-
stroke: rgba(0,0,0,0.33);
489+
stroke: #bbb;
490+
//stroke: rgba(0,0,0,0.33);
491491
}
492492
&[data-edge-selected="true"]{
493493
stroke-width: 3px;

0 commit comments

Comments
 (0)