Browse Source

HPCC-7867 Add timings "TreeMap" to graph web page.

Add indexed "TreeMap" view of the timings to the graph view web page.

Fixes HPCC-7867

Signed-off-by: Gordon Smith <gordon.smith@lexisnexis.com>
Gordon Smith 12 năm trước cách đây
mục cha
commit
6fe77583d5

+ 26 - 6
esp/files/scripts/GraphPageWidget.js

@@ -36,13 +36,16 @@ require([
 
     "hpcc/GraphWidget",
     "hpcc/ESPWorkunit",
+    "hpcc/TimingTreeMapWidget",
+
     "dojo/text!./templates/GraphPageWidget.html",
 
     "dijit/form/Select",
     "dijit/form/TextBox"
 ], function (declare, sniff, array, dom, domConstruct, on, Memory, ObjectStore,
             _LayoutWidget, _TemplatedMixin, _WidgetsInTemplateMixin, BorderContainer, TabContainer, ContentPane, registry, Dialog,
-            DataGrid, GraphWidget, ESPWorkunit, template) {
+            DataGrid, GraphWidget, ESPWorkunit, TimingTreeMapWidget,
+            template) {
     return declare("GraphPageWidget", [_LayoutWidget, _TemplatedMixin, _WidgetsInTemplateMixin], {
         templateString: template,
         baseClass: "GraphPageWidget",
@@ -56,6 +59,7 @@ require([
         local: null,
         graphSelect: null,
         timingGrid: null,
+        timingTreeMap: null,
         verticesGrid: null,
         edgesGrid: null,
         findField: null,
@@ -152,6 +156,7 @@ require([
                 context.timingGrid.setQuery({
                     GraphName: context.graphName
                 });
+                context.timingTreeMap.loadTimers(context.wu.timers, context.graphName);
             }
         },
 
@@ -163,7 +168,6 @@ require([
                 context.syncSelectionFrom(context.timingGrid);
             }, true);
 
-            var context = this;
             this.timingGrid.on("RowDblClick", function (evt) {
                 var idx = evt.rowIndex;
                 var item = this.getItem(idx);
@@ -173,6 +177,15 @@ require([
                     context.main.centerOnItem(mainItem, true);
                 }
             }, true);
+
+            this.timingTreeMap = registry.byId(this.id + "TimingsTreeMap");
+            this.timingTreeMap.onClick = function (value) {
+                context.syncSelectionFrom(context.timingTreeMap);
+            }
+            this.timingTreeMap.onDblClick = function (value) {
+                var mainItem = context.main.getItem(value.subGraphId);
+                context.main.centerOnItem(mainItem, true);
+            }
         },
 
         _initItemGrid: function (grid) {
@@ -351,7 +364,7 @@ require([
             }
 
             var layout = [[
-                { 'name': 'ID', 'field': 'id', 'width': '50px' }, 
+                { 'name': 'ID', 'field': 'id', 'width': '50px' },
                 { 'name': 'Label', 'field': 'label', 'width': '150px' }
             ]];
 
@@ -360,7 +373,7 @@ require([
             }
             layout[0].push({ 'name': "ECL", 'field': "ecl", 'width': '1024px' });
 
-            var store = new Memory({ data:  vertices});
+            var store = new Memory({ data: vertices });
             var dataStore = new ObjectStore({ objectStore: store });
             this.verticesGrid.setStructure(layout);
             this.verticesGrid.setStore(dataStore);
@@ -407,6 +420,8 @@ require([
                         selItems.push(items[i].SubGraphId);
                     }
                 }
+            } else if (sourceControl == this.timingTreeMap) {
+                selItems.push(sourceControl.lastSelection.subGraphId);
             } else if (sourceControl == this.verticesGrid || sourceControl == this.edgesGrid) {
                 var items = sourceControl.selection.getSelected();
                 for (var i = 0; i < items.length; ++i) {
@@ -424,6 +439,9 @@ require([
                     this.timingGrid.selection.setSelected(i, (row.SubGraphId && array.indexOf(selItems, row.SubGraphId) != -1));
                 }
             }
+            if (sourceControl != this.timingTreeMap) {
+                //TODO - Not sure if this is currently possible.
+            }
             if (sourceControl != this.verticesGrid && this.verticesGrid.store) {
                 for (var i = 0; i < this.verticesGrid.rowCount; ++i) {
                     var row = this.verticesGrid.getItem(i);
@@ -436,10 +454,12 @@ require([
                     this.edgesGrid.selection.setSelected(i, (row._globalID && array.indexOf(selItems, row._globalID) != -1));
                 }
             }
-            if (sourceControl != this.main)
+            if (sourceControl != this.main) {
                 this.main.setSelectedAsGlobalID(selItems);
-            if (sourceControl != this.overview)
+            }
+            if (sourceControl != this.overview) {
                 this.overview.setSelectedAsGlobalID(selItems);
+            }
 
             var mainItems = [];
             for (var i = 0; i < selItems.length; ++i) {

+ 84 - 53
esp/files/scripts/TimingTreeMapWidget.js

@@ -21,8 +21,8 @@ require([
     "dojo/dom",
     "dojo/dom-construct",
     "dojo/dom-class",
-	"dojo/store/Memory", 
-	"dojo/_base/Color",
+    "dojo/store/Memory",
+    "dojo/_base/Color",
 
     "dijit/registry",
     "dijit/layout/_LayoutWidget",
@@ -31,17 +31,17 @@ require([
     "dijit/layout/BorderContainer",
     "dijit/layout/ContentPane",
 
-	"dojox/treemap/TreeMap",
-	"dojox/color/MeanColorModel",
+    "dojox/treemap/TreeMap",
+    "dojox/color/MeanColorModel",
 
-	"hpcc/ESPWorkunit",
+    "hpcc/ESPWorkunit",
 
     "dojo/text!./templates/TimingTreeMapWidget.html"
 ],
     function (declare, aspect, has, dom, domConstruct, domClass, Memory, Color,
             registry, _LayoutWidget, _TemplatedMixin, _WidgetsInTemplateMixin, BorderContainer, ContentPane,
-			TreeMap, MeanColorModel,
-			ESPWorkunit,
+            TreeMap, MeanColorModel,
+            ESPWorkunit,
             template) {
         return declare("TimingTreeMapWidget", [_LayoutWidget, _TemplatedMixin, _WidgetsInTemplateMixin], {
             templateString: template,
@@ -51,6 +51,8 @@ require([
 
             dataStore: null,
 
+            lastSelection: null,
+
             buildRendering: function (args) {
                 this.inherited(arguments);
             },
@@ -59,6 +61,17 @@ require([
                 this.inherited(arguments);
                 this.borderContainer = registry.byId(this.id + "BorderContainer");
                 this.timingContentPane = registry.byId(this.id + "TimingContentPane");
+
+                var context = this;
+                this.timingContentPane.on("change", function (e) {
+                    context.lastSelection = e.newValue;
+                });
+                this.timingContentPane.on("click", function (evt) {
+                    context.onClick(context.lastSelection);
+                });
+                this.timingContentPane.on("dblclick", function (evt) {
+                    context.onDblClick(context.lastSelection);
+                });
             },
 
             startup: function (args) {
@@ -74,55 +87,73 @@ require([
                 this.inherited(arguments);
             },
 
-        	//  Plugin wrapper  ---
+            //  Plugin wrapper  ---
+            onClick: function (value) {
+            },
+
+            onDblClick: function (value) {
+            },
+
             initTreeMap: function () {
             },
 
             setWuid: function (wuid) {
-            	this.wuid = wuid;
-            	var context = this;
-            	if (wuid) {
-            		this.wu = new ESPWorkunit({
-            			wuid: wuid
-            		});
-            		this.wu.fetchTimers(function (timers) {
-            			context.largestValue = 0;
-            			var timerData = [];
-            			for (var i = 0; i < timers.length; ++i) {
-            				if (timers[i].GraphName) {
-            					var value = timers[i].Value;
-            					timerData.push({
-            						name: timers[i].Name,
-            						graphName: timers[i].GraphName,
-            						value: value
-            					});
-            					if (context.largestValue < value * 1000) {
-            						context.largestValue = value * 1000;
-            					}
-            				}
-            			}
-            			var dataStore = new Memory({
-            				idProperty: "name",
-            				data: timerData
-            			});
-
-            			context.timingContentPane.set("colorFunc", function (item) {
-            				var redness = 255 * (item.value * 1000 / context.largestValue);
-            				return {
-            					r: 255,
-            					g: 255 - redness,
-            					b: 255 - redness
-            				};
-            			});
-            			context.timingContentPane.set("areaAttr", "value");
-            			context.timingContentPane.set("tooltipFunc", function (item) {
-            				return item.name + " " + item.value;
-            			});
-            			context.timingContentPane.set("groupAttrs", ["graphName"]);
-
-            			context.timingContentPane.set("store", dataStore);
-            		});
-            	}
-        	}
+                this.wuid = wuid;
+                var context = this;
+                if (wuid) {
+                    this.wu = new ESPWorkunit({
+                        wuid: wuid
+                    });
+                    this.wu.fetchTimers(function (timers) {
+                        context.loadTimers(timers, "*");
+                    });
+                }
+            },
+
+            loadTimers: function (timers, query) {
+                this.largestValue = 0;
+                var timerData = [];
+                for (var i = 0; i < timers.length; ++i) {
+                    if (timers[i].GraphName && (query == "*" || query == timers[i].GraphName)) {
+                        var value = timers[i].Value;
+                        timerData.push({
+                            graphName: timers[i].GraphName,
+                            subGraphId: timers[i].SubGraphId,
+                            name: timers[i].Name,
+                            value: value
+                        });
+                        if (this.largestValue < value * 1000) {
+                            this.largestValue = value * 1000;
+                        }
+                    }
+                }
+                var dataStore = new Memory({
+                    idProperty: "name",
+                    data: timerData
+                });
+
+                var context = this;
+                this.timingContentPane.set("colorFunc", function (item) {
+                    var redness = 255 * (item.value * 1000 / context.largestValue);
+                    return {
+                        r: 255,
+                        g: 255 - redness,
+                        b: 255 - redness
+                    };
+                });
+                this.timingContentPane.set("areaAttr", "value");
+                this.timingContentPane.set("tooltipFunc", function (item) {
+                    return item.name + " " + item.value;
+                });
+                this.timingContentPane.set("groupAttrs", ["graphName"]);
+
+                this.timingContentPane.set("store", dataStore);
+            },
+
+            select: function (graphID, subGraphID) {
+                //this.timingContentPane.setItemSelected(this.timingContentPane.store.data[2]);
+
+            }
+
         });
     });

+ 11 - 15
esp/files/templates/GraphPageWidget.html

@@ -15,23 +15,19 @@
             <div id="${id}OverviewTabContainer" data-dojo-props="region: 'center', tabPosition: 'bottom'" data-dojo-type="dijit.layout.TabContainer">
                 <div id="${id}MiniGraphWidget" title="Overview" data-dojo-type="GraphWidget">
                 </div>
-                <div id="${id}Timings" title="Timings" style="padding: 0px; overflow: hidden" data-dojo-type="dijit.layout.ContentPane">
-                    <table id="${id}TimingsGrid" data-dojo-type="dojox.grid.DataGrid">
-                        <thead>
-                            <tr>
-                                <th field="Name" width="auto">Component</th>
-                                <th field="Value" width="auto">Time (ms)</th>
-                            </tr>
-                        </thead>
-                    </table>
+                <table id="${id}TimingsGrid" title="Timings" style="padding: 0px; overflow: hidden" data-dojo-type="dojox.grid.DataGrid">
+                    <thead>
+                        <tr>
+                            <th field="Name" width="auto">Component</th>
+                            <th field="Value" width="auto">Time (ms)</th>
+                        </tr>
+                    </thead>
+                </table>
+                <div id="${id}TimingsTreeMap" title="Timings Map" data-dojo-type="TimingTreeMapWidget">
                 </div>
-                <div id="${id}Vertices" title="Activities" style="padding: 0px; overflow: hidden" data-dojo-type="dijit.layout.ContentPane">
-                    <table id="${id}VerticesGrid" data-dojo-type="dojox.grid.DataGrid">
-                    </table>
+                <div id="${id}VerticesGrid" title="Activities" style="padding: 0px; overflow: hidden" data-dojo-type="dojox.grid.DataGrid">
                 </div>
-                <div id="${id}Edges" title="Edges" style="padding: 0px; overflow: hidden" data-dojo-type="dijit.layout.ContentPane">
-                    <table id="${id}EdgesGrid" data-dojo-type="dojox.grid.DataGrid">
-                    </table>
+                <div id="${id}EdgesGrid" title="Edges" style="padding: 0px; overflow: hidden" data-dojo-type="dojox.grid.DataGrid">
                 </div>
             </div>
             <div id="${id}LocalTabContainer" class="edgePanel" style="height: 66%" data-dojo-props="region: 'bottom', splitter:true, minSize: 120, tabPosition: 'bottom'" data-dojo-type="dijit.layout.TabContainer">