| 15 | } |
| 16 | |
| 17 | function removeOverlap(nodes, options){ |
| 18 | if(nodes.length>0){ |
| 19 | options = helper.extend(DEFAULT_OPTIONS, options); |
| 20 | |
| 21 | // For nodes with stub, set target position to stub's current position |
| 22 | nodes.forEach(function (node, index) { |
| 23 | node.targetPos = node.parent ? node.parent.currentPos : node.idealPos; |
| 24 | node.index = index; |
| 25 | }); |
| 26 | |
| 27 | const variables = nodes.concat() |
| 28 | .sort(function (a, b) { |
| 29 | const diff = a.targetPos - b.targetPos; |
| 30 | if (diff !== 0) return diff; |
| 31 | const diff2 = a.isStub() - b.isStub(); |
| 32 | if (diff2!== 0) return diff2; |
| 33 | // If same position, use original order |
| 34 | return a.index-b.index; |
| 35 | }) |
| 36 | .map(nodeToVariable); |
| 37 | |
| 38 | const constraints = []; |
| 39 | for(let i=1;i<variables.length;i++){ |
| 40 | const v1 = variables[i-1]; |
| 41 | const v2 = variables[i]; |
| 42 | |
| 43 | let gap; |
| 44 | if(v1.node.isStub() && v2.node.isStub()){ |
| 45 | gap = (v1.node.width+v2.node.width)/2 + options.lineSpacing; |
| 46 | } |
| 47 | else{ |
| 48 | gap = (v1.node.width+v2.node.width)/2 + options.nodeSpacing; |
| 49 | } |
| 50 | constraints.push(new vpsc.Constraint(v1, v2, gap)); |
| 51 | } |
| 52 | |
| 53 | if(helper.isDefined(options.minPos)){ |
| 54 | const leftWall = new vpsc.Variable(options.minPos, 1e10); |
| 55 | const v = variables[0]; |
| 56 | constraints.push(new vpsc.Constraint(leftWall, v, v.node.width/2)); |
| 57 | variables.unshift(leftWall); |
| 58 | } |
| 59 | |
| 60 | if(helper.isDefined(options.maxPos)){ |
| 61 | const rightWall = new vpsc.Variable(options.maxPos, 1e10); |
| 62 | const lastv = helper.last(variables); |
| 63 | constraints.push(new vpsc.Constraint(lastv, rightWall, lastv.node.width/2)); |
| 64 | variables.push(rightWall); |
| 65 | } |
| 66 | |
| 67 | (new vpsc.Solver(variables, constraints)).solve(); |
| 68 | |
| 69 | variables |
| 70 | .filter( v => v.node ) |
| 71 | .map(function(v){ |
| 72 | v.node.currentPos = Math.round(v.position()); |
| 73 | return v; |
| 74 | }); |