Skip to content

Commit

Permalink
Merge fbafa28 into 8f9558c
Browse files Browse the repository at this point in the history
  • Loading branch information
tadkollar committed Jun 8, 2020
2 parents 8f9558c + fbafa28 commit 728f8e5
Show file tree
Hide file tree
Showing 11 changed files with 351 additions and 171 deletions.
23 changes: 18 additions & 5 deletions openmdao/visualization/n2_viewer/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -115,24 +115,34 @@
<clipPath id="solverTreeClip">
<rect id="solver-clip-rect" x="0" y="0" width="1200" height="600" />
</clipPath>
<g id='matrix-connector-arrow' width='10' height='10'>
<path d='M0,3 h2 q5,0 5,5 h1 l-3,2 l-3,-2 h1 q0,-1 -1,-1 h-2 z'></path>
</g>
<g id='matrix-connector-square' width='10' height='10'>
<rect x='2' y='2' width='6' height='6'></rect>
</g>
</defs>
<g id='tree' clip-path='url(#partitionTreeClip)'></g>
<g id='highlight-bar'></g>
<g id='solver_tree' clip-path='url(#solverTreeClip)'></g>
<g id='n2outer'>
<g id='n2inner'>
<rect id='backgroundRect' class='background'></rect>
<g id='n2elements' clip-path='url(#n2MatrixClip)'></g>
<g id='n2background' clip-path='url(#n2MatrixClip)'></g>
<g id='n2gridlines' clip-path='url(#n2MatrixClip)'></g>
<g id='n2elements' clip-path='url(#n2MatrixClip)'></g>
<g id='n2componentBoxes' clip-path='url(#n2MatrixClip)'></g>
<g id='n2dots' clip-path='url(#n2MatrixClip)'></g>
<g id='n2highlights'></g>
<g id='n2arrows'></g>
</g>
<g id='n2top' class='offgridLabel'></g>
<g id='n2left' class='offgridLabel'></g>
<g id='n2right' class='offgridLabel'></g>
<g id='n2bottom' class='offgridLabel'></g>
</g>
<g id='tree' clip-path='url(#partitionTreeClip)'></g>
<g id='solver_tree' clip-path='url(#solverTreeClip)'></g>
<g id='text-width-renderer' class='partition_group'>
<text x='-200'></text>
</g>
</svg>
<div id='n2-resizer-box' class='inactive-resizer-box'>
<p id='n2-resizer-handle' class='inactive-resizer-handle'></p>
Expand Down Expand Up @@ -196,7 +206,8 @@
</div>
</div>

<table id="node-info-container" class='info-hidden' cellpadding='0' cellspacing='0'>
<div id="node-info-container" class='info-hidden'>
<table id="node-info-table" cellpadding='0' cellspacing='0'>
<thead>
<tr>
<th scope='col' colspan='2'>Name</th>
Expand All @@ -209,6 +220,8 @@
</tr>
</tfoot>
</table>
<p id='node-info-pin' class='info-hidden'>&#x1F4CC;</p>
</div>

<div class="tool-tip" style="position: absolute; visibility: hidden;"></div>
<div id="top" class="offgrid" style="visibility: hidden;"></div>
Expand Down
45 changes: 28 additions & 17 deletions openmdao/visualization/n2_viewer/src/N2Arrow.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class N2Arrow {
this.elementsGrp = n2Groups.elements;
this.nodeSize = nodeSize;
this.attribs = attribs;
this._genPath = this._angledPath;
}

