Skip to content

Commit fe1e3dc

Browse files
authored
Fixing zoom perf in azdata graph. (#74)
1 parent 76174d1 commit fe1e3dc

13 files changed

Lines changed: 451 additions & 204 deletions

dist/build.js

Lines changed: 120 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -25912,32 +25912,31 @@ mxPolyline.prototype.paintCurvedLine = function(c, pts)
2591225912

2591325913
__mxOutput.mxPolyline = typeof mxPolyline !== 'undefined' ? mxPolyline : undefined;
2591425914

25915-
function mxPolygon(points, fill, stroke, strokewidth)
25916-
{
25917-
mxPolyline.call(this);
25918-
this.points = points;
25919-
this.stroke = stroke;
25920-
this.fill = fill;
25921-
this.strokewidth = (strokewidth != null) ? strokewidth : 1;
25922-
};
25923-
25924-
/**
25925-
* Extends mxPolyline.
25926-
*/
25927-
mxUtils.extend(mxPolygon, mxPolyline);
25928-
25929-
/**
25930-
* Function: paintLine: overriding paintline function of polyline to paint the entire shape instead of just the line
25931-
*
25932-
* Paints the polygon
25933-
*/
25934-
mxPolygon.prototype.paintLine = function(c, pts, rounded)
25935-
{
25936-
var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
25937-
c.begin();
25938-
this.addPoints(c, pts, rounded, arcSize, true);
25939-
c.fillAndStroke();
25940-
};
25915+
function mxPolygon(points, fill, stroke, strokewidth) {
25916+
mxPolyline.call(this);
25917+
this.points = points;
25918+
this.stroke = stroke;
25919+
this.fill = fill;
25920+
this.strokewidth = (strokewidth != null) ? strokewidth : 1;
25921+
};
25922+
25923+
/**
25924+
* Extends mxPolyline.
25925+
*/
25926+
mxUtils.extend(mxPolygon, mxPolyline);
25927+
25928+
/**
25929+
* Function: paintLine: overriding paintline function of polyline to paint the entire shape instead of just the line
25930+
*
25931+
* Paints the polygon
25932+
*/
25933+
mxPolygon.prototype.paintLine = function (c, pts, rounded) {
25934+
var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
25935+
c.begin();
25936+
this.addPoints(c, pts, rounded, arcSize, true);
25937+
c.fillAndStroke();
25938+
};
25939+
2594125940
__mxOutput.mxPolygon = typeof mxPolygon !== 'undefined' ? mxPolygon : undefined;
2594225941

2594325942
/**
@@ -52618,22 +52617,22 @@ mxGraphView.prototype.getScale = function()
5261852617
*
5261952618
* value - Decimal value that specifies the new scale (1 is 100%).
5262052619
*/
52621-
mxGraphView.prototype.setScale = function(value)
52622-
{
52620+
mxGraphView.prototype.setScale = function (value) {
52621+
this.graph.container.style.display = 'none';
5262352622
var previousScale = this.scale;
52624-
52625-
if (this.scale != value)
52626-
{
52623+
52624+
if (this.scale != value) {
5262752625
this.scale = value;
5262852626

52629-
if (this.isEventsEnabled())
52630-
{
52627+
if (this.isEventsEnabled()) {
5263152628
this.viewStateChanged();
5263252629
}
5263352630
}
52634-
52631+
5263552632
this.fireEvent(new mxEventObject(mxEvent.SCALE,
5263652633
'scale', value, 'previousScale', previousScale));
52634+
52635+
this.graph.container.style.display = '';
5263752636
};
5263852637

5263952638
/**
@@ -92860,12 +92859,22 @@ const GRAPH_PADDING_LEFT = 80;
9286092859
const CELL_WIDTH = 70;
9286192860
const CELL_HEIGHT = 70;
9286292861

92862+
class PolygonRoot {
92863+
constructor(cell, fillColor, strokeColor, strokeWidth) {
92864+
this.cell = cell;
92865+
this.fillColor = fillColor;
92866+
this.strokeColor = strokeColor;
92867+
this.strokeWidth = strokeWidth;
92868+
}
92869+
}
92870+
9286392871
class Point {
9286492872
constructor(x, y) {
9286592873
this.x = x;
9286692874
this.y = y;
9286792875
}
9286892876
}
92877+
9286992878
class GraphNodeLayoutHelper {
9287092879
constructor() {
9287192880
this.layoutPoints = [];
@@ -92906,6 +92915,7 @@ class GraphNodeLayoutHelper {
9290692915
else {
9290792916
this.layoutPoints.push(new Point(xPosition, yPosition));
9290892917
}
92918+
9290992919
return;
9291092920
}
9291192921

@@ -92956,6 +92966,7 @@ class GraphNodeLayoutHelper {
9295692966
this.layoutPoints.splice(insertIndex + 1, lastIndex - insertIndex - 1);
9295792967
return;
9295892968
}
92969+
9295992970
++lastIndex;
9296092971
}
9296192972

@@ -92972,6 +92983,7 @@ class GraphNodeLayoutHelper {
9297292983
if (rowX < this.layoutPoints[i].x) {
9297392984
break;
9297492985
}
92986+
9297592987
yPosition = Math.max(this.layoutPoints[i].y, yPosition);
9297692988
}
9297792989
return yPosition;
@@ -92989,6 +93001,8 @@ function azdataQueryPlan(container, queryPlanGraph, iconPaths, badgeIconPaths) {
9298993001

9299093002
azdataQueryPlan.prototype.init = function (container, iconPaths, badgeIconPaths) {
9299193003
this.container = container;
93004+
this.polygonRoots = [];
93005+
this.drawnPolygons = [];
9299293006
this.badges = [];
9299393007
mxEvent.addListener(window, 'unload', mxUtils.bind(this, function () {
9299493008
this.destroy();
@@ -93228,6 +93242,7 @@ azdataQueryPlan.prototype.init = function (container, iconPaths, badgeIconPaths)
9322893242

9322993243
while (stack.length > 0) {
9323093244
var entry = stack.pop();
93245+
9323193246
if (entry.node.children) {
9323293247
for (var i = 0; i < entry.node.children.length; ++i) {
9323393248
var node = entry.node.children[i];
@@ -93237,12 +93252,15 @@ azdataQueryPlan.prototype.init = function (container, iconPaths, badgeIconPaths)
9323793252
rand = Math.floor((Math.random() * icons.length));
9323893253
iconName = 'azdataQueryplan-' + icons[rand];
9323993254
}
93255+
9324093256
if (node.position.x > maxX) {
9324193257
maxX = node.position.x;
9324293258
}
93259+
9324393260
if (node.position.y > maxY) {
9324493261
maxY = node.position.y;
9324593262
}
93263+
9324693264
vertex = graph.insertVertex(parent, node.id, node, node.position.x, node.position.y, CELL_WIDTH, CELL_HEIGHT, iconName);
9324793265
this.addBadges(vertex, badgeIconPaths);
9324893266

@@ -93288,7 +93306,6 @@ azdataQueryPlan.prototype.placeGraphNodes = function () {
9328893306
this.SetNodePositionRecursive(this.queryPlanGraph, startX, startY);
9328993307
}
9329093308

93291-
9329293309
azdataQueryPlan.prototype.SetNodePositionRecursive = function (node, x, y) {
9329393310

9329493311
// Recursively setting all the x positions in the graph.
@@ -93298,7 +93315,6 @@ azdataQueryPlan.prototype.SetNodePositionRecursive = function (node, x, y) {
9329893315

9329993316
}
9330093317

93301-
9330293318
azdataQueryPlan.prototype.setNodeXPositionRecursive = function (node, x) {
9330393319
// Place the node at given position
9330493320
node.position = new Point(x, 0);
@@ -93357,25 +93373,35 @@ azdataQueryPlan.prototype.setNodeYPositionRecursive = function (node, layoutHelp
9335793373
}
9335893374

9335993375

93360-
azdataQueryPlan.prototype.zoomIn = function(){
93361-
if(this.graph.view.getScale() * this.graph.zoomFactor <= 2){
93376+
azdataQueryPlan.prototype.zoomIn = function () {
93377+
this.removeDrawnPolygons();
93378+
93379+
if (this.graph.view.getScale() * this.graph.zoomFactor <= 2) {
9336293380
this.graph.zoomIn();
9336393381
} else {
9336493382
this.graph.zoomTo(2)
9336593383
}
9336693384
this.redrawBadges();
93385+
this.redrawPolygons();
9336793386
}
9336893387

93369-
azdataQueryPlan.prototype.zoomOut = function(){
93388+
azdataQueryPlan.prototype.zoomOut = function () {
93389+
this.removeDrawnPolygons();
93390+
9337093391
this.graph.zoomOut();
9337193392
this.redrawBadges();
93393+
this.redrawPolygons();
9337293394
}
9337393395

93374-
azdataQueryPlan.prototype.zoomToFit = function(){
93396+
azdataQueryPlan.prototype.zoomToFit = function () {
93397+
this.removeDrawnPolygons();
93398+
9337593399
this.graph.fit(undefined, true, 20);
9337693400
this.redrawBadges();
9337793401
this.graph.view.rendering = true;
9337893402
this.graph.refresh();
93403+
93404+
this.redrawPolygons();
9337993405
}
9338093406

9338193407
azdataQueryPlan.prototype.registerGraphCallback = function (eventType, callback) {
@@ -93389,6 +93415,8 @@ azdataQueryPlan.prototype.getZoomLevelPercentage = function () {
9338993415
};
9339093416

9339193417
azdataQueryPlan.prototype.zoomTo = function (zoomPercentage) {
93418+
this.removeDrawnPolygons();
93419+
9339293420
const ZOOM_PERCENTAGE_MINIMUM = 1;
9339393421
const ZOOM_PERCENTAGE_MAXIMUM = 200;
9339493422

@@ -93401,7 +93429,7 @@ azdataQueryPlan.prototype.zoomTo = function (zoomPercentage) {
9340193429
parsedZoomLevel = ZOOM_PERCENTAGE_MINIMUM;
9340293430
}
9340393431

93404-
if(parsedZoomLevel > ZOOM_PERCENTAGE_MAXIMUM) {
93432+
if (parsedZoomLevel > ZOOM_PERCENTAGE_MAXIMUM) {
9340593433
parsedZoomLevel = ZOOM_PERCENTAGE_MAXIMUM;
9340693434
}
9340793435

@@ -93467,7 +93495,7 @@ azdataQueryPlan.prototype.addBadges = function (cell, badgeIconPaths) {
9346793495
img.style.left = `${positionX}px`;
9346893496
img.style.top = `${positionY}px`;
9346993497
img.setAttribute('initLeft', positionX);
93470-
img.setAttribute('initTop', positionY);
93498+
img.setAttribute('initTop', positionY);
9347193499
img.setAttribute('initHeight', badgeHeight);
9347293500
img.setAttribute('initWidth', badgeWidth);
9347393501
this.graph.container.appendChild(img);
@@ -93477,7 +93505,7 @@ azdataQueryPlan.prototype.addBadges = function (cell, badgeIconPaths) {
9347793505
}
9347893506
}
9347993507

93480-
azdataQueryPlan.prototype.redrawBadges = function(){
93508+
azdataQueryPlan.prototype.redrawBadges = function () {
9348193509
this.badges.forEach(b => {
9348293510
b.style.left = b.getAttribute('initLeft') * this.graph.view.getScale() + 'px';
9348393511
b.style.top = b.getAttribute('initTop') * this.graph.view.getScale() + 'px';
@@ -93488,30 +93516,59 @@ azdataQueryPlan.prototype.redrawBadges = function(){
9348893516

9348993517
/**
9349093518
* Draws a polygon using the points given
93491-
* @param {*} pts array of points for all the corners of the polygon. A point has x and y attributes.
93519+
* @param {*} cell starting cell where the polygon will start to be drawn.
9349293520
* @param {*} fillColor string value for the fill color. Supported values are hex, rbg and rbga
9349393521
* @param {*} strokeColor string value for the stroke/border color. Supported values are hex, rbg and rbga
9349493522
* @param {*} strokeWidth thickness of the stroke
9349593523
*/
93496-
azdataQueryPlan.prototype.drawPolygon = function(pts, fillColor, strokeColor, strokeWidth){
93524+
azdataQueryPlan.prototype.drawPolygon = function (cell, fillColor, strokeColor, strokeWidth) {
93525+
let scale = this.graph.view.getScale();
93526+
let points = this.getPolygonPerimeter(cell);
9349793527

93498-
var samplePolygon = new mxPolygon(
93499-
pts.map(p => new mxPoint(p.x, p.y)),
93528+
var polygon = new mxPolygon(
93529+
points.map(p => new mxPoint(p.x * scale, p.y * scale)),
9350093530
fillColor,
9350193531
strokeColor,
9350293532
strokeWidth
93503-
)
93504-
samplePolygon.init(this.graph.getView().getBackgroundPane());
93505-
samplePolygon.isDashed = true;
93506-
samplePolygon.redraw();
93533+
);
93534+
polygon.init(this.graph.getView().getBackgroundPane());
93535+
polygon.isDashed = true;
93536+
polygon.redraw();
93537+
93538+
this.polygonRoots.push(new PolygonRoot(cell, fillColor, strokeColor, strokeWidth));
93539+
this.drawnPolygons.push(polygon);
93540+
}
93541+
93542+
/**
93543+
* Removes all drawn polygons on the execution plan.
93544+
*/
93545+
azdataQueryPlan.prototype.removeDrawnPolygons = function () {
93546+
while (this.drawnPolygons.length !== 0) {
93547+
let polygon = this.drawnPolygons.pop();
93548+
polygon.destroy();
93549+
}
93550+
}
93551+
93552+
/**
93553+
* Redraws all polygons on the execution plan.
93554+
*/
93555+
azdataQueryPlan.prototype.redrawPolygons = function () {
93556+
let polygonCount = this.polygonRoots.length;
93557+
93558+
while (polygonCount !== 0) {
93559+
let polygonRoot = this.polygonRoots.pop();
93560+
this.drawPolygon(polygonRoot.cell, polygonRoot.fillColor, polygonRoot.strokeColor, polygonRoot.strokeWidth);
93561+
93562+
polygonCount--;
93563+
}
9350793564
}
9350893565

9350993566
/**
9351093567
* Gets an array of points that represents the perimeter for a polygon.
9351193568
* @param {*} cell The starting node where the perimeter will start being outlined.
9351293569
* @returns an array of points
9351393570
*/
93514-
azdataQueryPlan.prototype.getPolygonPerimeter = function(cell) {
93571+
azdataQueryPlan.prototype.getPolygonPerimeter = function (cell) {
9351593572
let points = [];
9351693573
points = points.concat(this.getLeftSidePoints(cell));
9351793574
points = points.concat(this.getBottomSidePoints(cell));
@@ -93528,10 +93585,11 @@ const NODE_WIDTH = 100;
9352893585
* @param {*} cell The starting node for the left side perimeter points.
9352993586
* @returns an array of points for the left side of the starting node in the polygon.
9353093587
*/
93531-
azdataQueryPlan.prototype.getLeftSidePoints = function(cell) {
93588+
azdataQueryPlan.prototype.getLeftSidePoints = function (cell) {
9353293589
let points = [];
93533-
points.push({ x: cell.geometry.x, y: cell.geometry.y });
93534-
points.push({ x: cell.geometry.x, y: cell.geometry.y + NODE_HEIGHT })
93590+
let xPosition = cell.geometry.x - 15; // subtracting to push the x coordinate to the left.
93591+
points.push({ x: xPosition, y: cell.geometry.y });
93592+
points.push({ x: xPosition, y: cell.geometry.y + NODE_HEIGHT })
9353593593

9353693594
return points;
9353793595
}
@@ -93541,9 +93599,9 @@ azdataQueryPlan.prototype.getLeftSidePoints = function(cell) {
9354193599
* @param {*} cell The starting node where highlighting will begin.
9354293600
* @returns An array of points for the bottom side of the polygon.
9354393601
*/
93544-
azdataQueryPlan.prototype.getBottomSidePoints = function(cell) {
93602+
azdataQueryPlan.prototype.getBottomSidePoints = function (cell) {
9354593603
let points = [];
93546-
var stack = [ cell ];
93604+
var stack = [cell];
9354793605

9354893606
while (stack.length !== 0) {
9354993607
let entry = stack.pop();
@@ -93553,7 +93611,7 @@ azdataQueryPlan.prototype.getBottomSidePoints = function(cell) {
9355393611
let nextNode = this.graph.model.getCell(entry.value.children[entry.value.children.length - 1].id);
9355493612

9355593613
if (entry.value.children.length > 1) {
93556-
let auxiliaryPoint = { x: entry.geometry.x + NODE_WIDTH, y: nextNode.geometry.y + NODE_HEIGHT};
93614+
let auxiliaryPoint = { x: entry.geometry.x + NODE_WIDTH, y: nextNode.geometry.y + NODE_HEIGHT };
9355793615
points.push(auxiliaryPoint);
9355893616
}
9355993617

@@ -93569,15 +93627,15 @@ azdataQueryPlan.prototype.getBottomSidePoints = function(cell) {
9356993627
* @param {*} cell The starting node where highlighting will begin.
9357093628
* @returns An array of points for the right side of the polygon.
9357193629
*/
93572-
azdataQueryPlan.prototype.getRightSidePoints = function(cell) {
93630+
azdataQueryPlan.prototype.getRightSidePoints = function (cell) {
9357393631
let points = [];
9357493632
let leafNodes = this.getLeafNodes(cell);
9357593633

9357693634
for (let nodeIndex = 0; nodeIndex < leafNodes.length; ++nodeIndex) {
9357793635
let leafNode = leafNodes[nodeIndex];
9357893636

9357993637
points.push({ x: leafNode.geometry.x + NODE_WIDTH, y: leafNode.geometry.y + NODE_HEIGHT });
93580-
points.push({ x: leafNode.geometry.x + NODE_WIDTH, y: leafNode.geometry.y});
93638+
points.push({ x: leafNode.geometry.x + NODE_WIDTH, y: leafNode.geometry.y });
9358193639
}
9358293640

9358393641
return points;
@@ -93588,13 +93646,13 @@ azdataQueryPlan.prototype.getRightSidePoints = function(cell) {
9358893646
* @param {*} cell The root node that will be used to find all of the leaf nodes
9358993647
* @returns An array of leaf nodes for a region from bottom-up
9359093648
*/
93591-
azdataQueryPlan.prototype.getLeafNodes = function(cell) {
93649+
azdataQueryPlan.prototype.getLeafNodes = function (cell) {
9359293650
let leafNodeTable = {};
9359393651
let stack = [cell];
9359493652

9359593653
while (stack.length !== 0) {
9359693654
let entry = stack.pop();
93597-
93655+
9359893656
if (entry.value.children.length === 0) {
9359993657
if (entry.geometry.y in leafNodeTable) {
9360093658
let previouslyCachedEntry = leafNodeTable[entry.geometry.y];

0 commit comments

Comments
 (0)