Repository: ambari Updated Branches: refs/heads/trunk bb53d0df1 -> e2a743ba0
AMBARI-5141. Selecting operator in Tez DAG vertex should show operator table (alexantonenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/e2a743ba Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/e2a743ba Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/e2a743ba Branch: refs/heads/trunk Commit: e2a743ba074259e68cd885d589734113dbfb38b7 Parents: bb53d0d Author: Alex Antonenko <[email protected]> Authored: Wed Mar 19 18:18:10 2014 +0200 Committer: Alex Antonenko <[email protected]> Committed: Wed Mar 19 18:18:10 2014 +0200 ---------------------------------------------------------------------- ambari-web/app/styles/application.less | 5 +- ambari-web/app/styles/apps.less | 24 ++++++ .../templates/main/jobs/hive_job_details.hbs | 23 +++-- .../app/templates/main/jobs/hover_op_table.hbs | 20 +++++ ambari-web/app/utils/helper.js | 30 +++++++ .../main/jobs/hive_job_details_tez_dag_view.js | 88 +++++++------------- .../views/main/jobs/hive_job_details_view.js | 1 + 7 files changed, 125 insertions(+), 66 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/e2a743ba/ambari-web/app/styles/application.less ---------------------------------------------------------------------- diff --git a/ambari-web/app/styles/application.less b/ambari-web/app/styles/application.less index 3b92247..dadd30f 100644 --- a/ambari-web/app/styles/application.less +++ b/ambari-web/app/styles/application.less @@ -5715,16 +5715,13 @@ i.icon-asterisks { } } #tez-vertex-details-section-body { - table { - margin-bottom: 5px; - } td { border-top: none; } tr td:first-child { font-weight: bold; width: 20%; - overflow: scroll; + overflow: auto; } textarea { width: 95%; http://git-wip-us.apache.org/repos/asf/ambari/blob/e2a743ba/ambari-web/app/styles/apps.less ---------------------------------------------------------------------- diff --git a/ambari-web/app/styles/apps.less b/ambari-web/app/styles/apps.less index c59412d..2ce9353 100644 --- a/ambari-web/app/styles/apps.less +++ b/ambari-web/app/styles/apps.less @@ -278,6 +278,30 @@ } } } +#hover-op-table{ + margin-bottom: 2px; + td{ + padding: 2px; + word-wrap: break-word; + } +} + +#hive-job-details{ + #operator-table{ + td { + border-top: 1px solid #dddddd; + } + tr td:first-child{ + width: 20%; + overflow: auto; + } + td:first-child + td, + th:first-child + th { + width: 80%; + } + } +} + #jobs { http://git-wip-us.apache.org/repos/asf/ambari/blob/e2a743ba/ambari-web/app/templates/main/jobs/hive_job_details.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/jobs/hive_job_details.hbs b/ambari-web/app/templates/main/jobs/hive_job_details.hbs index 77ad505..b9e13c5 100644 --- a/ambari-web/app/templates/main/jobs/hive_job_details.hbs +++ b/ambari-web/app/templates/main/jobs/hive_job_details.hbs @@ -172,13 +172,24 @@ <td>{{view.selectedVertexIODisplay.records.write}}</td> </tr> {{/if}} - <tr> - <td>{{t jobs.hive.tez.operatorPlan}}</td> - <td></td> - <td></td> - </tr> </table> - {{view Ember.TextArea valueBinding="view.selectedVertex.operationPlan" rows="15" id="tez-vertex-operator-plan-textarea"}} + <p>{{t jobs.hive.tez.operatorPlan}}</p> + <table id="operator-table" class="table table-bordered table-striped"> + <thead> + <tr> + <th>{{t common.name}}</th> + <th>{{t common.value}}</th> + </tr> + </thead> + <tbody> + {{#each keys in view.operatorPlan}} + <tr> + <td>{{keys.name}}</td> + <td>{{keys.value}}</td> + </tr> + {{/each}} + </tbody> + </table> </div> </div> </div> http://git-wip-us.apache.org/repos/asf/ambari/blob/e2a743ba/ambari-web/app/templates/main/jobs/hover_op_table.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/jobs/hover_op_table.hbs b/ambari-web/app/templates/main/jobs/hover_op_table.hbs new file mode 100644 index 0000000..863fc10 --- /dev/null +++ b/ambari-web/app/templates/main/jobs/hover_op_table.hbs @@ -0,0 +1,20 @@ +<table id="hover-op-table" class="table table-bordered"> + <thead> + <tr> + <th>{{t common.name}}</th> + <th>{{t common.value}}</th> + </tr> + </thead> + <tbody> + {{#each keys in content}} + <tr> + <td> + {{keys.name}} + </td> + <td> + {{keys.value}} + </td> + </tr> + {{/each}} + </tbody> +</table> http://git-wip-us.apache.org/repos/asf/ambari/blob/e2a743ba/ambari-web/app/utils/helper.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/helper.js b/ambari-web/app/utils/helper.js index 162fad0..289afc6 100644 --- a/ambari-web/app/utils/helper.js +++ b/ambari-web/app/utils/helper.js @@ -36,6 +36,36 @@ String.prototype.capitalize = function () { return this.charAt(0).toUpperCase() + this.slice(1); }; +// Use: stringvalue.findIn(multi_dimensional_array_or_object) +/***Example: + var tofind = 'emotion'; + var person = {'name': 'Bob Loblaw', 'age': '28', 'personality': {'smart': 'yes', 'funny': 'yes', 'emotion': 'happy'} }; + tofind.findIn(person) + ***/ +String.prototype.findIn = function (multi) { + multi = multi || ''; + var val = this.valueOf(); + if(typeof multi == 'object' || typeof multi == 'array') + { + if(val in multi) + { + return multi[val]; + } + else + { + for(var x in multi) + { + var found = this.findIn(multi[x]); + if(found != false) + { + return found; + } + } + } + } + return false; +}; + /** * Replace {i} with argument. where i is number of argument to replace with * @return {String} http://git-wip-us.apache.org/repos/asf/ambari/blob/e2a743ba/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 index 1835dff..a11ed94 100644 --- 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 @@ -292,6 +292,25 @@ App.MainHiveJobDetailsTezDagView = Em.View.extend({ '[email protected]', '[email protected]', '[email protected]', '[email protected]'), + createOperationPlanObj: function (vertexName, op) { + var operatorPlanObj = []; + var text = this.get('content.tezDag.vertices').findProperty('name', vertexName).get('operationPlan'); + text = text.replace(/:"/g,'"'); + var jsonText = $.parseJSON(text); + var jsonText = op.findIn(jsonText); + 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. @@ -574,7 +593,6 @@ App.MainHiveJobDetailsTezDagView = Em.View.extend({ // // Draw SVG // - var self = this; var force = d3.layout.force().nodes(dagVisualModel.nodes).links(dagVisualModel.links).start(); var nodeDragData = { nodeRelativeX : 0, @@ -648,61 +666,15 @@ App.MainHiveJobDetailsTezDagView = Em.View.extend({ } return opCount[op]; }).on('mousedown', function(op) { - var opIndex = this.getAttribute ? this.getAttribute("opIndex") : null; - if (numberUtils.validateInteger(opIndex) == null) { - console.log("Clicked on operator: ", op, " [", opIndex, "]"); - var textArea = document.getElementById('tez-vertex-operator-plan-textarea'); - if (textArea && textArea.value) { - var text = textArea.value; - var opText = "\"" + op + "\""; - var count = 1; - var index = text.indexOf(opText); - while (index > -1 && count < opIndex) { - index = text.indexOf(opText, index + 1); - count++; - } - if (index > -1) { - var start = index; - var end = index; - var matchCount = 0; - var splits = text.substring(start).split(/({|})/); - splits.every(function(s) { - if (s == '{') { - matchCount++; - } else if (s == '}') { - matchCount--; - if (matchCount == 0) { - end += s.length; - return false; - } - } - end += s.length; - return true; - }); - textArea.setSelectionRange(start, end); - // Now scroll to the selection - var lines = 0; - var totalLines = 0; - var index = text.indexOf("\n"); - while (index > 0) { - index = text.indexOf("\n", index + 1); - if (index < start) { - lines++; - } - totalLines++; - } - console.log("Selection is from row ", lines, " out of ", totalLines); - lines -= 5; - var lineHeight = Math.floor(textArea.scrollHeight / totalLines); - var scrollHeight = Math.round(lines * lineHeight); - textArea.scrollTop = scrollHeight; - } - } - } - }); - opGroups.append("rect").attr("class", "operation svg-tooltip ").attr("width", "50").attr("height", "16").attr("title", function(op) { - return op; - }); + var operatorPlanObj = self.createOperationPlanObj(n.name, op); + self.get('parentView').set('operatorPlan', operatorPlanObj); + }).on('mouseover', function(op) { + var operatorPlanObj = self.createOperationPlanObj(n.name, op); + var template = App.HoverOpTable.create({content: operatorPlanObj}) ; + $(event.currentTarget).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] : ''; }); @@ -916,3 +888,7 @@ App.MainHiveJobDetailsTezDagView = Em.View.extend({ } }); + +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/e2a743ba/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 index 8afd59d..2e160e2 100644 --- a/ambari-web/app/views/main/jobs/hive_job_details_view.js +++ b/ambari-web/app/views/main/jobs/hive_job_details_view.js @@ -26,6 +26,7 @@ App.MainHiveJobDetailsView = Em.View.extend({ templateName : require('templates/main/jobs/hive_job_details'), selectedVertex : null, + operatorPlan: [], content : null, zoomScaleFrom : 1, zoomScaleTo: 2,
