ソースを参照

HUE-8665 [editor] Add navigation from risk to plan.

jdesjean 7 年 前
コミット
1dcb0939b9

+ 29 - 0
apps/jobbrowser/src/jobbrowser/static/jobbrowser/js/impala_dagre.js

@@ -20,6 +20,9 @@ function impalaDagre(id) {
       var scale = _impalaDagree.scale || 1;
       var height = value || 600;
       svg.attr('height', Math.min(g.graph().height * scale + 40, height) || height);
+    },
+    moveTo: function(id) {
+      zoomToNode(id);
     }
   };
 
@@ -75,6 +78,32 @@ function impalaDagre(id) {
 
   var is_first = true;
 
+  function zoomToNode(node) {
+    var nodes = g.nodes();
+    var key;
+    var nNode = parseInt(node, 10);
+    var keys = Object.keys(nodes);
+    for (var i = 0; i < keys.length; i++) {
+      if (parseInt(nodes[keys[i]].split(':')[0], 10) == nNode) {
+        key = nodes[keys[i]];
+        break;
+      }
+    }
+    if (!key) {
+      return;
+    }
+    var n = $("g.node:contains('" + key + "')")[0];
+    var t = d3.transform(d3.select(n).attr("transform")),
+        x = t.translate[0],
+        y = t.translate[1];
+
+    var scale = 1;
+
+    svg.transition().duration(1000)
+        .call(zoom.translate([((x * -scale) + (svg.property("clientWidth") / 2)), ((y * -scale) + svg.property("clientHeight") / 2)])
+            .scale(scale).event);
+  }
+
   function renderGraph(plan) {
     if (!plan || !plan.plan_nodes || !plan.plan_nodes.length) return;
     var states = [];

+ 1 - 1
apps/jobbrowser/src/jobbrowser/templates/job_browser.mako

@@ -1508,7 +1508,7 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
       <div class="tab-content">
         <div class="tab-pane" id="queries-page-plan${ SUFFIX }" data-profile="plan">
           <div data-bind="visible:properties.plan && properties.plan().plan_json && properties.plan().plan_json.plan_nodes.length">
-            <div id="queries-page-plan-graph${ SUFFIX }" data-bind="impalaDagre: {value: properties.plan && properties.plan().plan_json, height:$root.isMini() ? 250 : 600 }">
+            <div id="queries-page-plan-graph${ SUFFIX }" data-bind="impalaDagre: {value: properties.plan && properties.plan().plan_json, height:$root.isMini() ? 550 : 600 }">
               <svg class="query-plan" style="width:100%;height:100%;" id="queries-page-plan-svg${ SUFFIX }">
                 <g/>
               </svg>

+ 8 - 1
desktop/core/src/desktop/static/desktop/js/ko.hue-bindings.js

@@ -7495,7 +7495,14 @@
     return {
       init: function (element, valueAccessor, allBindingsAccessor) {
         var id = $(element).attr("id");
-        this._impalaDagre = impalaDagre(id);
+        var self = this;
+        self._impalaDagre = impalaDagre(id);
+        var clickSubscription = huePubSub.subscribe('impala.node.moveto', function(value) {
+          self._impalaDagre.moveTo(value);
+        });
+        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
+          clickSubscription.remove();
+        });
       },
       update: function (element, valueAccessor) {
         var props = ko.unwrap(valueAccessor());

+ 26 - 4
desktop/core/src/desktop/templates/ko_components/ko_execution_analysis.mako

@@ -59,7 +59,7 @@ from desktop.views import _ko
           <h4>${_('Top down analysis')}</h4>
           <ul class="risk-list" data-bind="foreach: $parent.healthChecks">
             <li>
-              <div><span data-bind="text: contribution_factor_str"></span> - <strong><span data-bind="duration: wall_clock_time"></strong></div>
+              <div><a href="javascript:void(0);" data-bind="click: $parents[1].handleNodePress.bind($parents[1], $data)"><span data-bind="text: contribution_factor_str"></span></a> - <strong><span data-bind="duration: wall_clock_time"></strong></div>
               <ol data-bind="foreach: reason">
                 <li>
                   <span data-bind="text: message, css: { striked: fix.fixed }"></span><strong> - <span data-bind="numberFormat: { value: impact, unit: unit }"></span></strong><span data-bind="visible: fix.fixable && !fix.fixed"> - <a href="javascript:void(0);" data-bind="click: $parents[2].handleFix.bind($parents[2], $data.fix)">${_('Fix')}</a></span>
@@ -81,7 +81,8 @@ from desktop.views import _ko
 
         self.loading = ko.observable(false);
         self.analysis = ko.observable();
-        self.analysis.subscribe(function (analysis) {
+        self.details = ko.observable();
+        var analysisSub = self.analysis.subscribe(function (analysis) {
           $('[href*=executionAnalysis] span:eq(1)').text(self.analysisCount());
           setTimeout(function () { // Wait for analysis to render
             if (analysis.heatmap) {
@@ -125,6 +126,7 @@ from desktop.views import _ko
           }
           if (details.analysisPossible) {
             self.analysisPossible(true);
+            self.details(details);
             self.loadAnalysis(details.compute, details.queryId);
           } else {
             self.analysisPossible(false);
@@ -132,13 +134,17 @@ from desktop.views import _ko
         });
 
         self.disposals.push(function () {
+          analysisSub.remove();
           clearAnalysisSub.remove();
           executionAnalysisSub.remove();
         });
       };
       ExecutionAnalysis.prototype.heatmapMetricChanged = function (model, el) {
         var self = this;
-        self.updateHeatMap(self.analysis().heatmap[el.target.value], el.target.value);
+        var analysis = self.analysis();
+        if (analysis.heatmap) {
+          self.updateHeatMap(analysis.heatmap[analysis.heatmapMetrics[0]], analysis.heatmapMetrics[0]);
+        }
       };
       ExecutionAnalysis.prototype.loadAnalysis = function (compute, queryId) {
         var self = this;
@@ -215,7 +221,6 @@ from desktop.views import _ko
 
       ExecutionAnalysis.prototype.handleFix = function (fix) {
         var self = this;
-        //TODO: Loading
         ApiHelper.getInstance().fixQueryExecutionAnalysis({ fix: fix, start_time: ko.mapping.toJSON((new Date()).getTime()) })
         .done(function(resp) {
           huePubSub.publish('notebook.task.submitted', resp.task.history_uuid);
@@ -224,6 +229,23 @@ from desktop.views import _ko
         });
       };
 
+      ExecutionAnalysis.prototype.handleNodePress = function (contributor) {
+        var self = this;
+        debugger;
+        //TODO: Loading
+        if (!$('[href*="' + self.details().name + '"]')[0]) {
+          huePubSub.publish('show.jobs.panel', { id: self.details().name, interface: 'queries' });
+          setTimeout(function() {
+            huePubSub.publish('impala.node.moveto', contributor.result_id);
+          }, 500);
+        } else {
+          if (!$('#jobsPanel').is(":visible")) {
+            $('#jobsPanel').show();
+          }
+          huePubSub.publish('impala.node.moveto', contributor.result_id);
+        }
+      };
+
       ExecutionAnalysis.prototype.dispose = function () {
         var self = this;
         while (self.disposals.length) {

+ 1 - 1
desktop/libs/libanalyze/src/libanalyze/rules.py

@@ -653,7 +653,7 @@ class TopDownAnalysis:
         for contributor in topContributors:
             reasons = self.getTopReasons(contributor)
             topContributions += [{
-                    "result_id" : contributor.plan_node_id if contributor.plan_node_id != -1 else '-1',
+                    "result_id" : contributor.plan_node_id if contributor.plan_node_id != -1 else -1,
                     "contribution_factor_str" : contributor.type + " " +
                                                 str(contributor.plan_node_id).zfill(2) +
                                                 ":" + contributor.plan_node_name,

+ 2 - 1
desktop/libs/notebook/src/notebook/static/notebook/js/notebook.ko.js

@@ -1781,7 +1781,8 @@ var EditorViewModel = (function() {
         huePubSub.publish('editor.update.execution.analysis', {
           analysisPossible: true,
           compute: self.compute(),
-          queryId: notebook.getContext().id()
+          queryId: notebook.getContext().id(),
+          name: self.jobs()[0] && self.jobs()[0].name
         });
       } else {
         huePubSub.publish('editor.update.execution.analysis', {