You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by pa...@apache.org on 2017/02/24 14:05:15 UTC
ambari git commit: AMBARI-20168. Hive 2: Compact Visual Explain Plan
is not loading in firefox (pallavkul)
Repository: ambari
Updated Branches:
refs/heads/trunk 1d3dce261 -> da9086dca
AMBARI-20168. Hive 2: Compact Visual Explain Plan is not loading in firefox (pallavkul)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/da9086dc
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/da9086dc
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/da9086dc
Branch: refs/heads/trunk
Commit: da9086dcaaf161a15e58bfc5fe44c338da18078d
Parents: 1d3dce2
Author: pallavkul <pa...@gmail.com>
Authored: Fri Feb 24 19:34:17 2017 +0530
Committer: pallavkul <pa...@gmail.com>
Committed: Fri Feb 24 19:34:17 2017 +0530
----------------------------------------------------------------------
.../ui/app/templates/queries/query/log.hbs | 2 +-
.../ui/app/templates/queries/query/results.hbs | 2 +-
.../templates/queries/query/visual-explain.hbs | 2 +-
.../ui/app/utils/hive-explainer/processor.js | 32 +++++-
.../ui/app/utils/hive-explainer/renderer.js | 55 ++++++++-
.../ui/app/utils/hive-explainer/transformer.js | 115 +++++++++++++------
6 files changed, 160 insertions(+), 48 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/da9086dc/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/log.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/log.hbs b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/log.hbs
index db1cea2..c7e30f2 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/log.hbs
+++ b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/log.hbs
@@ -17,7 +17,7 @@
}}
{{#unless hasJobAssociated}}
- <div>No Log avaiable.</div>
+ <div>No Log available.</div>
{{/unless}}
{{#if hasJobAssociated}}
http://git-wip-us.apache.org/repos/asf/ambari/blob/da9086dc/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/results.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/results.hbs b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/results.hbs
index 370e3ef..d859b04 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/results.hbs
+++ b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/results.hbs
@@ -19,7 +19,7 @@
{{outlet}}
{{#unless hasJobAssociated}}
- <div>No Results avaiable.</div>
+ <div>No Results available.</div>
{{/unless}}
{{#if hasJobAssociated}}
http://git-wip-us.apache.org/repos/asf/ambari/blob/da9086dc/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/visual-explain.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/visual-explain.hbs b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/visual-explain.hbs
index ef441b5..5b7e566 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/visual-explain.hbs
+++ b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/visual-explain.hbs
@@ -19,7 +19,7 @@
{{outlet}}
{{#unless hasJobAssociated}}
- <div>No Visual Explain avaiable.</div>
+ <div>No Visual Explain available.</div>
{{/unless}}
{{#if hasJobAssociated}}
http://git-wip-us.apache.org/repos/asf/ambari/blob/da9086dc/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/processor.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/processor.js b/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/processor.js
index 5dbeb2b..a252498 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/processor.js
+++ b/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/processor.js
@@ -25,11 +25,12 @@ function processEdges(vertices, edges) {
return vertices
.map(cVertex => {
- const isVertexPartOfSimpleEdge = edges.some(cEdge => cEdge.type === 'SIMPLE_EDGE' && cEdge.parent === cVertex._vertex);
- const isVertexPartOfBroadcastEdge = edges.some(cEdge => cEdge.type === 'BROADCAST_EDGE' && cEdge.parent === cVertex._vertex);
- const isVertexPartOfCustomSimpleEdge = edges.some(cEdge => cEdge.type === 'CUSTOM_SIMPLE_EDGE' && cEdge.parent === cVertex._vertex);
- const isVertexPartOfCustomEdge = edges.some(cEdge => cEdge.type === 'CUSTOM_EDGE' && cEdge.parent === cVertex._vertex);
- const isVertexPartOfXProdEdge = edges.some(cEdge => cEdge.type === 'XPROD_EDGE' && cEdge.parent === cVertex._vertex);
+ const isVertexPartOfSimpleEdge = edges.some(cEdge => cEdge.type === 'SIMPLE_EDGE' && cEdge._source === cVertex._vertex);
+ const isVertexPartOfBroadcastEdge = edges.some(cEdge => cEdge.type === 'BROADCAST_EDGE' && cEdge._source === cVertex._vertex);
+ const isVertexPartOfCustomSimpleEdge = edges.some(cEdge => cEdge.type === 'CUSTOM_SIMPLE_EDGE' && cEdge._source === cVertex._vertex);
+ const isVertexPartOfCustomEdge = edges.some(cEdge => cEdge.type === 'CUSTOM_EDGE' && cEdge._source === cVertex._vertex);
+ const isVertexPartOfXProdEdge = edges.some(cEdge => cEdge.type === 'XPROD_EDGE' && cEdge._source === cVertex._vertex);
+ const isVertexPartOfUnionEdge = edges.some(cEdge => cEdge.type === 'CONTAINS' && cEdge._source === cVertex._vertex);
let tVertex = cVertex;
@@ -58,6 +59,11 @@ function processEdges(vertices, edges) {
_operator: 'Cross-product Distribute Pseudo-Edge'
});
}
+ if(isVertexPartOfUnionEdge) {
+ tVertex = appendIfTerminusOfOperator(tVertex, {
+ _operator: 'Partition/Sort Pseudo-Edge'
+ });
+ }
return tVertex;
});
@@ -238,3 +244,19 @@ function doCloneAndOmit(obj, keys) {
[cObjKey]: obj[cObjKey]
}), {});
}
+
+export function getEdgesWithCorrectedUnion(edges) {
+
+ return edges
+ .map(cEdge => {
+ if(cEdge.type === 'CONTAINS') {
+ return Object.assign({}, cEdge, {
+ _source: cEdge._target,
+ _target: cEdge._source,
+ });
+ } else {
+ return cEdge;
+ }
+ });
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/da9086dc/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/renderer.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/renderer.js b/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/renderer.js
index 5fa5d2e..196a514 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/renderer.js
+++ b/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/renderer.js
@@ -18,7 +18,7 @@
export default function doRender(data, selector, onRequestDetail) {
- const width = '100vw', height = '100vh';
+ const width = '1200', height = '960';
d3.select(selector).select('*').remove();
const svg =
@@ -30,7 +30,8 @@ export default function doRender(data, selector, onRequestDetail) {
const container = svg.append('g');
const zoom =
d3.behavior.zoom()
- .scaleExtent([1 / 10, 4])
+ .scale(1/10)
+ .scaleExtent([1 / 10, 1])
.on('zoom', () => {
container.attr('transform', `translate(${d3.event.translate}) scale(${d3.event.scale})`);
});
@@ -58,7 +59,7 @@ export default function doRender(data, selector, onRequestDetail) {
.enter()
.insert('path', ':first-child')
.attr('class', 'edge')
- .attr('d', d => getConnectionPath(d, svg, container));
+ .attr('d', d => (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) ? getConnectionPathFF(d, svg, container) : getConnectionPath(d, svg, container));
reset(zoom, svg, container);
@@ -273,7 +274,51 @@ function reset(zoom, svg, container) {
.call( zoom.event );
}
-function getConnectionPath(connector, svg, container) {
+function getConnectionPathFF(connector, svg, container) {
+ const source = container.select(`#${connector._source._uuid}`).node();
+ const target = container.select(`#${connector._target._uuid}`).node();
+ const rSource = d3.select(source).data()[0];
+ const rTarget = d3.select(target).data()[0];
+ const rSourceVertex = d3.select($(source).closest('.vertex').get(0)).data()[0];
+ const rTargetVertex = d3.select($(target).closest('.vertex').get(0)).data()[0];
+
+ const offsetBox = $(container.node()).children('.vertex').get(0).getBoundingClientRect();
+
+
+ const pSource = {
+ x: offsetBox.left - 200 + (rSourceVertex._X + (rSourceVertex._widthOfSelf - (rSource._indexX + 1))) * 200 + 140 / 2,
+ y: offsetBox.top + (rSourceVertex._Y + rSource._indexY) * 100 + 55 / 2,
+ };
+ const pTarget = {
+ x: offsetBox.left - 200 + (rTargetVertex._X + (rTargetVertex._widthOfSelf - (rTarget._indexX + 1))) * 200 + 140 / 2,
+ y: offsetBox.top + (rTargetVertex._Y + rTarget._indexY) * 100 + 55 / 2,
+ };
+ const path = [
+ pTarget
+ ];
+ const junctionXMultiplier = (pTarget.x - pSource.x < 0) ? +1 : -1;
+ if(pSource.y !== pTarget.y) {
+ path.push({
+ x: pTarget.x + junctionXMultiplier * 90,
+ y: pTarget.y
+ }, {
+ x: pTarget.x + junctionXMultiplier * 90,
+ y: pSource.y
+ });
+ }
+ path.push(pSource);
+ const offsetY = svg.node().getBoundingClientRect().top;
+ return path.reduce((accumulator, cPoint, index) => {
+ if(index === 0) {
+ return accumulator + `M ${cPoint.x}, ${cPoint.y - offsetY}\n`
+ } else {
+ return accumulator + `L ${cPoint.x}, ${cPoint.y - offsetY}\n`
+ }
+ }, '');
+}
+
+
+function getConnectionPath(connector, svg, container){
const operators = container.selectAll('.operator');
const source = container.select(`#${connector._source._uuid}`);
const target = container.select(`#${connector._target._uuid}`);
@@ -317,7 +362,7 @@ function doClean(node) {
} else {
return (
Object.keys(node)
- .filter(cNodeKey => cNodeKey !== '_children' && cNodeKey !== '_uuid')
+ .filter(cNodeKey => cNodeKey === '_operator' || !cNodeKey.startsWith('_'))
.reduce((accumulator, cNodeKey) => {
accumulator[cNodeKey] = node[cNodeKey];
return accumulator;
http://git-wip-us.apache.org/repos/asf/ambari/blob/da9086dc/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/transformer.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/transformer.js b/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/transformer.js
index 70647a8..01d6000 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/transformer.js
+++ b/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/transformer.js
@@ -17,7 +17,7 @@
*/
import doEnhance from './enhancer';
-import {getProcessedVertices} from './processor';
+import {getProcessedVertices, getEdgesWithCorrectedUnion} from './processor';
export default function doTransform(data) {
const plan = getTezPlan(data);
@@ -29,22 +29,23 @@ export default function doTransform(data) {
];
const tezEdges = getEdges(plan, vertices);
- const edges = getEdgesWithFetch(tezEdges, vertices);
+ const edgesWithCorrectedUnion = getEdgesWithCorrectedUnion(tezEdges);
+ const edges = getEdgesWithFetch(edgesWithCorrectedUnion, vertices);
const enhancedVertices = doEnhance(vertices);
const processedVertices = getProcessedVertices(enhancedVertices, edges);
+ const verticesWithIndexOfChildren = getVerticesWithIndexOfChildren(processedVertices);
const tree = getVertexTree(edges);
- const connections = getConnections(processedVertices, edges);
- const treeWithOffsetY = getTreeWithOffsetAndHeight(tree, processedVertices, connections);
+ const connections = getConnections(verticesWithIndexOfChildren, edges);
+ const treeWithOffsetY = getTreeWithOffsetAndHeight(tree, verticesWithIndexOfChildren, connections);
-
- const nodes = getNodes(processedVertices);
+ const nodes = getNodes(verticesWithIndexOfChildren);
return ({
- vertices: processedVertices,
+ vertices: verticesWithIndexOfChildren,
edges,
tree: treeWithOffsetY,
nodes,
@@ -52,6 +53,32 @@ export default function doTransform(data) {
});
}
+function getVerticesWithIndexOfChildren(vertices) {
+ const verticesWithIndexX = vertices.map(cVertex => Object.assign({}, cVertex, {
+ _children: doGetChildrenWithIndexX(cVertex._children, 0)
+ }));
+
+ const verticesWithIndexY = verticesWithIndexX.map(cVertex => Object.assign({}, cVertex, {
+ _children: doGetChildrenWithIndexY(cVertex._children, 0)
+ }));
+
+ return verticesWithIndexY;
+}
+
+function doGetChildrenWithIndexX(children, cIndex) {
+ return children.map(cChild => Object.assign({}, cChild, {
+ _indexX: cIndex,
+ _children: doGetChildrenWithIndexX(cChild._children, cIndex + 1)
+ }))
+}
+
+function doGetChildrenWithIndexY(children, cIndex) {
+ return children.map((cChild, index) => Object.assign({}, cChild, {
+ _indexY: cIndex + index,
+ _children: doGetChildrenWithIndexY(cChild._children, cIndex + index)
+ }))
+}
+
function getTezPlan(data) {
const stages = data['STAGE PLANS'];
const tezStageKey = Object.keys(stages).find(cStageKey => stages[cStageKey].hasOwnProperty('Tez'));
@@ -179,21 +206,17 @@ function doHarmonize(nodes) {
});
}
-function doGetHeightOfNodes(children) {
- if(children.length > 0) {
- return children.reduce((height, cChild) => height + doGetHeightOfNodes(cChild._children), 0);
- }
- return 1;
-}
-
function getTreeWithOffsetAndHeight(node, vertices, connections) {
- const treeWithCumulativeHeight = getTreeWithCumulativeHeight(node, vertices);
- const treeWithCumulativeWidth = getTreeWithIndividualWidth(treeWithCumulativeHeight, vertices);
- const treeWithOffsetY = Object.assign({}, getTreeWithOffsetYInHiererchy(treeWithCumulativeWidth, connections), {
+ const treeWithCumulativeHeight = getTreeWithCumulativeHeight(node, vertices, connections);
+ const treeWithIndividualWidth = getTreeWithIndividualWidth(treeWithCumulativeHeight, vertices);
+ //const treeWithCumulativeWidth = getTreeWithCumulativeWidth(treeWithIndividualWidth);
+ const treeWithOffsetY = Object.assign({}, getTreeWithOffsetYInHiererchy(treeWithIndividualWidth, connections), {
_offsetY: 0
});
+ const treeWithEffectiveOffsetX = getTreeWithEffectiveOffsetX(treeWithOffsetY, 0);
+ const treeWithEffectiveOffsetY = getTreeWithEffectiveOffsetY(treeWithEffectiveOffsetX, 0);
- return treeWithOffsetY;
+ return treeWithEffectiveOffsetY;
}
function doGetWidthOfNodes(children = []) {
@@ -203,15 +226,50 @@ function doGetWidthOfNodes(children = []) {
return 1 + Math.max(0, ...children.map(cChild => doGetWidthOfNodes(cChild._children)));
}
-function getTreeWithCumulativeHeight(node, vertices) {
+function getTreeWithEffectiveOffsetX(node, positionX) {
+ const _vertices = node._vertices.map(cVertex => getTreeWithEffectiveOffsetX(cVertex, positionX + node._widthOfSelf));
+
+ return Object.assign({}, node, {
+ _X: positionX,
+ _vertices,
+ });
+}
+
+function getTreeWithEffectiveOffsetY(node, positionY) {
+ const _vertices = node._vertices.map(cVertex => getTreeWithEffectiveOffsetY(cVertex, positionY + cVertex._offsetY));
+
+ return Object.assign({}, node, {
+ _Y: positionY,
+ _vertices,
+ });
+}
+
+function doGetHeightOfNodes(children) {
+ if(children.length > 0) {
+ return children.reduce((height, cChild) => height + doGetHeightOfNodes(cChild._children), 0);
+ }
+ return 1;
+}
+
+function getTreeWithCumulativeHeight(node, vertices, connections) {
const vertexKey = node._vertex;
const vertex = vertices.find(cVertex => cVertex._vertex === vertexKey);
+ // if does not overlap > add 1
+ const vertexNext = node._vertices[0] && vertices.find(cVertex => cVertex._vertex === node._vertices[0]._vertex);
+ const source = vertexNext && getLastOperatorOf(vertexNext);
+ const target = getFirstOperatorOf(vertex);
+ const isFirstConnectedToLast = connections.some(cConnection => source && target && cConnection._source._uuid === source._uuid && cConnection._target._uuid === target._uuid);
+
+
let _height = doGetHeightOfNodes(vertex._children);
let _vertices = [];
if(Array.isArray(node._vertices)){
- _vertices = node._vertices.map(cVertex => getTreeWithCumulativeHeight(cVertex, vertices));
- _height = Math.max(_height, _vertices.reduce((height, cVertex) => height + cVertex._height, 1));
+ _vertices = node._vertices.map(cVertex => getTreeWithCumulativeHeight(cVertex, vertices, connections));
+ _height = Math.max(_height, _vertices.reduce((height, cVertex) => height + cVertex._height, 0));
+ }
+ if(source && !isFirstConnectedToLast) {
+ _height = _height + 1;
}
return Object.assign({}, node, vertex, {
_height,
@@ -288,20 +346,7 @@ function getEdges(plan, vertices) {
}
}, []);
- const edgesWithFixedUnions =
- edges
- .map(cEdge => {
- if(cEdge.type === 'CONTAINS') {
- return Object.assign({}, cEdge, {
- _source: cEdge._target,
- _target: cEdge._source,
- });
- } else {
- return cEdge;
- }
- });
-
- return edgesWithFixedUnions;
+ return edges;
}
function doCloneAndOmit(obj, keys) {