You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2014/08/14 15:19:43 UTC
[3/6] AMBARI-6840. Jobs View: Update Top Nav rendering for jobs
(srimanth)
http://git-wip-us.apache.org/repos/asf/ambari/blob/2f5ee092/ambari-web/app/views/main/jobs/hive_job_details_tez_dag_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/jobs/hive_job_details_tez_dag_view.js b/ambari-web/app/views/main/jobs/hive_job_details_tez_dag_view.js
deleted file mode 100644
index 3ce60b5..0000000
--- a/ambari-web/app/views/main/jobs/hive_job_details_tez_dag_view.js
+++ /dev/null
@@ -1,946 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with this
- * work for additional information regarding copyright ownership. The ASF
- * licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-var App = require('app');
-var date = require('utils/date');
-var numberUtils = require('utils/number_utils');
-var stringUtils = require('utils/string_utils');
-
-App.MainHiveJobDetailsTezDagView = Em.View.extend({
- templateName : require('templates/main/jobs/hive_job_details_tez_dag'),
- selectedVertex : null,
- summaryMetricType: null,
- svgVerticesLayer : null, // The contents of the <svg> element.
- svgTezRoot: null,
- svgWidth : -1,
- svgHeight : -1,
-
- // zoomScaleFom: -1, // Bound from parent view
- // zoomScaleTo: -1, // Bound from parent view
- // zoomScale: -1, // Bound from parent view
- zoomTranslate: [0, 0],
- zoomBehavior: null,
- svgCreated: false,
-
- content : null,
-
- /**
- * Populated by #drawTezDag()
- *
- * {
- * "nodes": [
- * {
- * "id": "Map2",
- * "name": "Map 2",
- * "type": App.TezDagVertexType.MAP,
- * "operations": [
- * "TableScan",
- * "File Output"
- * ],
- * "depth": 1,
- * "parents": [],
- * "children": [],
- * "x": 0,
- * "y": 0,
- * "metricDisplay": "100MB",
- * "metricPercent": 64,
- * "metricType": "Input",
- * "selected": true,
- * "fixed": true,
- * "metrics": {
- * "input": 40022,
- * "output": 224344,
- * "recordsRead": 200,
- * "recordsWrite": 122,
- * "tezTasks": 2
- * }
- * }
- * ],
- * "links": [
- * {
- * "source": {},
- * "target": {},
- * "edgeType": "BROADCAST"
- * }
- * ]
- * }
- */
- dagVisualModel : {
- nodes : [],
- links : [],
- maxMetrics : {},
- minMetrics: {}
- },
-
- didInsertElement : function() {
- this._super();
- this.createSvg();
- },
-
- willDestroyElement : function() {
- $('.svg-tooltip').tooltip('destroy');
- },
-
- createSvg : function() {
- var self = this;
- var dagVisualModel = this.get('dagVisualModel');
- dagVisualModel.nodes.clear();
- dagVisualModel.links.clear();
- dagVisualModel.maxMetrics = {};
- dagVisualModel.minMetrics = {};
-
- this.set('content', this.get('controller.content'));
- var svg = d3.select("#tez-dag-svg");
- d3.selectAll(".tez-dag-canvas").remove();
- var tezRoot = svg.append("svg:g").attr("class", "tez-root");
- this.set('svgTezRoot', tezRoot);
- var tezRootRect = tezRoot.append("rect").attr("class", "tez-root-rect");
- this.set('svgVerticesLayer', tezRoot.append("svg:g").attr("class", "tez-dag-canvas"));
- this.adjustGraphHeight();
- var canvasSize = this.drawTezDag();
- var minScale = Math.min(this.get('svgHeight') / canvasSize.height, this.get('svgWidth') / canvasSize.width);
- if (minScale > 1) {
- minScale = 1;
- }
- tezRootRect.attr("width", canvasSize.width).attr("height", canvasSize.height);
- var zoom = d3.behavior.zoom().scaleExtent([ minScale, 2 ]).on("zoom", function() {
- tezRoot.attr("transform", "translate(" + (d3.event.translate) + ")scale(" + d3.event.scale + ")");
- self.set('zoomScale', d3.event.scale);
- self.set('zoomTranslate', d3.event.translate);
- });
- svg.call(zoom);
- this.set('zoomBehavior', zoom);
- this.set('zoomTranslate', [0, 0]);
- this.set('zoomScaleFrom', minScale);
- this.set('zoomScaleTo', 2);
- this.set('zoomScale', minScale);
- this.set('svgCreated', true);
- },
-
- zoomScaleObserver : function() {
- var tezRoot = this.get("svgTezRoot");
- var newScale = this.get('zoomScale');
- var newScaleFrom = this.get('zoomScaleFrom');
- var newScaleTo = this.get('zoomScaleTo');
- var zoomTranslate = this.get('zoomTranslate');
- var zoomBehavior = this.get('zoomBehavior');
- if (d3.event == null && this.get('svgCreated')) {
- // Values were set from actions instead of UI events
- // We need to center in on selected vertex if available.
- var selectedNode = null;
- var dagVisualModel = this.get('dagVisualModel');
- if (dagVisualModel && dagVisualModel.nodes && dagVisualModel.nodes.length > 0) {
- dagVisualModel.nodes.every(function(node) {
- if (node.selected) {
- selectedNode = node;
- return false;
- }
- return true;
- })
- }
- if (selectedNode != null) {
- var cX = selectedNode.x + selectedNode.width / 2;
- var cY = selectedNode.y + selectedNode.height / 2;
- var mX = (cX * zoomBehavior.scale()) + zoomTranslate[0];
- var mY = (cY * zoomBehavior.scale()) + zoomTranslate[1];
- var pX = (cX * newScale) + zoomTranslate[0];
- var pY = (cY * newScale) + zoomTranslate[1];
- var nX = (mX - pX);
- var nY = (mY - pY);
- zoomTranslate[0] += nX;
- zoomTranslate[1] += nY;
- this.set('zoomTranslate', zoomTranslate);
- }
- }
- console.debug("zoomScaleObserver(): New scale = " + newScale + ", Range = [" + newScaleFrom + ", " + newScaleTo + "]. Translate = ", zoomTranslate.join(','));
- zoomBehavior.scale(newScale);
- zoomBehavior.translate(zoomTranslate);
- tezRoot.attr("transform", "translate(" + zoomTranslate + ")scale(" + newScale + ")");
- }.observes('zoomScale', 'zoomScaleFrom', 'zoomScaleTo', 'zoomTranslate'),
-
- /**
- * We have to make the height of the DAG section match the height of the
- * Summary section.
- */
- adjustGraphHeight : function() {
- var rhsDiv = document.getElementById('tez-vertices-rhs');
- var lhsDiv = document.getElementById('tez-dag-section');
- if (lhsDiv && rhsDiv) {
- var rhsHeight = rhsDiv.clientHeight - 26; // box boundary
- var currentWidth = lhsDiv.clientWidth;
- var currentHeight = lhsDiv.clientHeight;
- $(lhsDiv).attr('style', "height:" + rhsHeight + "px;");
- var svgHeight = rhsHeight - 20;
- d3.select("#tez-dag-svg").attr('height', svgHeight).attr('width', '100%');
- this.set('svgWidth', currentWidth);
- this.set('svgHeight', svgHeight);
- console.log("SVG Width=", currentWidth, ", Height=", svgHeight);
- }
- },
-
- vertexSelectionUpdated : function() {
- var vertexId = this.get('selectedVertex.id');
- var zoomTranslate = [];
- var zoomBehavior = this.get('zoomBehavior');
- var selectedNode = this.get('dagVisualModel').nodes.findProperty('id', vertexId);
- var dagVisualModel = this.get('dagVisualModel');
- if (dagVisualModel && dagVisualModel.nodes && dagVisualModel.nodes.length > 0) {
- dagVisualModel.nodes.forEach(function(node) {
- node.selected = node.id == vertexId;
- console.log("vertexSelectionUpdated(): Updated ",node.id," to ",node.selected);
- })
- }
- if(!this.get('selectedVertex.notTableClick')){
- var cX = selectedNode.x + (selectedNode.width) / 2;
- var cY = selectedNode.y + (selectedNode.height) / 2;
- zoomTranslate[0] = (225 / zoomBehavior.scale() -cX) ;
- zoomTranslate[1] = (250 / zoomBehavior.scale() -cY) ;
- this.set('zoomTranslate', [0,0]);
- this.get('svgVerticesLayer').attr("transform", "translate(0,0)");
- this.get('svgVerticesLayer').attr("transform", "translate("+zoomTranslate[0]+","+zoomTranslate[1]+")");
- }
- this.refreshGraphUI();
- }.observes('selectedVertex'),
-
- summaryMetricTypeUpdated : function() {
- var summaryMetricType = this.get('summaryMetricType');
- var dagVisualModel = this.get('dagVisualModel');
- var min = dagVisualModel.minMetrics[summaryMetricType];
- var max = dagVisualModel.maxMetrics[summaryMetricType];
- dagVisualModel.nodes.forEach(function(node) {
- var value = node.metrics[summaryMetricType];
- var percent = -1;
- if (numberUtils.validateInteger(value)==null && value >= 0) {
- if (numberUtils.validateInteger(min) == null && numberUtils.validateInteger(max) == null) {
- if (max > min && value >= 0) {
- percent = Math.round((value - min) * 100 / (max - min));
- }
- }
- } else {
- value = '';
- }
- switch (summaryMetricType) {
- case "input":
- case "output":
- value = numberUtils.bytesToSize(value);
- break;
- default:
- break;
- }
- node.metricType = Em.I18n.t('jobs.hive.tez.metric.' + summaryMetricType);
- node.metricDisplay = value;
- node.metricPercent = percent;
- });
- this.refreshGraphUI();
- }.observes('summaryMetricType'),
-
- /**
- * Observes metrics of all vertices.
- */
- vertexMetricsUpdated : function() {
- var dagVisualModel = this.get('dagVisualModel');
- dagVisualModel.minMetrics = {
- input : Number.MAX_VALUE,
- output : Number.MAX_VALUE,
- recordsRead : Number.MAX_VALUE,
- recordsWrite : Number.MAX_VALUE,
- tezTasks : Number.MAX_VALUE,
- spilledRecords : Number.MAX_VALUE
- };
- dagVisualModel.maxMetrics = {
- input : 0,
- output : 0,
- recordsRead : 0,
- recordsWrite : 0,
- tezTasks : 0,
- spilledRecords : 0
- };
- if (dagVisualModel.nodes) {
- dagVisualModel.nodes.forEach(function(node) {
- var vertex = App.TezDagVertex.find(node.id);
- if (vertex) {
- node.metrics['input'] = vertex.get('fileReadBytes') + vertex.get('hdfsReadBytes');
- node.metrics['output'] = vertex.get('fileWriteBytes') + vertex.get('hdfsWriteBytes');
- node.metrics['recordsRead'] = vertex.get('recordReadCount');
- node.metrics['recordsWrite'] = vertex.get('recordWriteCount');
- node.metrics['tezTasks'] = vertex.get('tasksCount');
- node.metrics['spilledRecords'] = vertex.get('spilledRecords');
- node.state = vertex.get('state');
- // Min metrics
- dagVisualModel.minMetrics.input = Math.min(dagVisualModel.minMetrics.input, node.metrics.input);
- dagVisualModel.minMetrics.output = Math.min(dagVisualModel.minMetrics.output, node.metrics.output);
- dagVisualModel.minMetrics.recordsRead = Math.min(dagVisualModel.minMetrics.recordsRead, node.metrics.recordsRead);
- dagVisualModel.minMetrics.recordsWrite = Math.min(dagVisualModel.minMetrics.recordsWrite, node.metrics.recordsWrite);
- dagVisualModel.minMetrics.tezTasks = Math.min(dagVisualModel.minMetrics.tezTasks, node.metrics.tezTasks);
- dagVisualModel.minMetrics.spilledRecords = Math.min(dagVisualModel.minMetrics.spilledRecords, node.metrics.spilledRecords);
- // Max metrics
- dagVisualModel.maxMetrics.input = Math.max(dagVisualModel.maxMetrics.input, node.metrics.input);
- dagVisualModel.maxMetrics.output = Math.max(dagVisualModel.maxMetrics.output, node.metrics.output);
- dagVisualModel.maxMetrics.recordsRead = Math.max(dagVisualModel.maxMetrics.recordsRead, node.metrics.recordsRead);
- dagVisualModel.maxMetrics.recordsWrite = Math.max(dagVisualModel.maxMetrics.recordsWrite, node.metrics.recordsWrite);
- dagVisualModel.maxMetrics.tezTasks = Math.max(dagVisualModel.maxMetrics.tezTasks, node.metrics.tezTasks);
- dagVisualModel.maxMetrics.spilledRecords = Math.max(dagVisualModel.maxMetrics.spilledRecords, node.metrics.spilledRecords);
- }
- });
- }
- Ember.run.once(this, 'summaryMetricTypeUpdated');
- }.observes('content.tezDag.vertices.@each.fileReadBytes', 'content.tezDag.vertices.@each.fileWriteBytes',
- 'content.tezDag.vertices.@each.hdfsReadBytes', 'content.tezDag.vertices.@each.hdfsWriteBytes',
- 'content.tezDag.vertices.@each.recordReadCount', 'content.tezDag.vertices.@each.recordWriteCount',
- 'content.tezDag.vertices.@each.state', 'content.tezDag.vertices.@each.spilledRecords'),
-
- createOperationPlanObj: function (vertexName, op, opIndex) {
- var operatorPlanObj = [];
- var text = this.get('content.tezDag.vertices').findProperty('name', vertexName).get('operationPlan');
- text = text.replace(/:"/g,'"').replace(/([:,])(?=\S)/g,'$1 ');
- var jsonText = $.parseJSON(text);
- if (!opIndex) {
- opIndex = 0;
- } else {
- opIndex = parseInt(opIndex) - 1;
- }
- var jsonText = op.findIn(jsonText, opIndex);
- if (jsonText!=null) {
- for (var key in jsonText) {
- if (jsonText.hasOwnProperty(key) && typeof(jsonText[key]) == "string") {
- operatorPlanObj.push(
- {
- name: key,
- value: jsonText[key]
- }
- );
- }
- }
- }
- return operatorPlanObj;
- },
-
- /**
- * Determines layout and creates Tez graph. In the process it populates the
- * visual model into 'dagVisualModel' field.
- *
- * Terminology: 'vertices' and 'edges' are Tez terms. 'nodes' and 'links' are
- * visual (d3) terms.
- */
- drawTezDag : function() {
- var self = this;
- var width = this.get('svgWidth');
- var svgLayer = this.get('svgVerticesLayer');
- var vertices = this.get('content.tezDag.vertices');
- var edges = this.get('content.tezDag.edges');
- var constants = this.get('constants');
- var vertexIdToNode = {};
- var depthToNodes = []; // Array of id arrays
- var dagVisualModel = this.get('dagVisualModel');
- var selectedVertex = this.get('selectedVertex');
- var minVertexDuration = Number.MAX_VALUE;
- var maxVertexDuration = Number.MIN_VALUE;
-
- //
- // CALCULATE DEPTH - BFS to get correct graph depth
- //
- var visitEdges = [];
- var maxRowLength = 0;
- var maxRowDepth = 0;
- vertices.forEach(function(v) {
- if (v.get('incomingEdges.length') < 1) {
- visitEdges.push({
- depth : 0,
- parent : null,
- toVertex : v
- });
- }
- });
- function getNodeFromEdge(edgeObj) {
- var vertex = edgeObj.toVertex;
- var pName = edgeObj.parent ? edgeObj.parent.name : null;
- var cName = edgeObj.toVertex ? edgeObj.toVertex.get('name') : null;
- console.debug("Processing vertex ", edgeObj, " (",pName, " > ", cName,")");
- if(edgeObj.parent && edgeObj.depth < edgeObj.parent.depth + 1){
- console.debug("Updating child edge to " + (edgeObj.parent.depth + 1));
- edgeObj.depth = edgeObj.parent.depth + 1;
- }
- var node = vertexIdToNode[vertex.get('id')];
- for ( var k = depthToNodes.length; k <= edgeObj.depth; k++) {
- depthToNodes.push([]);
- }
- if (!node) {
- // New node
- node = {
- id : vertex.get('id'),
- name : vertex.get('name'),
- state : vertex.get('state'),
- type : vertex.get('type'),
- operations : vertex.get('operations'),
- depth : edgeObj.depth,
- parents : [],
- children : [],
- x : 0,
- y : 0,
- metricType : null,
- metricDisplay : null,
- metricPercent : -1,
- selected : selectedVertex != null ? selectedVertex.get('id') == vertex.get('id') : false,
- fixed : true,
- metrics : {
- input : -1,
- output : -1,
- recordsRead : -1,
- recordsWrite : -1,
- tezTasks : -1
- },
- duration: vertex.get('duration')
- }
- if (node.duration < minVertexDuration && node.duration > 0) {
- minVertexDuration = node.duration;
- }
- if (node.duration > maxVertexDuration && node.duration > 0) {
- maxVertexDuration = node.duration;
- }
- vertexIdToNode[vertex.get('id')] = node;
- depthToNodes[node.depth].push(node);
- } else {
- // Existing node
- if (edgeObj.depth > node.depth) {
- function moveNodeToDepth(node, newDepth) {
- console.debug("Moving " + node.name + " from depth " + node.depth + " to " + newDepth);
- var oldIndex = depthToNodes[node.depth].indexOf(node);
- depthToNodes[node.depth].splice(oldIndex, 1);
- node.depth = newDepth;
- if (!depthToNodes[node.depth]) {
- depthToNodes[node.depth] = [];
- }
- depthToNodes[node.depth].push(node);
- if (node.children) {
- // Move children down depth
- node.children.forEach(function(c) {
- moveNodeToDepth(c, node.depth + 1);
- })
- }
- }
- moveNodeToDepth(node, edgeObj.depth);
- }
- }
- if (depthToNodes[node.depth].length > maxRowLength) {
- maxRowLength = depthToNodes[node.depth].length;
- maxRowDepth = node.depth;
- }
- if (edgeObj.parent != null) {
- node.parents.push(edgeObj.parent);
- edgeObj.parent.children.push(node);
- }
- return node;
- }
- var edgeObj;
- var visitedVertexMap = {};
- while (edgeObj = visitEdges.shift()) {
- var node = getNodeFromEdge(edgeObj);
- if (!visitedVertexMap[edgeObj.toVertex.get('id')]) {
- visitedVertexMap[edgeObj.toVertex.get('id')] = true;
- var outEdges = edgeObj.toVertex.get('outgoingEdges');
- outEdges.forEach(function(oe) {
- var childVertex = oe.get('toVertex');
- visitEdges.push({
- depth : node.depth + 1,
- parent : node,
- toVertex : childVertex
- });
- });
- }
- }
- edges.forEach(function(e) {
- dagVisualModel.links.push({
- source : vertexIdToNode[e.get('fromVertex.id')],
- target : vertexIdToNode[e.get('toVertex.id')],
- edgeType : e.get('edgeType')
- });
- });
- // Sort nodes so that parents stay together
- for ( var depth = 0; depth < depthToNodes.length; depth++) {
- var nodes = depthToNodes[depth];
- nodes.sort(function(n1, n2) {
- var ck1 = '';
- var ck2 = '';
- if (n1.children) {
- n1.children.forEach(function(c) {
- ck1 += c.name;
- });
- }
- if (n2.children) {
- n2.children.forEach(function(c) {
- ck2 += c.name;
- });
- }
- if (ck1 < ck2) {
- return -1
- }
- if (ck1 > ck2) {
- return 1
- }
- return 0
- });
- depthToNodes[depth] = nodes;
- }
-
- //
- // LAYOUT - Now with correct depth, we calculate layouts
- //
- // When a node's effective width changes, all its parent nodes are updated.
- var updateNodeEffectiveWidth = function(node, newEffectiveWidth) {
- console.debug("Updating effective width of (" + node.id + ") to " + newEffectiveWidth);
- if (numberUtils.validateInteger(node.effectiveWidth) != null) {
- node.effectiveWidth = newEffectiveWidth;
- }
- var diff = newEffectiveWidth - node.effectiveWidth;
- if (diff > 0) {
- var oldEffectiveWidth = node.effectiveWidth;
- node.effectiveWidth = newEffectiveWidth;
- if (node.parents != null) {
- node.parents.forEach(function(parent) {
- updateNodeEffectiveWidth(parent, parent.effectiveWidth + diff);
- })
- }
- }
- }
- var xGap = 20;
- var yGap = 70;
- var currentY = 40;
- // First pass - calculate layout widths, and Y coordinates
- for ( var depth = 0; depth < depthToNodes.length; depth++) {
- var nodes = depthToNodes[depth];
- var maxNodeHeight = 0;
- for ( var nodeIndex = 0; nodeIndex < nodes.length; nodeIndex++) {
- var node = nodes[nodeIndex];
- var nodeDim = this.getNodeCalculatedDimensions(node, minVertexDuration, maxVertexDuration);
- node.drawWidth = nodeDim.drawWidth;
- node.drawHeight = nodeDim.drawHeight;
- node.scale = nodeDim.scale;
- node.width = nodeDim.width;
- node.height = nodeDim.height;
- if (maxNodeHeight < node.height) {
- maxNodeHeight = node.height;
- }
- if (depth == 0) {
- // Top nodes - position uniformly
- updateNodeEffectiveWidth(node, xGap + node.width);
- }
- if (node.children && node.children.length > 0) {
- // There can be dedicated or shared children.
- // Dedicated children increase effective width of parent by their
- // width.
- // Shared children increase effective width of parent only by the
- // fraction of parentage
- var childrenWidth = 0;
- node.children.forEach(function(child) {
- var childDim = self.getNodeCalculatedDimensions(child, minVertexDuration, maxVertexDuration);
- childrenWidth += ((childDim.width + xGap) / child.parents.length);
- });
- updateNodeEffectiveWidth(node, Math.max(childrenWidth, (node.width+xGap)));
- } else {
- updateNodeEffectiveWidth(node, xGap + node.width);
- }
- node.y = currentY;
- node.incomingY = node.y;
- node.outgoingY = node.incomingY + node.height;
- }
- currentY += maxNodeHeight;
- currentY += yGap;
- }
- // Second pass - determine actual X coordinates
- var maxX = 0;
- for ( var depth = 0; depth < depthToNodes.length; depth++) {
- var nodes = depthToNodes[depth];
- var currentX = -1;
- var parentCurrentXMap = {};
- for ( var nodeIndex = 0; nodeIndex < nodes.length; nodeIndex++) {
- var node = nodes[nodeIndex];
- var parentsKey = null;
- if (node.parents != null && node.parents.length > 0) {
- var parentMidX = 0;
- var parentsKey = '';
- var childrenEffectiveWidth = -1;
- node.parents.forEach(function(parent) {
- parentMidX += (parent.x + (parent.width / 2));
- parentsKey += (parent.id + '//');
- if (childrenEffectiveWidth < 0) {
- parent.children.forEach(function(c){
- childrenEffectiveWidth += (c.effectiveWidth);
- });
- }
- });
- parentMidX = parentMidX / node.parents.length;
- var parentCurrentX = parentCurrentXMap[parentsKey];
- if (parentCurrentX == null || parentCurrentX == undefined) {
- parentCurrentX = parentMidX - (childrenEffectiveWidth/2);
- parentCurrentXMap[parentsKey] = parentCurrentX;
- }
- currentX = parentCurrentX;
- } else {
- if (currentX < 0) {
- currentX = 0;
- }
- }
- node.x = (currentX + (node.effectiveWidth - node.width) / 2);
- node.outgoingX = (node.x + node.width / 2);
- node.incomingX = node.outgoingX;
- console.log("drawTezDag(). Layout Node: ", node);
- dagVisualModel.nodes.push(node);
- if (parentsKey != null) {
- parentCurrentXMap[parentsKey] = currentX + node.effectiveWidth;
- } else {
- currentX += node.effectiveWidth;
- }
- if ((node.x + node.width) > maxX) {
- maxX = node.x + node.width;
- }
- }
- }
- var canvasHeight = currentY;
- var canvasWidth = maxX + (xGap << 1);
-
- //
- // Draw SVG
- //
- var force = d3.layout.force().nodes(dagVisualModel.nodes).links(dagVisualModel.links).start();
- var nodeDragData = {
- nodeRelativeX : 0,
- nodeRelativeY : 0
- };
- var nodeDrag = d3.behavior.drag().on('dragstart', function(node){
- d3.event.sourceEvent.stopPropagation();
- var rc = d3.mouse(this);
- nodeDragData.nodeRelativeX = (rc[0] * node.scale);
- nodeDragData.nodeRelativeY = (rc[1] * node.scale);
- }).on('drag', function(node){
- var nx = d3.event.x - nodeDragData.nodeRelativeX;
- var ny = d3.event.y - nodeDragData.nodeRelativeY;
- self.dragVertex(d3.select(this), node, [nx, ny], diagonal);
- }).on('dragend', function(){
- nodeDragData.nodeRelativeX = 0;
- nodeDragData.nodeRelativeY = 0;
- });
- // Create Links
- var diagonal = d3.svg.diagonal().source(function(d) {
- return {
- x : d.source.outgoingX,
- y : d.source.outgoingY
- };
- }).target(function(d) {
- return {
- x : d.target.incomingX,
- y : d.target.incomingY - 12
- }
- });
- var link = svgLayer.selectAll(".link-g").data(dagVisualModel.links).enter().append("g").attr("class", "link-g").attr("marker-end", "url(#arrow)");
- link.append("path").attr("class", function(l) {
- var classes = "link svg-tooltip ";
- if (l.edgeType) {
- classes += ("type-" + l.edgeType.toLowerCase() + " ");
- } else {
- classes += "type-unknown ";
- }
- return classes;
- }).attr("d", diagonal).attr("title", function(l) {
- var lower = l.edgeType ? l.edgeType.toLowerCase() : '';
- return Em.I18n.t("jobs.hive.tez.edge." + lower);
- });
- // Create Nodes
- var node = svgLayer.selectAll(".node").data(dagVisualModel.nodes).enter().append("g").attr("class", "node").call(nodeDrag);
- node.append("rect").attr("class", "background").attr("width", function(n) {
- return n.drawWidth;
- }).attr("height", function(n) {
- return n.drawHeight;
- }).attr("rx", "10").attr("filter", "url(#shadow)").on('mousedown', function(n) {
- var vertex = App.TezDagVertex.find(n.id);
- if (vertex != null) {
- self.get('parentView').doSelectVertex({
- context : vertex
- }, true);
- }
- });
- node.each(function(n, nodeIndex) {
- var ops = n.operations;
- var opCount = {};
- if (ops != null && ops.length > 0) {
- var opGroups = d3.select(this).selectAll(".operation").data(ops).enter().append("g").attr("class", "operation").attr("transform", function(op, opIndex) {
- var row = Math.floor(opIndex / 3);
- var column = opIndex % 3;
- return "translate(" + (10 + column * 55) + "," + (37 + row * 20) + ")";
- }).attr("clip-path", "url(#operatorClipPath)").attr("opIndex", function(op){
- if(!opCount[op]) {
- opCount[op] = 1;
- } else {
- opCount[op] = opCount[op]+1;
- }
- return opCount[op];
- }).on('mouseover', function(op) {
- var viewContent = {
- operationName: op,
- operatorPlanObj: []
- };
- var opIndex = this.getAttribute('opIndex');
- var operatorPlanObj = self.createOperationPlanObj(n.name, op, opIndex);
- viewContent.operatorPlanObj = operatorPlanObj;
- var template = App.HoverOpTable.create({content: viewContent}) ;
- $(this).find('.svg-tooltip').attr('title', template.renderToBuffer().string()).tooltip('fixTitle').tooltip('show');
- })
-
- opGroups.append("rect").attr("class", "operation svg-tooltip ").attr("width", "50").attr("height", "16");
- opGroups.append("text").attr("x", "2").attr("dy", "1em").text(function(op) {
- return op != null ? op.split(' ')[0] : '';
- });
- }
- });
- var metricNodes = node.append("g").attr("class", "metric").attr("transform", "translate(112,7)");
- metricNodes.append("rect").attr("width", function(n) {
- if (n.type == App.TezDagVertexType.UNION) {
- return 0;
- }
- return 60;
- }).attr("height", function(n) {
- if (n.type == App.TezDagVertexType.UNION) {
- return 0;
- }
- return 18;
- }).attr("rx", "3").attr("class", "metric-title svg-tooltip");
- metricNodes.append("text").attr("class", "metric-text").attr("x", "2").attr("dy", "1em");
- node.append("text").attr("x", "1.9em").attr("dy", "1.5em").text(function(d) {
- return d.name;
- });
- var iconContainer = node.append('g').attr('class', 'vertex-icon-container').attr('transform', 'translate(10,10)');
- iconContainer.append('rect').attr('width', '1em').attr('height', '1em').attr('class', 'vertex-icon-rect svg-tooltip ');
- iconContainer.append('text').attr('dy', '10px').attr("font-family", "FontAwesome").attr('class', 'vertex-icon-text');
- node.attr("transform", function(d) {
- return "translate(" + d.x + "," + d.y + ") scale("+d.scale+") ";
- });
- this.vertexMetricsUpdated();
- $('.svg-tooltip').each(function() {
- var item = $(this);
- if (item.prop('tagName') == 'path') {
- item.hover(function(e) {
- var offset = $(this).offset();
- item.prop('offsetWidth', function() {
- return 2 * (e.pageX - offset.left);
- });
- item.prop('offsetHeight', function() {
- return 2 * (e.pageY - offset.top);
- });
- });
- };
- if (item.prop('offsetWidth') == undefined) {
- item.prop('offsetWidth', function() {
- return item.width();
- });
- };
- if (item.prop('offsetHeight') == undefined) {
- item.prop('offsetHeight', function() {
- return item.height();
- });
- };
- });
- App.tooltip($('.svg-tooltip'), {
- placement : 'left',
- template: '<div class="tooltip jobs-tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
- });
-
- if (App.supports.debugJobsDag) {
- // Draws node bounding box - for debug purposes
- node.append("rect").attr("width", function(n) {
- return n.effectiveWidth;
- }).attr("height", function(n) {
- return n.height;
- }).attr("x", function(n) {
- return -1 * ((n.effectiveWidth - n.width) / 2);
- }).attr("y", function(n) {
- return 0;
- }).attr("style", "opacity: 0.2;fill:yellow;");
- }
-
- // Position in center
- var translateX = Math.round((width - canvasWidth) / 2);
- if (translateX > 0) {
- svgLayer.attr("transform", "translate("+translateX+",0)");
- }
- return {
- width : canvasWidth,
- height : canvasHeight
- }
- },
-
- dragVertex: function(d3Vertex, node, newPosition, diagonal){
- console.debug("Dragging vertex [", node.name, "] to (", newPosition[0], ",", newPosition[1], ")");
- // Move vertex
- node.x = newPosition[0];
- node.y = newPosition[1];
- node.incomingX = newPosition[0] + (node.width/2);
- node.incomingY = newPosition[1];
- node.outgoingX = newPosition[0] + (node.width/2);
- node.outgoingY = newPosition[1] + node.height;
- d3Vertex.attr('transform', 'translate(' + newPosition[0] + ',' + newPosition[1] + ') scale('+node.scale+') ');
- // Move links
- d3.selectAll('.link').filter(function(l) {
- if (l && (l.source === node || l.target === node)) {
- return this
- }
- return null;
- }).attr('d', diagonal);
- },
-
- /**
- * Refreshes UI of the Tez graph with latest values
- */
- refreshGraphUI: function () {
- var svgLayer = this.get('svgVerticesLayer');
- if (svgLayer!=null) {
- var self = this;
- var metricNodes = svgLayer.selectAll(".metric");
- var metricNodeTexts = svgLayer.selectAll(".metric-text");
- var metricNodeTitles = svgLayer.selectAll(".metric-title");
- var nodeBackgrounds =svgLayer.selectAll(".background");
- var vertexIconTexts = svgLayer.selectAll(".vertex-icon-text");
- var vertexIconRects = svgLayer.selectAll(".vertex-icon-rect");
- metricNodes.attr("class", function(node) {
- var classes = "metric ";
- var percent = node.metricPercent;
- if (numberUtils.validateInteger(percent) == null && percent >= 0) {
- if (percent <= 20) {
- classes += "heat-0-20 ";
- } else if (percent <= 40) {
- classes += "heat-20-40 ";
- } else if (percent <= 60) {
- classes += "heat-40-60 ";
- } else if (percent <= 80) {
- classes += "heat-60-80 ";
- } else if (percent <= 100) {
- classes += "heat-80-100 ";
- } else {
- classes += "heat-none";
- }
- } else {
- classes += "heat-none";
- }
- return classes;
- });
- metricNodeTexts.text(function(node){
- if (node.type == App.TezDagVertexType.UNION) {
- return '';
- }
- return node.metricDisplay;
- });
- metricNodeTitles.attr("title", function(node){
- return node.metricType;
- }).attr("data-original-title", function(node){
- return node.metricType;
- });
- nodeBackgrounds.attr("class", function(n) {
- var classes = "background ";
- if (n.type) {
- classes += (n.type.toLowerCase() + " ");
- } else {
- classes += "unknown-vertex-type ";
- }
- if (n.selected) {
- classes += "selected ";
- }
- return classes;
- });
- vertexIconRects.attr('title', function(node) {
- return stringUtils.getCamelCase(node.state);
- }).attr('data-original-title', function(node) {
- return stringUtils.getCamelCase(node.state);
- });
- vertexIconTexts.text(function(n) {
- return self.getVertexIcon(n)
- }).attr('class', function(n) {
- var classes = 'vertex-icon-text ';
- if (n.state != null) {
- if (n.state == App.TezDagVertexState.JOBFAILED) {
- classes += App.TezDagVertexState.FAILED.toLowerCase();
- } else {
- classes += n.state.toLowerCase();
- };
- };
- return classes;
- });
- }
- },
-
- getVertexIcon : function(node){
- var icon = "";
- switch (node.state) {
- case App.TezDagVertexState.NEW:
- icon = '\uF10C'; //icon-circle-blank
- case App.TezDagVertexState.RUNNING:
- case App.TezDagVertexState.FAILED:
- icon = '\uF111'; //icon-circle
- break;
- case App.TezDagVertexState.SUCCEEDED:
- icon = '\uF00C'; //icon-ok
- break;
- case App.TezDagVertexState.KILLED:
- case App.TezDagVertexState.ERROR:
- icon = '\uF057'; //icon-remove-sign
- break;
- case App.TezDagVertexState.INITED:
- case App.TezDagVertexState.INITIALIZING:
- case App.TezDagVertexState.TERMINATING:
- icon = '\uF141'; //icon-ellipsis-horizontal
- break;
- case App.TezDagVertexState.JOBFAILED:
- icon = '\uF05C'; //icon-remove-circle
- break;
- }
- return icon;
- },
-
- /**
- * Determines the size of a node by taking into account its duration and
- * number of operations performed.
- *
- * @return {Object} Provides various metrics necessary in drawing a node.
- * <code>
- * {
- * width: 360, // Scaled width of the node
- * height: 80, // Scaled height of the node
- * scale: 2, // Scale used on vertex dimensions. Quickest vertex is scaled to 1 and slowest vertex is scaled to 10.
- * drawWidth: 180, // Width of actual drawing (that will be scaled)
- * drawHeight: 40 // Height of actual drawing (that will be scaled)
- * }
- * </code>
- */
- getNodeCalculatedDimensions : function(node, minVertexDuration, maxVertexDuration) {
- var size = {
- width : 180,
- height : 40,
- drawWidth : 180,
- drawHeight : 40,
- scale : 1
- }
- if (node.operations && node.operations.length > 0) {
- var opsHeight = Math.ceil(node.operations.length / 3);
- size.drawHeight += (opsHeight * 20);
- }
- size.width = size.drawWidth * size.scale;
- size.height = size.drawHeight * size.scale;
- return size;
- }
-
-});
-
-App.HoverOpTable = Ember.View.extend({
- templateName : require('templates/main/jobs/hover_op_table')
-});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/2f5ee092/ambari-web/app/views/main/jobs/hive_job_details_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/jobs/hive_job_details_view.js b/ambari-web/app/views/main/jobs/hive_job_details_view.js
deleted file mode 100644
index d22ed20..0000000
--- a/ambari-web/app/views/main/jobs/hive_job_details_view.js
+++ /dev/null
@@ -1,351 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with this
- * work for additional information regarding copyright ownership. The ASF
- * licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-var App = require('app');
-var date = require('utils/date');
-var numberUtils = require('utils/number_utils');
-var dateUtils = require('utils/date');
-var stringUtils = require('utils/string_utils');
-var sort = require('views/common/sort_view');
-
-App.MainHiveJobDetailsView = Em.View.extend({
- templateName : require('templates/main/jobs/hive_job_details'),
-
- selectedVertex : null,
- content : null,
- zoomScaleFrom : 1,
- zoomScaleTo: 2,
- zoomScale : 1,
- showQuery : false,
-
- zoomStep : function() {
- var zoomStep = 0.01;
- var zoomFrom = this.get('zoomScaleFrom');
- var zoomTo = this.get('zoomScaleTo');
- if (zoomFrom < zoomTo) {
- zoomStep = (zoomTo - zoomFrom) / 5;
- }
- return zoomStep;
- }.property('zoomScaleFrom', 'zoomScaleTo'),
- isGraphMaximized: false,
-
- toggleShowQuery : function () {
- this.toggleProperty('showQuery');
- var queryBlock = $('.query-info');
- if (this.get('showQuery')) {
- queryBlock.slideDown();
- } else {
- queryBlock.slideUp();
- };
- },
-
- toggleShowQueryText : function () {
- return this.get('showQuery') ? Em.I18n.t('jobs.hive.less') : Em.I18n.t('jobs.hive.more');
- }.property('showQuery'),
-
- summaryMetricType: 'input',
- summaryMetricTypesDisplay : [
- Em.I18n.t('jobs.hive.tez.metric.input'),
- Em.I18n.t('jobs.hive.tez.metric.output'),
- /* Em.I18n.t('jobs.hive.tez.metric.recordsRead'),
- Em.I18n.t('jobs.hive.tez.metric.recordsWrite'), */
- Em.I18n.t('jobs.hive.tez.metric.tezTasks'),
- Em.I18n.t('jobs.hive.tez.metric.spilledRecords')
- ],
- summaryMetricTypeDisplay: function(){
- return Em.I18n.t('jobs.hive.tez.metric.'+this.get('summaryMetricType'));
- }.property('summaryMetricType'),
-
- sortedVertices : function() {
- var sortColumn = this.get('controller.sortingColumn');
- if(sortColumn && sortColumn.get('status')){
- var sortColumnStatus = sortColumn.get('status');
- var sorted = sortColumn.get('parentView').sort(sortColumn, sortColumnStatus === "sorting_desc", true);
- sortColumn.set('status', sortColumnStatus);
- return sorted;
- }
- var vertices = this.get('controller.content.tezDag.vertices');
- if (vertices != null) {
- vertices = vertices.toArray();
- return vertices;
- }
- return vertices;
- }.property('content.tezDag.vertices','controller.sortingColumn'),
-
- initialDataLoaded : function() {
- var loaded = this.get('controller.loaded');
- if (loaded) {
- this.set('content', this.get('controller.content'));
- }
- }.observes('controller.loaded'),
-
- yarnApplicationIdLink : function() {
- var yarnService = App.YARNService.find().objectAt(0);
- var appId = this.get('content.tezDag.yarnApplicationId');
- if (yarnService != null) {
- var quickLinksView = App.QuickViewLinks.create();
- try {
- quickLinksView.set('content', yarnService);
- quickLinksView.setQuickLinks();
- var links = quickLinksView.get('quickLinks');
- if (links && links.length > 0) {
- var rmUILink = links.findProperty('label', 'ResourceManager UI');
- if (rmUILink != null) {
- return rmUILink.get('url') + '/cluster/app/' + appId;
- }
- }
- } finally {
- quickLinksView.destroy();
- quickLinksView = null;
- }
- }
- return null;
- }.property('content.tezDag.yarnApplicationId', 'App.YARNService.resourceManager.hostName'),
-
- jobObserver : function() {
- var content = this.get('content');
- var selectedVertex = this.get('selectedVertex');
- if (selectedVertex == null && content != null) {
- var vertices = content.get('tezDag.vertices');
- if (vertices) {
- vertices.setEach('isSelected', false);
- this.doSelectVertex({
- context : vertices.objectAt(0)
- }, false);
- }
- }
- }.observes('selectedVertex', 'content.tezDag.vertices.@each.id'),
-
- doSelectVertex : function(event,notTableClick) {
- notTableClick = notTableClick ? true : false;
- var newVertex = event.context;
- var currentVertex = this.get('selectedVertex');
- if (currentVertex != null) {
- currentVertex.set('isSelected', false);
- }
- newVertex.set('notTableClick', notTableClick);
- newVertex.set('isSelected', true);
- this.set('selectedVertex', newVertex);
- },
-
- doSelectSummaryMetricType: function(event) {
- var summaryType = event.context;
- switch (summaryType) {
- case Em.I18n.t('jobs.hive.tez.metric.input'):
- summaryType = 'input';
- break;
- case Em.I18n.t('jobs.hive.tez.metric.output'):
- summaryType = 'output';
- break;
- case Em.I18n.t('jobs.hive.tez.metric.recordsRead'):
- summaryType = 'recordsRead';
- break;
- case Em.I18n.t('jobs.hive.tez.metric.recordsWrite'):
- summaryType = 'recordsWrite';
- break;
- case Em.I18n.t('jobs.hive.tez.metric.tezTasks'):
- summaryType = 'tezTasks';
- break;
- case Em.I18n.t('jobs.hive.tez.metric.spilledRecords'):
- summaryType = 'spilledRecords';
- break;
- default:
- break;
- }
- this.set('summaryMetricType', summaryType);
- },
-
- /**
- * Provides display information for vertex I/O.
- *
- * {
- * 'file': {
- * 'read': {
- * 'ops': '100 reads',
- * 'bytes': '10 MB'
- * }
- * 'write: {
- * 'ops': '200 writes',
- * 'bytes': '20 MB'
- * }
- * },
- * 'hdfs': {
- * 'read': {
- * 'ops': '100 reads',
- * 'bytes': '10 MB'
- * }
- * 'write: {
- * 'ops': '200 writes',
- * 'bytes': '20 MB'
- * }
- * },
- * 'records': {
- * 'read': '100 records',
- * 'write': '123 records'
- * },
- * 'started': 'Feb 12, 2014 10:30am',
- * 'ended': 'Feb 12, 2014 10:35am',
- * 'status': 'Running'
- * }
- */
- selectedVertexIODisplay : function() {
- var v = this.get('selectedVertex');
- var status = v.get('state');
- if (status) {
- status = stringUtils.getCamelCase(status);
- }
- var fileReadOps = v.get('fileReadOps');
- var fileWriteOps = v.get('fileWriteOps');
- var hdfsReadOps = v.get('hdfsReadOps');
- var hdfsWriteOps = v.get('hdfsWriteOps');
- var naString = Em.I18n.t('common.na');
- if (fileReadOps === null) {
- fileReadOps = naString;
- }
- if (fileWriteOps === null) {
- fileWriteOps = naString;
- }
- if (hdfsReadOps === null) {
- hdfsReadOps = naString;
- }
- if (hdfsWriteOps === null) {
- hdfsWriteOps = naString;
- }
- return {
- file : {
- read : {
- ops : Em.I18n.t('jobs.hive.tez.reads').format(fileReadOps),
- bytes : numberUtils.bytesToSize(v.get('fileReadBytes'))
- },
- write : {
- ops : Em.I18n.t('jobs.hive.tez.writes').format(fileWriteOps),
- bytes : numberUtils.bytesToSize(v.get('fileWriteBytes'))
- }
- },
- hdfs : {
- read : {
- ops : Em.I18n.t('jobs.hive.tez.reads').format(hdfsReadOps),
- bytes : numberUtils.bytesToSize(v.get('hdfsReadBytes'))
- },
- write : {
- ops : Em.I18n.t('jobs.hive.tez.writes').format(hdfsWriteOps),
- bytes : numberUtils.bytesToSize(v.get('hdfsWriteBytes'))
- }
- },
- records : {
- read : v.get('recordReadCount') == null ? null : Em.I18n.t('jobs.hive.tez.records.count').format(v.get('recordReadCount')),
- write : v.get('recordWriteCount') == null ? null : Em.I18n.t('jobs.hive.tez.records.count').format(v.get('recordWriteCount'))
- },
- started: v.get('startTime') ? dateUtils.dateFormat(v.get('startTime'), 'ddd, MMM DD, YYYY HH:mm:ss:SSS') : '',
- ended: v.get('endTime') ? dateUtils.dateFormat(v.get('endTime'), 'ddd, MMM DD, YYYY HH:mm:ss:SSS') : '',
- status: status
- };
- }.property('selectedVertex.fileReadOps', 'selectedVertex.fileWriteOps', 'selectedVertex.hdfsReadOps', 'selectedVertex.hdfdWriteOps',
- 'selectedVertex.fileReadBytes', 'selectedVertex.fileWriteBytes', 'selectedVertex.hdfsReadBytes', 'selectedVertex.hdfdWriteBytes',
- 'selectedVertex.recordReadCount', 'selectedVertex.recordWriteCount', 'selectedVertex.status'),
-
- canGraphZoomIn : function() {
- var zoomTo = this.get('zoomScaleTo');
- var zoomScale = this.get('zoomScale');
- console.debug("canGraphZoomIn? : ", (zoomScale < zoomTo), " (scaleTo=", zoomTo,", scale=",zoomScale,")");
- return zoomScale < zoomTo;
- }.property('zoomScale', 'zoomScaleTo'),
-
- canGraphZoomOut : function() {
- var zoomFrom = this.get('zoomScaleFrom');
- var zoomScale = this.get('zoomScale');
- console.debug("canGraphZoomOut? : ", (zoomScale > zoomFrom), " (scaleFrom=", zoomFrom,", scale=",zoomScale,")");
- return zoomScale > zoomFrom;
- }.property('zoomScale', 'zoomScaleFrom'),
-
- doGraphZoomIn: function() {
- var zoomTo = this.get('zoomScaleTo');
- var zoomScale = this.get('zoomScale');
- var zoomStep = this.get('zoomStep');
- if (zoomScale < zoomTo) {
- var step = Math.min(zoomStep, (zoomTo - zoomScale));
- zoomScale += step;
- console.debug("doGraphZoomIn(): New scale = ", zoomScale);
- this.set('zoomScale', zoomScale);
- }
- },
-
- doGraphZoomOut: function() {
- var zoomFrom = this.get('zoomScaleFrom');
- var zoomScale = this.get('zoomScale');
- var zoomStep = this.get('zoomStep');
- if (zoomScale > zoomFrom) {
- var step = Math.min(zoomStep, (zoomScale - zoomFrom));
- zoomScale -= step;
- console.debug("doGraphZoomOut(): New scale = ", zoomScale);
- this.set('zoomScale', zoomScale);
- }
- },
-
- doGraphMaximize: function() {
- this.set('isGraphMaximized', true);
- },
-
- doGraphMinimize: function() {
- this.set('isGraphMaximized', false);
- }
-});
-
-App.MainHiveJobDetailsVerticesTableView = App.TableView.extend({
- sortView: sort.wrapperView,
-
- didInsertElement: function () {
- if(!this.get('controller.sortingColumn')){
- var columns = this.get('childViews')[0].get('childViews');
- if(columns && columns.findProperty('name', 'name')){
- columns.findProperty('name','name').set('status', 'sorting_asc');
- this.get('controller').set('sortingColumn', columns.findProperty('name','name'))
- }
- }
- },
-
- nameSort: sort.fieldView.extend({
- column: 0,
- name: 'name',
- displayName: Em.I18n.t('common.name'),
- type: 'string'
- }),
- tasksSort: sort.fieldView.extend({
- column: 1,
- name: 'tasksNumber',
- displayName: Em.I18n.t('common.tasks'),
- type: 'number'
- }),
- inputSort: sort.fieldView.extend({
- column: 2,
- name: 'totalReadBytes',
- displayName: Em.I18n.t('apps.item.dag.input'),
- type: 'number'
- }),
- outputSort: sort.fieldView.extend({
- column: 3,
- name: 'totalWriteBytes',
- displayName: Em.I18n.t('apps.item.dag.output'),
- type: 'number'
- }),
- durationSort: sort.fieldView.extend({
- column: 4,
- name: 'duration',
- displayName: Em.I18n.t('apps.item.dag.duration'),
- type: 'number'
- })
-});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/2f5ee092/ambari-web/app/views/main/jobs/select_custom_date_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/jobs/select_custom_date_view.js b/ambari-web/app/views/main/jobs/select_custom_date_view.js
deleted file mode 100644
index d0c03ef..0000000
--- a/ambari-web/app/views/main/jobs/select_custom_date_view.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-var date = require('utils/date');
-
-App.JobsCustomDatesSelectView = Em.View.extend({
- name: 'jobsCustomDatesSelectView',
- templateName: require('templates/main/jobs/custom_dates_popup'),
-
- middayPeriodOptions: [Em.I18n.t('jobs.table.custom.date.am'), Em.I18n.t('jobs.table.custom.date.pm')],
-
- hourOptions: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'],
-
- minuteOptions: ['00', '05', '10', '15', '20', '25', '30', '35', '40', '45', '50', '55'],
-
- didInsertElement: function () {
- $('.datepicker').datepicker({
- format: 'mm/dd/yyyy'
- });
- }
-});
http://git-wip-us.apache.org/repos/asf/ambari/blob/2f5ee092/ambari-web/app/views/main/jobs_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/jobs_view.js b/ambari-web/app/views/main/jobs_view.js
deleted file mode 100644
index ea6cec9..0000000
--- a/ambari-web/app/views/main/jobs_view.js
+++ /dev/null
@@ -1,336 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-var filters = require('views/common/filter_view');
-var sort = require('views/common/sort_view');
-
-App.MainJobsView = App.TableView.extend({
- templateName: require('templates/main/jobs'),
-
- content: [],
-
-
- /**
- * If no jobs table rows to show.
- */
- noDataToShow:true,
-
- filterCondition:[],
-
- /*
- If no jobs to display set noDataToShow to true, else set emptyData to false.
- */
- noDataToShowObserver: function () {
- if(this.get("controller.content.length") > 0){
- this.set("noDataToShow",false);
- }else{
- this.set("noDataToShow",true);
- }
- }.observes("controller.content.length"),
-
- willInsertElement: function () {
- this._super();
- var self = this;
- var name = this.get('controller.name');
- var colPropAssoc = this.get('colPropAssoc');
- var filterConditions = App.db.getFilterConditions(name);
- if (filterConditions) {
- this.set('filterConditions', filterConditions);
- var childViews = this.get('childViews');
-
- filterConditions.forEach(function(condition) {
- var view = !Em.isNone(condition.iColumn) && childViews.findProperty('column', condition.iColumn);
- if (view) {
- //self.get('controller.filterObject').set(colPropAssoc[condition.iColumn], condition.value);
- view.set('value', condition.value);
- if(view.get('setPropertyOnApply')){
- view.setValueOnApply();
- }
- Em.run.next(function() {
- view.showClearFilter();
- });
- }
- });
- } else {
- this.clearFilters();
- }
- this.onApplyIdFilter();
- this.set('tableFilteringComplete', true);
- },
-
- didInsertElement: function () {
- if(!this.get('controller.sortingColumn')){
- var columns = this.get('childViews')[0].get('childViews')
- if(columns && columns.findProperty('name', 'startTime')){
- columns.findProperty('name','startTime').set('status', 'sorting_desc');
- this.get('controller').set('sortingColumn', columns.findProperty('name','startTime'))
- }
- }
- },
-
- onApplyIdFilter: function() {
- var isIdFilterApplied = this.get('controller.filterObject.isIdFilterApplied');
- this.get('childViews').forEach(function(childView) {
- if (childView['clearFilter'] && childView.get('column') != 1) {
- if(isIdFilterApplied){
- childView.clearFilter();
- }
- var childOfChild = childView.get('childViews')[0];
- if(childOfChild){
- Em.run.next(function() {
- childOfChild.set('disabled', isIdFilterApplied);
- })
- }
- }
- });
- }.observes('controller.filterObject.isIdFilterApplied'),
-
- saveFilter: function () {
- if(this.get('tableFilteringComplete')){
- this.updateFilter(1, this.get('controller.filterObject.id'), 'string');
- this.updateFilter(2, this.get('controller.filterObject.user'), 'string');
- this.updateFilter(4, this.get('controller.filterObject.windowEnd'), 'date');
- }
- }.observes(
- 'controller.filterObject.id',
- 'controller.filterObject.user',
- 'controller.filterObject.windowEnd'
- ),
-
- sortView: sort.wrapperView,
- idSort: sort.fieldView.extend({
- column: 1,
- name: 'id',
- displayName: Em.I18n.t('jobs.column.id'),
- type: 'string'
- }),
- userSort: sort.fieldView.extend({
- column: 2,
- name: 'user',
- displayName: Em.I18n.t('jobs.column.user'),
- type: 'string'
- }),
- startTimeSort: sort.fieldView.extend({
- column: 3,
- name: 'startTime',
- displayName: Em.I18n.t('jobs.column.start.time'),
- type: 'number'
- }),
- endTimeSort: sort.fieldView.extend({
- column: 4,
- name: 'endTime',
- displayName: Em.I18n.t('jobs.column.end.time'),
- type: 'number'
- }),
- durationSort: sort.fieldView.extend({
- column: 5,
- name: 'duration',
- displayName: Em.I18n.t('jobs.column.duration'),
- type: 'number'
- }),
-
- /**
- * Select View with list of "rows-per-page" options
- * @type {Ember.View}
- */
- rowsPerPageSelectView: Em.Select.extend({
- content: ['10', '25', '50', '100', "250", "500"],
- valueBinding: "controller.filterObject.jobsLimit",
- attributeBindings: ['disabled'],
- disabled: false,
- disabledObserver: function () {
- if (this.get("parentView.hasBackLinks")) {
- this.set('disabled', true);
- }else{
- this.set('disabled', false);
- }
- }.observes('parentView.hasBackLinks'),
- change: function () {
- this.get('controller').set('navIDs.nextID', '');
- this.get('parentView').saveDisplayLength();
- }
- }),
-
- /**
- * return filtered number of all content number information displayed on the page footer bar
- * @returns {String}
- */
- filteredJobs: function () {
- return Em.I18n.t('jobs.filtered.jobs').format(this.get('controller.content.length'));
- }.property('controller.content.length', 'controller.totalOfJobs'),
-
- pageContentObserver: function () {
- if (!this.get('controller.loading')) {
- if ($('.tooltip').length) {
- Ember.run.later(this, function() {
- if ($('.tooltip').length > 1) {
- $('.tooltip').first().remove();
- };
- }, 500);
- };
- };
- }.observes('controller.loading'),
-
- init: function() {
- this._super();
- App.tooltip($('body'), {
- selector: '[rel="tooltip"]',
- template: '<div class="tooltip jobs-tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
- placement: 'bottom'
- });
- },
-
- willDestroyElement : function() {
- $('.tooltip').remove();
- },
-
- /**
- * Filter-field for Jobs ID.
- * Based on <code>filters</code> library
- */
- jobsIdFilterView: filters.createTextView({
- column: 1,
- showApply: true,
- setPropertyOnApply: 'controller.filterObject.id'
- }),
-
- /**
- * Filter-list for User.
- * Based on <code>filters</code> library
- */
- userFilterView: filters.createTextView({
- column: 2,
- fieldType: 'input-small',
- showApply: true,
- setPropertyOnApply: 'controller.filterObject.user'
- }),
-
- /**
- * Filter-field for Start Time.
- * Based on <code>filters</code> library
- */
- startTimeFilterView: filters.createSelectView({
- fieldType: 'input-120',
- column: 3,
- content: ['Any', 'Past 1 hour', 'Past 1 Day', 'Past 2 Days', 'Past 7 Days', 'Past 14 Days', 'Past 30 Days', 'Custom'],
- valueBinding: "controller.filterObject.startTime",
- onChangeValue: function () {
- this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'date');
- }
- }),
-
- jobNameView: Em.View.extend({
- classNames: ['job-link'],
- tagName: 'a',
- classNameBindings: ['isLink'],
- attributeBindings: ['rel', 'job.queryText:data-original-title', 'href'],
- rel: 'tooltip',
- href: '#',
- isLink: 'is-not-link',
- isLinkObserver: function () {
- this.refreshLinks();
- }.observes('controller.sortingDone'),
- refreshLinks: function () {
- if (this.get('job.hasTezDag')) {
- this.set('isLink', "");
- }else{
- this.set('isLink', "is-not-link");
- }
- },
- template: Ember.Handlebars.compile('{{job.name}}'),
- click: function(event) {
- if (this.get('job.hasTezDag')) {
- App.router.transitionTo('main.jobs.jobDetails', this.get('job'));
- };
- return false;
- },
- didInsertElement: function () {
- this.refreshLinks();
- }
- }),
-
- /**
- * associations between content (jobs list) property and column index
- */
- colPropAssoc: function () {
- var associations = [];
- associations[1] = 'id';
- associations[2] = 'user';
- associations[3] = 'startTime';
- associations[4] = 'endTime';
- return associations;
- }.property(),
-
- clearFilters: function() {
- this.get('childViews').forEach(function(childView) {
- if (childView['clearFilter']) {
- childView.clearFilter();
- }
- });
- },
-
- jobFailMessage: function() {
- return Em.I18n.t('jobs.table.job.fail');
- }.property(),
-
- jobsPaginationLeft: Ember.View.extend({
- tagName: 'a',
- template: Ember.Handlebars.compile('<i class="icon-arrow-left"></i>'),
- classNameBindings: ['class'],
- class: function () {
- if (this.get("parentView.hasBackLinks") && !this.get('controller.filterObject.isAnyFilterApplied')) {
- return "paginate_previous";
- }
- return "paginate_disabled_previous";
- }.property('parentView.hasBackLinks', 'controller.filterObject.isAnyFilterApplied'),
-
- click: function () {
- if (this.get("parentView.hasBackLinks") && !this.get('controller.filterObject.isAnyFilterApplied')) {
- this.get('controller').navigateBack();
- }
- }
- }),
-
- jobsPaginationRight: Ember.View.extend({
- tagName: 'a',
- template: Ember.Handlebars.compile('<i class="icon-arrow-right"></i>'),
- classNameBindings: ['class'],
- class: function () {
- if (this.get("parentView.hasNextJobs") && !this.get('controller.filterObject.isAnyFilterApplied')) {
- return "paginate_next";
- }
- return "paginate_disabled_next";
- }.property("parentView.hasNextJobs", 'controller.filterObject.isAnyFilterApplied'),
-
- click: function () {
- if (this.get("parentView.hasNextJobs") && !this.get('controller.filterObject.isAnyFilterApplied')) {
- this.get('controller').navigateNext();
- }
- }
- }),
-
- hasNextJobs: function() {
- return (this.get("controller.navIDs.nextID.length") > 0);
- }.property('controller.navIDs.nextID'),
-
- hasBackLinks: function() {
- return (this.get("controller.navIDs.backIDs").length > 1);
- }.property('controller.navIDs.backIDs.[].length')
-
-});
http://git-wip-us.apache.org/repos/asf/ambari/blob/2f5ee092/ambari-web/app/views/main/menu.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/menu.js b/ambari-web/app/views/main/menu.js
index 9ac0f40..b81c90c 100644
--- a/ambari-web/app/views/main/menu.js
+++ b/ambari-web/app/views/main/menu.js
@@ -48,9 +48,6 @@ App.MainMenuView = Em.CollectionView.extend({
if (!App.get('isHadoop2Stack')) {
result.push({ label:Em.I18n.t('menu.item.jobs'), routing:'apps'});
- } else if( App.router.get('mainAdminController.isAccessAvailable') && App.supports.jobs
- && (App.router.get('mainAdminAccessController.showJobs') || App.get('isAdmin'))) {
- result.push({ label:Em.I18n.t('menu.item.jobs'), routing:'jobs'});
}
if (App.get('isAdmin')) {
@@ -65,7 +62,7 @@ App.MainMenuView = Em.CollectionView.extend({
}
return result;
- }.property('App.router.loggedIn', 'App.router.clusterController.isLoaded', 'App.supports.views', 'App.supports.mirroring', 'App.supports.secureCluster', 'App.supports.highAvailability', 'App.supports.jobs'),
+ }.property('App.router.loggedIn', 'App.router.clusterController.isLoaded', 'App.supports.views', 'App.supports.mirroring', 'App.supports.secureCluster', 'App.supports.highAvailability'),
/**
* Adds observer on lastSetURL and calls navigation sync procedure