get offsetAbsX() {
Expand Down Expand Up @@ -70,9 +71,10 @@ class N2BentArrow extends N2Arrow {
let offsetAbsX = this.offsetAbsX;
let offsetAbsY = this.offsetAbsY;

let offsetX = (this.start.col < this.end.col) ? offsetAbsX : -offsetAbsX; // Left-to-Right : Right-to-Left
this.pts.start.x = this.nodeSize.width * this.start.col + this.nodeSize.width * .5 + offsetX;
this.offsetX = (this.start.col < this.end.col) ? offsetAbsX : -offsetAbsX; // Left-to-Right : Right-to-Left
this.pts.start.x = this.nodeSize.width * this.start.col + this.nodeSize.width * .5 + this.offsetX;
this.pts.mid.x = this.nodeSize.width * this.middle.col + this.nodeSize.width * .5;
// this.pts.mid.x = (this.offsetX > 0)? this.nodeSize.width * this.middle.col : this.nodeSize.width * (this.middle.col + 1);
this.pts.end.x = this.nodeSize.width * this.end.col + this.nodeSize.width * .5;

let offsetY = (this.start.row < this.end.row) ? -offsetAbsY : offsetAbsY; // Down : Up
Expand All @@ -81,16 +83,30 @@ class N2BentArrow extends N2Arrow {
this.pts.end.y = this.nodeSize.height * this.end.row + this.nodeSize.height * .5 + offsetY;
}

/**
* Use SVG to draw the line segments, add a circle at the "middle",
* and an arrow at the end-point.
*/
/** Create a path string with a quadratic curve at the bend. */
_curvedPath() {
const dir = (this.offsetX > 0)? 1 : -1;
const s = this.nodeSize.width * .5 * dir;

return "M" + this.pts.start.x + " " + this.pts.start.y +
" L" + this.pts.mid.x + " " + this.pts.mid.y +
` q${s} 0 ${s} ${s}` +
" L" + this.pts.end.x + " " + this.pts.end.y;
}

/** Generate a path with a 90-degree angle at the bend. */
_angledPath() {
return "M" + this.pts.start.x + " " + this.pts.start.y +
" L" + this.pts.mid.x + " " + this.pts.mid.y +
" L" + this.pts.end.x + " " + this.pts.end.y;
}

/** Use SVG to draw the line segments and an arrow at the end-point. */
draw() {
this.path = this.arrowsGrp.insert("path")
.attr("class", "n2_hover_elements")
.attr("d", "M" + this.pts.start.x + " " + this.pts.start.y +
" L" + this.pts.mid.x + " " + this.pts.mid.y +
" L" + this.pts.end.x + " " + this.pts.end.y)
.attr("marker-end", "url(#arrow)")
.attr("d", this._genPath())
.attr("fill", "none")
.style("stroke-width", this.width)
.style("stroke", this.color);
Expand All @@ -102,7 +118,7 @@ class N2BentArrow extends N2Arrow {
.attr("r", this.width * 1.0)
.style("stroke-width", 0)
.style("fill-opacity", 1)
.style("fill", "black");
.style("fill", N2Style.color.connection);

this.dotsGrp.append("circle")
.attr("class", "n2_hover_elements")
Expand All @@ -112,8 +128,6 @@ class N2BentArrow extends N2Arrow {
.style("stroke-width", 0)
.style("fill-opacity", .75)
.style("fill", this.color);

this.path.attr("marker-end", "url(#arrow)");
}
}

Expand Down Expand Up @@ -180,14 +194,13 @@ class N2OffGridArrow extends N2Arrow {
return true;
}

/**
* Put the SVG arrow on the screen and position the tooltip.
*/
/** Put the SVG arrow on the screen and position the tooltip. */
draw() {
debugInfo('Adding offscreen ' + this.attribs.direction +
' arrow connected to ' + this.label.text);

this.path = this.arrowsGrp.insert('path')
.attr('marker-end', 'url(#arrow)')
.attr('class', 'n2_hover_elements')
.attr('stroke-dasharray', '5,5')
.attr('d', 'M' + this.pts.start.x + ' ' + this.pts.start.y +
Expand All @@ -196,8 +209,6 @@ class N2OffGridArrow extends N2Arrow {
.style('stroke-width', this.width)
.style('stroke', this.color);

this.path.attr('marker-end', 'url(#arrow)');

for (let pos in this.label.pts) {
this.label.ref.style(pos, this.label.pts[pos] + 'px');
}
Expand Down
97 changes: 60 additions & 37 deletions openmdao/visualization/n2_viewer/src/N2Diagram.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,10 @@ class N2Diagram {
'svgStyle': d3.select("#svgId style"),
'toolTip': d3.select(".tool-tip"),
'arrowMarker': d3.select("#arrow"),
'nodeInfo': d3.select('#node-data'),
'n2OuterGroup': d3.select('g#n2outer'),
'n2InnerGroup': d3.select('g#n2inner'),
'pTreeGroup': d3.select('g#tree'),
'highlightBar': d3.select('g#highlight-bar'),
'pSolverTreeGroup': d3.select('g#solver_tree'),
'n2BackgroundRect': d3.select('g#n2inner rect'),
'clips': {
Expand Down Expand Up @@ -274,6 +274,11 @@ class N2Diagram {
.attr("width", this.dims.size.partitionTree.width)
.attr("transform", "translate(0 " + innerDims.margin + ")");

this.dom.highlightBar
.attr("height", innerDims.height)
.attr("width", "8")
.attr("transform", "translate(" + this.dims.size.partitionTree.width + 1 + " " + innerDims.margin + ")");

this.dom.n2OuterGroup
.attr("height", outerDims.height)
.attr("width", outerDims.height)
Expand Down Expand Up @@ -330,7 +335,11 @@ class N2Diagram {
self.prevScales.model.y(d.prevDims.y) + ")";
})
.on("click", function (d) {
self.ui.leftClick(d);
if (self.ui.nodeInfoBox.hidden) { self.ui.leftClick(d); } // Zoom if not in info panel mode
else { // Pin/unpin the info panel
self.ui.nodeInfoBox.togglePin();
self.ui.nodeInfoBox.update(d3.event, d, d3.select(this).select('rect').style('fill'));
}
})
.on("contextmenu", function (d) {
self.ui.rightClick(d, this);
Expand All @@ -353,16 +362,18 @@ class N2Diagram {
return d.prevDims.height * self.prevTransitCoords.model.y;
})
.attr("id", function (d) {
return d.absPathName.replace(/\./g, '_');
});
return d.absPathName.replace(/[\.:]/g, '_');
})
.attr('rx', 12)
.attr('ry', 12);

nodeEnter.append("text")
.attr("dy", ".35em")
.attr("transform", function (d) {
let anchorX = d.prevDims.width * self.prevTransitCoords.model.x -
self.layout.size.rightTextMargin;
return "translate(" + anchorX + " " + d.prevDims.height *
self.prevTransitCoords.model.y / 2 + ")";
return "translate(" + anchorX + " " +
(d.prevDims.height * self.prevTransitCoords.model.y / 2) + ")";
})
.style("opacity", function (d) {
if (d.depth < self.zoomedElement.depth) return 0;
Expand Down Expand Up @@ -407,8 +418,8 @@ class N2Diagram {
.attr("transform", function (d) {
let anchorX = d.dims.width * self.transitCoords.model.x -
self.layout.size.rightTextMargin;
return "translate(" + anchorX + " " + d.dims.height *
self.transitCoords.model.y / 2 + ")";
return "translate(" + anchorX + " " + (d.dims.height *
self.transitCoords.model.y / 2) + ")";
})
.style("opacity", function (d) {
if (d.depth < self.zoomedElement.depth) return 0;
Expand Down Expand Up @@ -440,8 +451,8 @@ class N2Diagram {
.attr("transform", function (d) {
let anchorX = d.dims.width * self.transitCoords.model.x -
self.layout.size.rightTextMargin;
return "translate(" + anchorX + "," + d.dims.height *
self.transitCoords.model.y / 2 + ")";
return "translate(" + anchorX + "," + (d.dims.height *
self.transitCoords.model.y / 2) + ")";
})
.style("opacity", 0);
}
Expand Down Expand Up @@ -470,7 +481,11 @@ class N2Diagram {
self.prevScales.solver.y(d.prevSolverDims.y) + ")";
})
.on("click", function (d) {
self.ui.leftClick(d);
if (self.ui.nodeInfoBox.hidden) { self.ui.leftClick(d); } // Zoom if not in info panel mode
else { // Pin/unpin the info panel
self.ui.nodeInfoBox.togglePin();
self.ui.nodeInfoBox.update(d3.event, d, d3.select(this).select('rect').style('fill'));
}
})
.on("contextmenu", function (d) {
self.ui.rightClick(d, this);
Expand All @@ -497,6 +512,8 @@ class N2Diagram {
}
})
.on("mousemove", function () {
self.ui.nodeInfoBox.move(d3.event);

if (self.model.abs2prom != undefined) {
self.dom.toolTip.style("top", (d3.event.pageY - 30) + "px")
.style("left", (d3.event.pageX + 5) + "px");
Expand Down Expand Up @@ -614,8 +631,13 @@ class N2Diagram {
.style("opacity", 0);
}

clearHighlights() {
this.dom.highlightBar.selectAll('rect').remove();
}

clearArrows() {
this.dom.n2OuterGroup.selectAll("[class^=n2_hover_elements]").remove();
this.clearHighlights();
}

/** Reveal arrows that had been hidden */
Expand Down Expand Up @@ -752,43 +774,44 @@ class N2Diagram {
/** When the mouse leaves a cell, remove all temporary arrows. */
mouseOut() {
this.dom.n2OuterGroup.selectAll(".n2_hover_elements").remove();
d3.selectAll("div.offgrid")
.style("visibility", "hidden")
.html('');
this.clearHighlights();
d3.selectAll("div.offgrid").style("visibility", "hidden").html('');

this.ui.nodeInfoBox.clear();
}

/**
* When the mouse if left-clicked on a cell, change their CSS class
* When the mouse is left-clicked on a cell, change their CSS class
* so they're not removed when the mouse moves out.
* @param {N2MatrixCell} cell The cell the event occured on.
*/
mouseClick(cell) {
let newClassName = "n2_hover_elements_" + cell.row + "_" + cell.col;
let selection = this.dom.n2OuterGroup.selectAll("." + newClassName);
if (selection.size() > 0) {
selection.remove();
const arrow = this.arrowCache.find(o => o.cell.row === cell.row && o.cell.col === cell.col);
const arrowIndex = this.arrowCache.indexOf(arrow);
this.arrowCache.splice(arrowIndex, 1);
}
else {
const arrow = {
'cell': cell,
'element': this.dom.n2OuterGroup
.selectAll("path.n2_hover_elements, circle.n2_hover_elements"),
'className': newClassName
if (this.ui.nodeInfoBox.hidden) { // If not in info panel mode
let newClassName = "n2_hover_elements_" + cell.row + "_" + cell.col;
let selection = this.dom.n2OuterGroup.selectAll("." + newClassName);
if (selection.size() > 0) {
selection.remove();
const arrow = this.arrowCache.find(o => o.cell.row === cell.row && o.cell.col === cell.col);
const arrowIndex = this.arrowCache.indexOf(arrow);
this.arrowCache.splice(arrowIndex, 1);
}
else {
const arrow = {
'cell': cell,
'element': this.dom.n2OuterGroup
.selectAll("path.n2_hover_elements, circle.n2_hover_elements"),
'className': newClassName
}
this.arrowCache.push(arrow);
this.dom.n2OuterGroup
.selectAll("path.n2_hover_elements, circle.n2_hover_elements")
.attr("class", newClassName);
}
this.arrowCache.push(arrow);
this.dom.n2OuterGroup
.selectAll("path.n2_hover_elements, circle.n2_hover_elements")
.attr("class", newClassName);
}
}

clearActiveNode() {
this.dom.nodeInfo.html('');
else { // Pin/unpin the info panel
this.ui.nodeInfoBox.togglePin();
this.ui.nodeInfoBox.update(d3.event, cell.obj, cell.color());
}
}

mouseClickAll(cell) {
Expand Down
16 changes: 10 additions & 6 deletions openmdao/visualization/n2_viewer/src/N2Layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,8 @@ class N2Layout {

/** Create an off-screen area to render text for _getTextWidth() */
_setupTextRenderer() {
let textGroup = this.svg.append("g").attr("class", "partition_group");
let textSVG = textGroup.append("text")
.text("")
.attr("x", -100); // Put text off screen to the left.
const textGroup = this.svg.select('#text-width-renderer');
const textSVG = textGroup.select('text');

this.textRenderer = {
'group': textGroup,
Expand Down Expand Up @@ -522,8 +520,8 @@ class N2Layout {

this.ratio = (window.innerWidth - 200) / outerDims.width;
if (this.ratio > 1 || manuallyResized) this.ratio = 1;
else if ( this.ratio < 1 )
debugInfo("Scaling diagram to " + Math.round(this.ratio * 100) + "%" );
else if (this.ratio < 1)
debugInfo("Scaling diagram to " + Math.round(this.ratio * 100) + "%");

dom.svgDiv
.style("width", (outerDims.width * this.ratio) + this.size.unit)
Expand All @@ -547,6 +545,12 @@ class N2Layout {
.attr("width", this.size.partitionTree.width)
.attr("transform", "translate(0 " + innerDims.margin + ")");

dom.highlightBar
.transition(sharedTransition)
.attr("height", innerDims.height)
.attr("width", "8")
.attr("transform", "translate(" + this.size.partitionTree.width + 1 + " " + innerDims.margin + ")");

// Move n2 outer group to right of partition tree, spaced by the margin.
dom.n2OuterGroup
.transition(sharedTransition)
Expand Down
Loading

0 comments on commit 728f8e5

Please sign in to comment.