You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by kw...@apache.org on 2017/09/10 21:34:59 UTC

qpid-broker-j git commit: QPID-7772: [Java Broker] Make generic statistic panel group pairs of messages/byte statistics into single row to make efficient use of screen estate

Repository: qpid-broker-j
Updated Branches:
  refs/heads/master 38151b3e4 -> c977f76fd


QPID-7772: [Java Broker] Make generic statistic panel group pairs of messages/byte statistics into single row to make efficient use of screen estate

Added generic statistics panel to virtualhost, exchange and queue, replacing the existing statistics in the attribute area.
Statistics panel default to offering a key-set of statistics. More button allows all statistics for that object to be seen.
Improved some statistic descriptions.


Project: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/commit/c977f76f
Tree: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/tree/c977f76f
Diff: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/diff/c977f76f

Branch: refs/heads/master
Commit: c977f76fd46031f8ce778ef10ecde8e8c9019e61
Parents: 38151b3
Author: Keith Wall <ke...@gmail.com>
Authored: Sat Sep 9 16:09:06 2017 +0100
Committer: Keith Wall <ke...@gmail.com>
Committed: Sun Sep 10 22:29:52 2017 +0100

----------------------------------------------------------------------
 .../org/apache/qpid/server/model/Exchange.java  |  15 +-
 .../org/apache/qpid/server/model/Queue.java     |   4 +-
 .../virtualhost/QueueManagingVirtualHost.java   |   2 +-
 .../java/resources/common/StatisticsWidget.html |  14 +-
 .../src/main/java/resources/css/common.css      |  13 +
 .../src/main/java/resources/images/minus.svg    |  26 ++
 .../js/qpid/common/StatisticsWidget.js          | 421 ++++++++++++++-----
 .../java/resources/js/qpid/common/metadata.js   |  43 +-
 .../java/resources/js/qpid/management/Broker.js |   8 +-
 .../resources/js/qpid/management/Exchange.js    |  65 +--
 .../java/resources/js/qpid/management/Queue.js  |  92 ++--
 .../resources/js/qpid/management/VirtualHost.js |  84 ++--
 .../src/main/java/resources/showBroker.html     |   6 +-
 .../src/main/java/resources/showExchange.html   |  23 +-
 .../src/main/java/resources/showQueue.html      |  49 +--
 .../main/java/resources/showVirtualHost.html    |  24 +-
 16 files changed, 501 insertions(+), 388 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/c977f76f/broker-core/src/main/java/org/apache/qpid/server/model/Exchange.java
----------------------------------------------------------------------
diff --git a/broker-core/src/main/java/org/apache/qpid/server/model/Exchange.java b/broker-core/src/main/java/org/apache/qpid/server/model/Exchange.java
index 904251b..1603f6d 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/model/Exchange.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/model/Exchange.java
@@ -72,19 +72,24 @@ public interface Exchange<X extends Exchange<X>> extends ConfiguredObject<X>, Me
     CreatingLinkInfo getCreatingLinkInfo();
 
     // Statistics
-    @ManagedStatistic(statisticType = StatisticType.POINT_IN_TIME, units = StatisticUnit.COUNT, label = "Bindings")
+    @ManagedStatistic(statisticType = StatisticType.POINT_IN_TIME, units = StatisticUnit.COUNT, label = "Bindings",
+                      description = "Number of bindings to this exchange.")
     long getBindingCount();
 
-    @ManagedStatistic(statisticType = StatisticType.CUMULATIVE, units = StatisticUnit.BYTES, label = "Dropped")
+    @ManagedStatistic(statisticType = StatisticType.CUMULATIVE, units = StatisticUnit.BYTES, label = "Dropped",
+                      description = "Total size of all unroutable messages dropped by this exchange.")
     long getBytesDropped();
 
-    @ManagedStatistic(statisticType = StatisticType.CUMULATIVE, units = StatisticUnit.BYTES, label = "Inbound")
+    @ManagedStatistic(statisticType = StatisticType.CUMULATIVE, units = StatisticUnit.BYTES, label = "Inbound",
+                      description = "Total size of messages received by this exchange.")
     long getBytesIn();
 
-    @ManagedStatistic(statisticType = StatisticType.CUMULATIVE, units = StatisticUnit.MESSAGES, label = "Dropped")
+    @ManagedStatistic(statisticType = StatisticType.CUMULATIVE, units = StatisticUnit.MESSAGES, label = "Dropped",
+                      description = "Number of unroutable messages dropped by this exchange.")
     long getMessagesDropped();
 
-    @ManagedStatistic(statisticType = StatisticType.CUMULATIVE, units = StatisticUnit.MESSAGES, label = "Inbound")
+    @ManagedStatistic(statisticType = StatisticType.CUMULATIVE, units = StatisticUnit.MESSAGES, label = "Inbound",
+                      description = "Number of messages received by this exchange.")
     long getMessagesIn();
 
 

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/c977f76f/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java
----------------------------------------------------------------------
diff --git a/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java b/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java
index 2561e74..ae34568 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java
@@ -344,7 +344,7 @@ public interface Queue<X extends Queue<X>> extends ConfiguredObject<X>,
     @ManagedStatistic(statisticType = StatisticType.CUMULATIVE, units = StatisticUnit.MESSAGES, label = "Enqueued (Persistent)")
     long getPersistentEnqueuedMessages();
 
-    @ManagedStatistic(statisticType = StatisticType.POINT_IN_TIME, units = StatisticUnit.BYTES, label = "Queue Depth Including Header")
+    @ManagedStatistic(statisticType = StatisticType.POINT_IN_TIME, units = StatisticUnit.BYTES, label = "Queue Depth")
     long getQueueDepthBytes();
 
     @ManagedStatistic(statisticType = StatisticType.POINT_IN_TIME, units = StatisticUnit.MESSAGES, label = "Queue Depth")
@@ -367,7 +367,7 @@ public interface Queue<X extends Queue<X>> extends ConfiguredObject<X>,
     long getTotalEnqueuedMessages();
 
     @SuppressWarnings("unused")
-    @ManagedStatistic(statisticType = StatisticType.POINT_IN_TIME, units = StatisticUnit.MESSAGES, label = "Prefetched")
+    @ManagedStatistic(statisticType = StatisticType.POINT_IN_TIME, units = StatisticUnit.BYTES, label = "Prefetched")
     long getUnacknowledgedBytes();
 
     @SuppressWarnings("unused")

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/c977f76f/broker-core/src/main/java/org/apache/qpid/server/virtualhost/QueueManagingVirtualHost.java
----------------------------------------------------------------------
diff --git a/broker-core/src/main/java/org/apache/qpid/server/virtualhost/QueueManagingVirtualHost.java b/broker-core/src/main/java/org/apache/qpid/server/virtualhost/QueueManagingVirtualHost.java
index a2f6d5e..6dfadfd 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/virtualhost/QueueManagingVirtualHost.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/virtualhost/QueueManagingVirtualHost.java
@@ -199,7 +199,7 @@ public interface QueueManagingVirtualHost<X extends QueueManagingVirtualHost<X>>
     @ManagedStatistic(statisticType = StatisticType.CUMULATIVE, units = StatisticUnit.MESSAGES, label = "Outbound")
     long getMessagesOut();
 
-    @ManagedStatistic(statisticType = StatisticType.POINT_IN_TIME, units = StatisticUnit.BYTES, label = "Total Depth of Queues Including Header")
+    @ManagedStatistic(statisticType = StatisticType.POINT_IN_TIME, units = StatisticUnit.BYTES, label = "Total Depth of Queues")
     long getTotalDepthOfQueuesBytes();
 
     @ManagedStatistic(statisticType = StatisticType.POINT_IN_TIME, units = StatisticUnit.MESSAGES, label = "Total Depth of Queues")

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/c977f76f/broker-plugins/management-http/src/main/java/resources/common/StatisticsWidget.html
----------------------------------------------------------------------
diff --git a/broker-plugins/management-http/src/main/java/resources/common/StatisticsWidget.html b/broker-plugins/management-http/src/main/java/resources/common/StatisticsWidget.html
index e882780..aa84f96 100644
--- a/broker-plugins/management-http/src/main/java/resources/common/StatisticsWidget.html
+++ b/broker-plugins/management-http/src/main/java/resources/common/StatisticsWidget.html
@@ -20,8 +20,16 @@
   -->
 <div>
     <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Statistics',  open: false" data-dojo-attach-point="statisticsPane">
-        <div data-dojo-attach-point="cumulativeStatisticsGridContainer"></div>
-        <br/>
-        <div data-dojo-attach-point="pointInTimeStatisticsGridContainer"></div>
+        <div data-dojo-attach-point="msgBytePairCumulativeStatisticsGridContainer"></div>
+        <div data-dojo-attach-point="otherCumulativeStatisticsGridContainer"></div>
+        <div data-dojo-attach-point="msgBytePairPointInTimeStatisticsGridContainer"></div>
+        <div data-dojo-attach-point="otherPointInTimeStatisticsGridContainer"></div>
+        <div class="alignRight">
+            <div data-dojo-attach-point="allStatsToggle" data-dojo-type="dijit/form/ToggleButton"
+                 data-dojo-props="label: 'Show more statistics',
+                                  iconClass: 'addIcon',
+                                  value: false"></div>
+        </div>
+        <div class="clear"/>
     </div>
 </div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/c977f76f/broker-plugins/management-http/src/main/java/resources/css/common.css
----------------------------------------------------------------------
diff --git a/broker-plugins/management-http/src/main/java/resources/css/common.css b/broker-plugins/management-http/src/main/java/resources/css/common.css
index 7f03736..bdacc7d 100644
--- a/broker-plugins/management-http/src/main/java/resources/css/common.css
+++ b/broker-plugins/management-http/src/main/java/resources/css/common.css
@@ -674,6 +674,14 @@ td.advancedSearchField, col.autoWidth {
     background-size: 1em;
 }
 
+.minusIcon
+{
+    background: url("../images/minus.svg") left center no-repeat;
+    width: 15px;
+    height: 15px;
+    background-size: 1em;
+}
+
 #message-content-preview
 {
     width: 100%;
@@ -753,3 +761,8 @@ td.advancedSearchField, col.autoWidth {
 {
     text-align: center;
 }
+
+.statisticGrid
+{
+    margin-bottom: 10px !important;
+}

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/c977f76f/broker-plugins/management-http/src/main/java/resources/images/minus.svg
----------------------------------------------------------------------
diff --git a/broker-plugins/management-http/src/main/java/resources/images/minus.svg b/broker-plugins/management-http/src/main/java/resources/images/minus.svg
new file mode 100644
index 0000000..239d1a5
--- /dev/null
+++ b/broker-plugins/management-http/src/main/java/resources/images/minus.svg
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+  ~
+  ~ 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.
+  ~
+  -->
+
+<svg xmlns="http://www.w3.org/2000/svg" width="360" height="360" id="plus" version="1.1">
+    <rect style="opacity:1;fill:#FF0000;fill-opacity:1;stroke:#FF0000;stroke-width:0;"
+          id="horizontal" width="360" height="100" x="0" y="130"/>
+</svg>

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/c977f76f/broker-plugins/management-http/src/main/java/resources/js/qpid/common/StatisticsWidget.js
----------------------------------------------------------------------
diff --git a/broker-plugins/management-http/src/main/java/resources/js/qpid/common/StatisticsWidget.js b/broker-plugins/management-http/src/main/java/resources/js/qpid/common/StatisticsWidget.js
index bd4d6bb..dcab5b9a 100644
--- a/broker-plugins/management-http/src/main/java/resources/js/qpid/common/StatisticsWidget.js
+++ b/broker-plugins/management-http/src/main/java/resources/js/qpid/common/StatisticsWidget.js
@@ -18,9 +18,7 @@
  * under the License.
  *
  */
-define(["qpid/common/UpdatableStore",
-        "qpid/common/formatter",
-        "dojox/grid/EnhancedGrid",
+define(["dojox/lang/functional/object",
         "dojo/_base/declare",
         "dojo/_base/array",
         "dojo/_base/lang",
@@ -28,14 +26,18 @@ define(["qpid/common/UpdatableStore",
         "dojo/on",
         "dojo/mouse",
         "dojo/number",
+        "dojo/store/Memory",
+        "dojox/grid/EnhancedGrid",
+        "dojo/data/ObjectStore",
+        "dojo/store/Observable",
         "dijit/_WidgetBase",
         "dijit/Tooltip",
         "dijit/registry",
+        "qpid/common/formatter",
         "dojo/text!common/StatisticsWidget.html",
+        "dijit/form/ToggleButton",
         "dojo/domReady!"],
-    function (UpdatableStore,
-              formatter,
-              EnhancedGrid,
+    function (fobject,
               declare,
               array,
               lang,
@@ -43,9 +45,14 @@ define(["qpid/common/UpdatableStore",
               on,
               mouse,
               number,
+              Memory,
+              EnhancedGrid,
+              ObjectStore,
+              Observable,
               _WidgetBase,
               Tooltip,
               registry,
+              formatter,
               template) {
 
         return declare("qpid.common.StatisticsWidget",
@@ -54,107 +61,310 @@ define(["qpid/common/UpdatableStore",
                 //Strip out the apache comment header from the template html as comments unsupported.
                 templateString: template.replace(/<!--[\s\S]*?-->/g, ""),
 
-                cumulativeStatisticsGridContainer: null,
-                pointInTimeStatisticsGridContainer: null,
+                msgBytePairCumulativeStatisticsGridContainer: null,
+                otherCumulativeStatisticsGridContainer: null,
+                msgBytePairPointInTimeStatisticsGridContainer: null,
+                otherPointInTimeStatisticsGridContainer: null,
+
                 statisticsPane: null,
+                allStatsToggle: null,
 
                 category: null,
                 type: null,
                 management: null,
+                defaultStatistics: null,
+
+                _msgBytePairCumulativeStatisticsGrid: null,
+                _otherCumulativeStatisticsGrid: null,
+                _msgBytePairPointInTimeStatisticsGrid: null,
+                _otherPointInTimeStatisticsGrid: null,
+                _allGrids: [],
 
-                _grid: null,
+                _showAllStats : false,
                 _sampleTime: null,
                 _previousSampleTime: null,
+                _nodes: {},
 
-                postCreate: function () {
+                postCreate: function ()
+                {
                     this.inherited(arguments);
 
+                    var metadata = this.management.metadata;
+
+                    var type = this.type ? this.type : this.category;
+
                     this.userPreferences = this.management.userPreferences;
+                    var allStatistics = metadata.getStatisticsMetadata(this.category, type);
+                    var allAugmentedStatistics = this._augmentStatistics(allStatistics);
+                    var pairedByteMessageStatistic = [];
+                    var otherStatistics = [];
 
-                    this.cumulativeStatisticsGrid =
-                        new UpdatableStore([], this.cumulativeStatisticsGridContainer, [{
-                            name: "Name",
-                            field: "label",
-                            width: "50%"
-                        }, {
-                            name: "Value",
-                            fields: ["value","units"],
-                            width: "25%",
-                            formatter: lang.hitch(this, this._formatValue)
-                        }, {
-                            name: "Rate",
-                            fields: ["value", "previousValue", "units"],
-                            width: "25%",
-                            formatter: lang.hitch(this, this._formatRate)
-                        }], null, {}, EnhancedGrid);
-
-                    this.pointInTimeStatisticsGrid =
-                        new UpdatableStore([], this.pointInTimeStatisticsGridContainer, [{
-                            name: "Name",
-                            field: "label",
-                            width: "50%"
-                        }, {
-                            name: "Value",
-                            fields: ["value","units"],
-                            width: "50%",
-                            formatter: lang.hitch(this, this._formatValue)
-                        }], null, {}, EnhancedGrid);
+                    this._filterMessageByteStatisticPairs(allAugmentedStatistics, pairedByteMessageStatistic, otherStatistics);
 
-                    var metadata = this.management.metadata;
-                    var type = this.type ? this.type : this.category;
-                    var cumulativeStatistics = metadata.getStatisticsMetadata(this.category, type, "CUMULATIVE");
-                    var pointInTimeStatistics = metadata.getStatisticsMetadata(this.category, type, "POINT_IN_TIME");
-                    var augmentedCumulativeStatistics = this._augmentStatisticsForDisplay(cumulativeStatistics);
-                    var augmentedPointInTimeStatistics = this._augmentStatisticsForDisplay(pointInTimeStatistics);
+                    this._store = new Memory({
+                        data: allAugmentedStatistics,
+                        idProperty: "id"
+                    });
+
+                    this._dataStore = ObjectStore({objectStore: new Observable(this._store)});
+
+                    var formatRate = function (fields)
+                    {
+                        var value = fields[0] ? fields[0] : 0;
+                        var previousValue = fields[1] ? fields[1] : 0;
+                        var units = fields[2];
+                        var rateWithUnit = this._formatRate(value, previousValue, units);
+                        return rateWithUnit ? rateWithUnit.toString() : "N/A";
+                    };
+
+                    var formatValue = function (fields) {
+                        var value = fields[0] ? fields[0] : 0;
+                        var units = fields[1];
+                        return this._formatValue(value, units);
+                    };
+
+                    var formatByteStatValueFromMsgStat = function (msgStatItem) {
+                        var byteStatItem = this._queryStatItem(msgStatItem, "BYTES");
+                        var value = this._formatValue(byteStatItem.value ? byteStatItem.value : 0, byteStatItem.units);
+                        return value;
+                    };
+
+                    var formatByteStatRateFromMsgStat = function (msgStatItem) {
+                        var byteStatItem = this._queryStatItem(msgStatItem, "BYTES");
+                        var rateWithUnit = this._formatRate(byteStatItem.value ? byteStatItem.value : 0, byteStatItem.previousValue ? byteStatItem.previousValue : 0, byteStatItem.units);
+                        return rateWithUnit ? rateWithUnit.toString() : "N/A";
+                    };
+
+                    this._msgBytePairCumulativeStatisticsGrid =
+                        new EnhancedGrid({
+                            store: this._dataStore,
+                            class: "statisticGrid",
+                            autoHeight: true,
+                            structure: [{
+                                name: "Name",
+                                field: "label",
+                                width: "52%"
+                            }, {
+                                name: "Messages",
+                                fields: ["value", "units"],
+                                width: "12%",
+                                formatter: lang.hitch(this, formatValue)
+                            }, {
+                                name: "Message Rate",
+                                fields: ["value", "previousValue", "units"],
+                                width: "12%",
+                                formatter: lang.hitch(this, formatRate)
+                            }, {
+                                name: "Bytes",
+                                field: "_item",
+                                width: "12%",
+                                formatter: lang.hitch(this, formatByteStatValueFromMsgStat)
+                            }, {
+                                name: "Byte Rate",
+                                field: "_item",
+                                width: "12%",
+                                formatter: lang.hitch(this, formatByteStatRateFromMsgStat)
+                            }]
+                        }, this.msgBytePairCumulativeStatisticsGridContainer);
+
+                    this._msgBytePairCumulativeStatisticsGrid.query = lang.hitch(this, function (statItem) {
+                        return statItem.statisticType === "CUMULATIVE" &&
+                               statItem.units === "MESSAGES" &&
+                               array.indexOf(pairedByteMessageStatistic, statItem) > -1 &&
+                               this._isStatItemShown(statItem);
+                    });
+
+                    this._otherCumulativeStatisticsGrid =
+                        new EnhancedGrid({
+                            store: this._dataStore,
+                            class: "statisticGrid",
+                            autoHeight: true,
+                            structure: [{
+                                name: "Name",
+                                field: "label",
+                                width: "52%"
+                            }, {
+                                name: "Value",
+                                fields: ["value", "units"],
+                                width: "24%",
+                                formatter: lang.hitch(this, formatValue)
+                            }, {
+                                name: "Rate",
+                                fields: ["value", "previousValue", "units"],
+                                width: "24%",
+                                formatter: lang.hitch(this, formatRate)
+                            }]
+                        }, this.otherCumulativeStatisticsGridContainer);
+                    this._otherCumulativeStatisticsGrid.query = lang.hitch(this, function (statItem) {
+                        return statItem.statisticType === "CUMULATIVE" &&
+                               array.indexOf(pairedByteMessageStatistic, statItem) === -1 &&
+                               this._isStatItemShown(statItem);
+                    });
+
+                    this._msgBytePairPointInTimeStatisticsGrid =
+                        new EnhancedGrid({
+                            store: this._dataStore,
+                            class: "statisticGrid",
+                            autoHeight: true,
+                            structure: [{
+                                name: "Name",
+                                field: "label",
+                                width: "52%"
+                            }, {
+                                name: "Message Value",
+                                fields: ["value", "units"],
+                                width: "24%",
+                                formatter: lang.hitch(this, formatValue)
+                            }, {
+                                name: "Byte Value",
+                                field: "_item",
+                                width: "24%",
+                                formatter: lang.hitch(this, formatByteStatValueFromMsgStat)
+                            }]
+                        }, this.msgBytePairPointInTimeStatisticsGridContainer);
+
+                    this._msgBytePairPointInTimeStatisticsGrid.query = lang.hitch(this, function (statItem) {
+                        return statItem.statisticType === "POINT_IN_TIME" &&
+                               statItem.units === "MESSAGES" &&
+                               array.indexOf(pairedByteMessageStatistic, statItem) > -1 &&
+                               this._isStatItemShown(statItem);
+                    });
 
-                    this.cumulativeStatisticsGrid.grid.beginUpdate();
-                    this.cumulativeStatisticsGrid.update(augmentedCumulativeStatistics);
-                    this.cumulativeStatisticsGrid.grid.endUpdate();
+                    this._otherPointInTimeStatisticsGrid =
+                        new EnhancedGrid({
+                            store: this._dataStore,
+                            class: "statisticGrid",
+                            autoHeight: true,
+                            structure: [{
+                                name: "Name",
+                                field: "label",
+                                width: "52%"
+                            }, {
+                                name: "Value",
+                                fields: ["value", "units"],
+                                width: "48%",
+                                formatter: lang.hitch(this, formatValue)
+                            }]
+                        }, this.otherPointInTimeStatisticsGridContainer);
 
-                    this.pointInTimeStatisticsGrid.grid.beginUpdate();
-                    this.pointInTimeStatisticsGrid.update(augmentedPointInTimeStatistics);
-                    this.pointInTimeStatisticsGrid.grid.endUpdate();
+                    this._otherPointInTimeStatisticsGrid.query = lang.hitch(this, function (statItem) {
+                        return statItem.statisticType === "POINT_IN_TIME" &&
+                               array.indexOf(pairedByteMessageStatistic, statItem) === -1 &&
+                               this._isStatItemShown(statItem);
+                    });
+
+                    this._allGrids.push(this._msgBytePairCumulativeStatisticsGrid,
+                                        this._otherCumulativeStatisticsGrid,
+                                        this._msgBytePairPointInTimeStatisticsGrid,
+                                        this._otherPointInTimeStatisticsGrid);
 
                     connect.connect(this.statisticsPane, "toggle", lang.hitch(this, this.resize));
-                    connect.connect(this.cumulativeStatisticsGrid.grid, "onCellMouseOver", lang.hitch(this, function(e)
+                    array.forEach(this._allGrids, function(grid)
                     {
-                        this._addDynamicTooltipToGridRow(e, augmentedCumulativeStatistics);
-                    }));
-                    connect.connect(this.pointInTimeStatisticsGrid.grid, "onCellMouseOver", lang.hitch(this, function(e)
+                        connect.connect(grid, "onCellMouseOver", lang.hitch(this, this._addDynamicTooltipToGridRow));
+                    }, this);
+
+                    this.allStatsToggle.on("change", lang.hitch(this, this._onStatsToggleChange));
+                },
+                startup: function ()
+                {
+                    if (!this._started)
                     {
-                        this._addDynamicTooltipToGridRow(e, augmentedPointInTimeStatistics);
-                    }));
+                        this.inherited(arguments);
+
+                        array.forEach(this._allGrids, function (grid) {
+                            grid.startup();
+                        }, this);
+                    }
                 },
-                _formatRate : function (fields)
+                resize: function ()
                 {
-                    if (this._previousSampleTime)
+                    this.inherited(arguments);
+                    this._showHideGrids();
+                    array.forEach(this._allGrids, function(grid)
                     {
-                        var value = fields[0] ? fields[0] : 0;
-                        var previousValue = fields[1] ? fields[1] : 0;
-                        var units = fields[2];
+                        grid.resize();
+                    }, this);
+
+                },
+                update: function (statistics)
+                {
+                    this._previousSampleTime = this._sampleTime;
+                    this._sampleTime = new Date();
+
+                    array.forEach(this._allGrids, function(grid)
+                    {
+                        grid.beginUpdate();
+                    }, this);
+
+                    this._updateStoreData(statistics, this._store.data);
+
+                    array.forEach(this._allGrids, function(grid)
+                    {
+                        grid.endUpdate();
+                    }, this);
+                },
+                uninitialize: function ()
+                {
+                    this.inherited(arguments);
+                    this._dataStore.close();
+                },
+                _isStatItemShown: function (statItem)
+                {
+                    return this._showAllStats || (!this.defaultStatistics || array.indexOf(this.defaultStatistics, statItem.name) > -1);
+                },
+                _onStatsToggleChange: function (value)
+                {
+                    this.allStatsToggle.set("label", value ? "Show fewer statistics" : "Show more statistics");
+                    this.allStatsToggle.set("iconClass", value ? "minusIcon" : "addIcon");
+                    this._showAllStats = value;
 
+                    array.forEach(this._allGrids, function(grid)
+                    {
+                        grid._refresh();
+                    }, this);
+
+                    this._showHideGrids();
+                    this.resize();
+                },
+                _formatRate : function (value, previousValue, units)
+                {
+                    if (this._previousSampleTime)
+                    {
                         var samplePeriod = this._sampleTime.getTime() - this._previousSampleTime.getTime();
 
                         var rate = number.round((1000 * (value - previousValue)) / samplePeriod);
 
+                        var valueWithUnit = {
+                            units: null,
+                            value: rate,
+                            toString : function()
+                            {
+                                return this.value + " " + this.units;
+                            }
+                        };
+
                         if (units === "BYTES")
                         {
-                            return formatter.formatBytes(rate) + "/s";
+                            var byteValueWithUnit = formatter.formatBytes(rate);
+                            valueWithUnit.units = byteValueWithUnit.units  + "/s";
+                            valueWithUnit.value = byteValueWithUnit.value;
                         }
                         else if (units === "MESSAGES")
                         {
-                            return "" + rate + " msg/s"
+                            valueWithUnit.units = " msg/s";
                         }
                         else
                         {
-                            return "" + rate + " &Delta;s"
+                            valueWithUnit.units = " &Delta;s"
                         }
+                        return valueWithUnit;
                     }
-                    return "N/A";
+
+                    return null;
                 },
-                _formatValue : function (fields) {
-                    var value = fields[0] ? fields[0] : 0;
-                    var units = fields[1];
+                _formatValue : function (value, units)
+                {
                     if (units === "BYTES")
                     {
                         return formatter.formatBytes(value);
@@ -175,24 +385,12 @@ define(["qpid/common/UpdatableStore",
                         return value;
                     }
                 },
-                resize: function ()
-                {
-                    this.inherited(arguments);
-                    this.cumulativeStatisticsGrid.grid.resize();
-                    this.pointInTimeStatisticsGrid.grid.resize();
-                },
-                update: function (statistics)
+                _showHideGrids: function ()
                 {
-                    this._previousSampleTime = this._sampleTime;
-                    this._sampleTime = new Date();
-
-                    this.cumulativeStatisticsGrid.grid.beginUpdate();
-                    this._updateStoreData(statistics, this.cumulativeStatisticsGrid.store.data);
-                    this.cumulativeStatisticsGrid.grid.endUpdate();
-
-                    this.pointInTimeStatisticsGrid.grid.beginUpdate();
-                    this._updateStoreData(statistics, this.pointInTimeStatisticsGrid.store.data);
-                    this.pointInTimeStatisticsGrid.grid.endUpdate();
+                    array.forEach(this._allGrids, function(grid)
+                    {
+                        grid.set("hidden", grid.rowCount === 0);
+                    }, this);
                 },
                 _updateStoreData: function (statistics, data) {
                     array.forEach(data, function (storeItem) {
@@ -200,37 +398,68 @@ define(["qpid/common/UpdatableStore",
                         storeItem["value"] = statistics[storeItem.id];
                     }, this);
                 },
-                _augmentStatisticsForDisplay : function(statItems)
+                _augmentStatistics : function(statItems)
                 {
                     var items = [];
-                    array.forEach(statItems, function(statItem) {
+                    fobject.forIn(statItems, function(statItem) {
                         var item = lang.mixin(statItem,
                             {id: statItem.name,
                                 value: null,
                                 previousValue: null});
                         items.push(item);
-
                     }, this);
                     items.sort(function(x,y) {return ((x.label === y.label) ? 0 : ((x.label > y.label) ? 1 : -1 ))});
                     return items;
                 },
-                destroy: function ()
+                _filterMessageByteStatisticPairs : function(augmentedStatistics, byteMsgPairStatistics, otherStatistics)
                 {
-                    this.inherited(arguments);
-                    this.cumulativeStatisticsGrid.close();
-                    this.pointInTimeStatisticsGrid.close();
+                    array.forEach(augmentedStatistics, function (item) {
+                        otherStatistics.push(item);
+                    }, this);
+
+                    var msgCandidates = array.filter(otherStatistics, function(item)
+                    {return item.units === "MESSAGES"}, this);
+
+                    array.forEach(msgCandidates, function(msgItemCandidate)
+                    {
+                        var byteItemCandidates = array.filter(otherStatistics, function(item)
+                        {
+                            return item.units === "BYTES" && item.label === msgItemCandidate.label;
+                        });
+
+                        if (byteItemCandidates.length === 1)
+                        {
+                            // Found a msg/byte statistic pair
+                            var byteItemCandidate = byteItemCandidates[0];
+                            otherStatistics.splice(array.indexOf(otherStatistics, msgItemCandidate), 1);
+                            otherStatistics.splice(array.indexOf(otherStatistics, byteItemCandidate), 1);
+
+                            byteMsgPairStatistics.push(msgItemCandidate);
+                            byteMsgPairStatistics.push(byteItemCandidate);
+                        }
+
+                    }, this);
                 },
-                _addDynamicTooltipToGridRow: function(e, data)
+                _addDynamicTooltipToGridRow: function(e)
                 {
-                    var tip = data[e.rowIndex];
-                    if (tip && tip.description)
+                    var statItem = e.grid.getItem(e.rowIndex);
+                    if (statItem && statItem.description)
                     {
-                        Tooltip.show(tip.description, e.rowNode);
+                        Tooltip.show(statItem.description, e.rowNode);
                         on.once(e.rowNode, mouse.leave, function()
                         {
                             Tooltip.hide(e.rowNode);
                         });
                     }
+                },
+                _queryStatItem: function (statItem, units)
+                {
+                    var result = this._store.query({
+                        label: statItem.label,
+                        statisticType: statItem.statisticType,
+                        units: units
+                    });
+                    return result[0];
                 }
             });
     });

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/c977f76f/broker-plugins/management-http/src/main/java/resources/js/qpid/common/metadata.js
----------------------------------------------------------------------
diff --git a/broker-plugins/management-http/src/main/java/resources/js/qpid/common/metadata.js b/broker-plugins/management-http/src/main/java/resources/js/qpid/common/metadata.js
index a2b0c2f..5458045 100644
--- a/broker-plugins/management-http/src/main/java/resources/js/qpid/common/metadata.js
+++ b/broker-plugins/management-http/src/main/java/resources/js/qpid/common/metadata.js
@@ -32,19 +32,12 @@ define(["dojo/_base/array", "dojox/lang/functional/object"], function (array, fo
         return null;
     };
 
-    Metadata.prototype.getStatisticsMetadata = function (category, type, statisticType)
+    Metadata.prototype.getStatisticsMetadata = function (category, type)
     {
         var metadata = this.getMetaData(category, type);
         if (metadata && metadata.statistics)
         {
-            var filteredStatItems = [];
-            fobject.forIn(metadata.statistics, function(statItem) {
-               if (statItem.statisticType === statisticType)
-               {
-                   filteredStatItems.push(statItem);
-               }
-            }, this);
-            return filteredStatItems;
+            return metadata.statistics;
         }
         else
         {
@@ -75,16 +68,19 @@ define(["dojo/_base/array", "dojox/lang/functional/object"], function (array, fo
         var defaultValues = {};
         for (var attributeName in attributesForType)
         {
-            var attribute = attributesForType[attributeName];
-            if (attribute.defaultValue)
+            if (attributesForType.hasOwnProperty(attributeName))
             {
-                if (attribute.type == "Boolean")
+                var attribute = attributesForType[attributeName];
+                if (attribute.defaultValue)
                 {
-                    defaultValues[attributeName] = (attribute.defaultValue === "true");
-                }
-                else
-                {
-                    defaultValues[attributeName] = attribute.defaultValue;
+                    if (attribute.type === "Boolean")
+                    {
+                        defaultValues[attributeName] = (attribute.defaultValue === "true");
+                    }
+                    else
+                    {
+                        defaultValues[attributeName] = attribute.defaultValue;
+                    }
                 }
             }
         }
@@ -99,12 +95,12 @@ define(["dojo/_base/array", "dojox/lang/functional/object"], function (array, fo
     Metadata.prototype.extractUniqueListOfValues = function (data)
     {
         var values = [];
-        for (i = 0; i < data.length; i++)
+        for (var i = 0; i < data.length; i++)
         {
-            for (j = 0; j < data[i].length; j++)
+            for (var j = 0; j < data[i].length; j++)
             {
                 var current = data[i][j];
-                if (array.indexOf(values, current) == -1)
+                if (array.indexOf(values, current) === -1)
                 {
                     values.push(current);
                 }
@@ -134,9 +130,12 @@ define(["dojo/_base/array", "dojox/lang/functional/object"], function (array, fo
         var categoryLower = category ? category.toLowerCase() : null;
         for (var fieldName in this.metadata)
         {
-            if (new String(fieldName).toLowerCase() === categoryLower)
+            if (this.metadata.hasOwnProperty(fieldName))
             {
-                return true;
+                if (new String(fieldName).toLowerCase() === categoryLower)
+                {
+                    return true;
+                }
             }
         }
         return false;

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/c977f76f/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js
----------------------------------------------------------------------
diff --git a/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js b/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js
index a89c729..b23e7d5 100644
--- a/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js
+++ b/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js
@@ -268,7 +268,7 @@ define(["dojo/parser",
                             {
                                 for (var i = 0; i < data.length; i++)
                                 {
-                                    if (data[i].type.indexOf("File") != -1)
+                                    if (data[i].type.indexOf("File") !== -1)
                                     {
                                         warning = "NOTE: provider deletion will also remove the group file on disk.\n\n"
                                         break;
@@ -381,9 +381,11 @@ define(["dojo/parser",
             this.brokerStatistics = new qpid.common.StatisticsWidget({
                 category:  "Broker",
                 type: null,
-                management: this.controller.management
+                management: this.controller.management,
+                defaultStatistics: ["messagesIn", "messagesOut"]
             });
             this.brokerStatistics.placeAt(dom.byId("showBroker.statistics"));
+            this.brokerStatistics.startup();
 
             this.accessControlProvidersWarn = query(".broker-access-control-providers-warning", node)[0];
             this.management = this.controller.management;
@@ -407,7 +409,7 @@ define(["dojo/parser",
 
             function isActiveVH(item)
             {
-                return item && item.vhId && item.vhState == "ACTIVE";
+                return item && item.vhId && item.vhState === "ACTIVE";
             }
 
             this.vhostsGrid =

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/c977f76f/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js
----------------------------------------------------------------------
diff --git a/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js b/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js
index 1ccde12..baa6d6e 100644
--- a/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js
+++ b/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js
@@ -37,6 +37,7 @@ define(["dojo/_base/xhr",
         "dojox/grid/EnhancedGrid",
         "dojox/html/entities",
         "dojo/text!showExchange.html",
+        "qpid/common/StatisticsWidget",
         "dojo/domReady!"],
     function (xhr,
               parser,
@@ -56,7 +57,8 @@ define(["dojo/_base/xhr",
               addExchange,
               EnhancedGrid,
               entities,
-              template)
+              template,
+              StatisticsWidget)
     {
 
         function Exchange(kwArgs)
@@ -202,19 +204,14 @@ define(["dojo/_base/xhr",
                     that[names[i]] = findNode(names[i]);
                 }
             }
+            this.exchangeStatisticsNode = findNode("exchangeStatistics");
 
             storeNodes(["name",
                         "type",
                         "state",
                         "durable",
                         "lifetimePolicy",
-                        "alternateBinding",
-                        "msgInRate",
-                        "bytesInRate",
-                        "bytesInRateUnits",
-                        "msgDropRate",
-                        "bytesDropRate",
-                        "bytesDropRateUnits"]);
+                        "alternateBinding"]);
 
             that.exchangeData = {};
 
@@ -279,13 +276,23 @@ define(["dojo/_base/xhr",
                 {
                     thisObj.exchangeData = data[0];
 
+                    if (!thisObj.exchangeStatistics)
+                    {
+                        thisObj.exchangeStatistics = new StatisticsWidget({
+                            category:  "Exchange",
+                            type: thisObj.exchangeData.type,
+                            management: thisObj.management,
+                            defaultStatistics: ["messagesIn", "messagesDropped"]
+                        });
+                        thisObj.exchangeStatistics.placeAt(thisObj.exchangeStatisticsNode);
+                        thisObj.exchangeStatistics.startup();
+                    }
+
                     if (callback)
                     {
                         callback();
                     }
 
-                    util.flattenStatistics(thisObj.exchangeData);
-
                     var bindings = thisObj.exchangeData.bindings || [];
                     for (var i = 0; i < bindings.length; i++)
                     {
@@ -293,42 +300,10 @@ define(["dojo/_base/xhr",
                         bindings[i].id = bindings[i].destination + "/" + bindings[i].bindingKey;
                     }
 
-                    var sampleTime = new Date();
-
+                    thisObj.exchangeStatistics.update(thisObj.exchangeData.statistics);
+                    thisObj.exchangeStatistics.resize();
                     thisObj.updateHeader();
 
-                    var messageIn = thisObj.exchangeData["messagesIn"];
-                    var bytesIn = thisObj.exchangeData["bytesIn"];
-                    var messageDrop = thisObj.exchangeData["messagesDropped"];
-                    var bytesDrop = thisObj.exchangeData["bytesDropped"];
-
-                    if (thisObj.sampleTime)
-                    {
-                        var samplePeriod = sampleTime.getTime() - thisObj.sampleTime.getTime();
-
-                        var msgInRate = (1000 * (messageIn - thisObj.messageIn)) / samplePeriod;
-                        var msgDropRate = (1000 * (messageDrop - thisObj.messageDrop)) / samplePeriod;
-                        var bytesInRate = (1000 * (bytesIn - thisObj.bytesIn)) / samplePeriod;
-                        var bytesDropRate = (1000 * (bytesDrop - thisObj.bytesDrop)) / samplePeriod;
-
-                        thisObj.msgInRate.innerHTML = msgInRate.toFixed(0);
-                        var bytesInFormat = formatter.formatBytes(bytesInRate);
-                        thisObj.bytesInRate.innerHTML = "(" + bytesInFormat.value;
-                        thisObj.bytesInRateUnits.innerHTML = bytesInFormat.units + "/s)";
-
-                        thisObj.msgDropRate.innerHTML = msgDropRate.toFixed(0);
-                        var bytesDropFormat = formatter.formatBytes(bytesDropRate);
-                        thisObj.bytesDropRate.innerHTML = "(" + bytesDropFormat.value;
-                        thisObj.bytesDropRateUnits.innerHTML = bytesDropFormat.units + "/s)"
-
-                    }
-
-                    thisObj.sampleTime = sampleTime;
-                    thisObj.messageIn = messageIn;
-                    thisObj.bytesIn = bytesIn;
-                    thisObj.messageDrop = messageDrop;
-                    thisObj.bytesDrop = bytesDrop;
-
                     // update bindings
                     if (thisObj.bindingsGrid.update(bindings))
                     {
@@ -355,7 +330,7 @@ define(["dojo/_base/xhr",
                 this.management.remove(this.modelObj)
                     .then(function (data)
                     {
-                        that.contentPane.onClose()
+                        that.contentPane.onClose();
                         that.controller.tabContainer.removeChild(that.contentPane);
                         that.contentPane.destroyRecursive();
                     }, util.xhrErrorHandler);

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/c977f76f/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Queue.js
----------------------------------------------------------------------
diff --git a/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Queue.js b/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Queue.js
index 6ba1607..d808cb4 100644
--- a/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Queue.js
+++ b/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Queue.js
@@ -39,6 +39,7 @@ define(["dojo/_base/declare",
         "qpid/common/JsonRest",
         "dojox/grid/EnhancedGrid",
         "qpid/management/query/QueryGrid",
+        "qpid/common/StatisticsWidget",
         "dojo/data/ObjectStore",
         "dojox/html/entities",
         "dojo/text!showQueue.html",
@@ -66,6 +67,7 @@ define(["dojo/_base/declare",
               JsonRest,
               EnhancedGrid,
               QueryGrid,
+              StatisticsWidget,
               ObjectStore,
               entities,
               template)
@@ -118,7 +120,7 @@ define(["dojo/_base/declare",
                         queryParams: {includeHeaders: false},
                         totalRetriever: function ()
                         {
-                            if (that.queueUpdater.queueData && that.queueUpdater.queueData.queueDepthMessages != undefined)
+                            if (that.queueUpdater.queueData && that.queueUpdater.queueData.queueDepthMessages !== undefined)
                             {
                                 return that.queueUpdater.queueData.queueDepthMessages;
                             }
@@ -313,7 +315,6 @@ define(["dojo/_base/declare",
             var data = this.grid.selection.getSelected();
             if (data.length)
             {
-                var that = this;
                 var i, putData = {messages: []};
                 if (move)
                 {
@@ -380,6 +381,8 @@ define(["dojo/_base/declare",
                 }
             }
 
+            this.queueStatisticsNode = findNode("queueStatistics");
+
             storeNodes(["name",
                         "state",
                         "durable",
@@ -409,21 +412,8 @@ define(["dojo/_base/declare",
                         "messageGroups",
                         "messageGroupKey",
                         "messageGroupSharedGroups",
-                        "queueDepthMessagesIncludingHeader",
-                        "queueDepthBytesIncludingHeader",
-                        "queueDepthBytesUnitsIncludingHeader",
-                        "unacknowledgedMessages",
-                        "unacknowledgedBytes",
-                        "unacknowledgedBytesUnits",
-                        "msgInRate",
-                        "bytesInRate",
-                        "bytesInRateUnits",
-                        "msgOutRate",
-                        "bytesOutRate",
-                        "bytesOutRateUnits",
                         "maximumDeliveryAttempts",
-                        "holdOnPublishEnabled",
-                        "oldestMessageAge"]);
+                        "holdOnPublishEnabled"]);
 
             that.queueData = {};
             that.bindingsGrid = new UpdatableStore([], findNode("bindings"), [{
@@ -564,17 +554,8 @@ define(["dojo/_base/declare",
                 this.queueData["alternateBinding"] && this.queueData["alternateBinding"]["destination"]
                     ? entities.encode(String(this.queueData["alternateBinding"]["destination"])) : "";
 
-            this.queueDepthMessagesIncludingHeader.innerHTML = entities.encode(String(this.queueData["queueDepthMessages"]));
-            bytesDepth = formatter.formatBytes(this.queueData["queueDepthBytesIncludingHeader"]);
-            this.queueDepthBytesIncludingHeader.innerHTML = "(" + bytesDepth.value;
-            this.queueDepthBytesUnitsIncludingHeader.innerHTML = bytesDepth.units + ")";
-
-            this.unacknowledgedMessages.innerHTML = entities.encode(String(this.queueData["unacknowledgedMessages"]));
-            bytesDepth = formatter.formatBytes(this.queueData["unacknowledgedBytes"]);
-            this.unacknowledgedBytes.innerHTML = "(" + bytesDepth.value;
-            this.unacknowledgedBytesUnits.innerHTML = bytesDepth.units + ")";
             this["type"].innerHTML = entities.encode(this.queueData["type"]);
-            if (this.queueData["type"] == "standard")
+            if (this.queueData["type"] === "standard")
             {
                 this.typeQualifier.style.display = "none";
             }
@@ -588,7 +569,7 @@ define(["dojo/_base/declare",
             var overflowPolicy = this.queueData["overflowPolicy"];
             this["overflowPolicy"].innerHTML = entities.encode(overflowPolicy);
 
-            if (overflowPolicy && overflowPolicy != "NONE")
+            if (overflowPolicy && overflowPolicy !== "NONE")
             {
                 this.maximumQueueDepth.style.display = "block";
                 renderMaximumQueueDepthBytes(this["maximumQueueDepthBytes"], this["maximumQueueDepthBytesUnits"], this.queueData.maximumQueueDepthBytes);
@@ -610,11 +591,13 @@ define(["dojo/_base/declare",
                 this.messageGroups.style.display = "none";
             }
 
-            this.oldestMessageAge.innerHTML = entities.encode(String(this.queueData["oldestMessageAge"] / 1000));
             var maximumDeliveryAttempts = this.queueData["maximumDeliveryAttempts"];
             this.maximumDeliveryAttempts.innerHTML =
-                entities.encode(String(maximumDeliveryAttempts == 0 ? "" : maximumDeliveryAttempts));
+                entities.encode(String(maximumDeliveryAttempts === 0 ? "" : maximumDeliveryAttempts));
             this.holdOnPublishEnabled.innerHTML = entities.encode(String(this.queueData["holdOnPublishEnabled"]));
+
+            this.queueStatistics.update(this.queueData.statistics);
+            this.queueStatistics.resize();
         };
 
         QueueUpdater.prototype.update = function (callback)
@@ -637,12 +620,26 @@ define(["dojo/_base/declare",
                 {
                     var i, j;
                     thisObj.queueData = data.queue[0];
-                    util.flattenStatistics(thisObj.queueData);
+
+                    if (!thisObj.queueStatistics)
+                    {
+                        thisObj.queueStatistics = new StatisticsWidget({
+                            category:  "Queue",
+                            type: thisObj.queueData.type,
+                            management: thisObj.management,
+                            defaultStatistics: ["totalEnqueuedMessages", "totalDequeuedMessages",
+                                                "unacknowledgedMessages", "queueDepthMessages",
+                                                "oldestMessageAge"]
+                        });
+                        thisObj.queueStatistics.placeAt(thisObj.queueStatisticsNode);
+                        thisObj.queueStatistics.startup();
+                    }
+
+
                     if (callback)
                     {
                         callback();
                     }
-                    var bindings = thisObj.queueData["bindings"];
                     var consumers = thisObj.queueData["consumers"];
 
                     var bindings = data.publishingLinks || [];
@@ -676,37 +673,6 @@ define(["dojo/_base/declare",
                     thisObj.alertThresholdQueueDepthMessages.innerHTML =
                         entities.encode(String(thisObj.queueData["alertThresholdQueueDepthMessages"]));
 
-                    var sampleTime = new Date();
-                    var messageIn = thisObj.queueData["totalEnqueuedMessages"];
-                    var bytesIn = thisObj.queueData["totalEnqueuedBytes"];
-                    var messageOut = thisObj.queueData["totalDequeuedMessages"];
-                    var bytesOut = thisObj.queueData["totalDequeuedBytes"];
-
-                    if (thisObj.sampleTime)
-                    {
-                        var samplePeriod = sampleTime.getTime() - thisObj.sampleTime.getTime();
-
-                        var msgInRate = (1000 * (messageIn - thisObj.messageIn)) / samplePeriod;
-                        var msgOutRate = (1000 * (messageOut - thisObj.messageOut)) / samplePeriod;
-                        var bytesInRate = (1000 * (bytesIn - thisObj.bytesIn)) / samplePeriod;
-                        var bytesOutRate = (1000 * (bytesOut - thisObj.bytesOut)) / samplePeriod;
-
-                        thisObj.msgInRate.innerHTML = msgInRate.toFixed(0);
-                        var bytesInFormat = formatter.formatBytes(bytesInRate);
-                        thisObj.bytesInRate.innerHTML = "(" + bytesInFormat.value;
-                        thisObj.bytesInRateUnits.innerHTML = bytesInFormat.units + "/s)";
-
-                        thisObj.msgOutRate.innerHTML = msgOutRate.toFixed(0);
-                        var bytesOutFormat = formatter.formatBytes(bytesOutRate);
-                        thisObj.bytesOutRate.innerHTML = "(" + bytesOutFormat.value;
-                        thisObj.bytesOutRateUnits.innerHTML = bytesOutFormat.units + "/s)";
-                    }
-
-                    thisObj.sampleTime = sampleTime;
-                    thisObj.messageIn = messageIn;
-                    thisObj.bytesIn = bytesIn;
-                    thisObj.messageOut = messageOut;
-                    thisObj.bytesOut = bytesOut;
                     thisObj.consumers = consumers;
 
                     // update bindings
@@ -736,7 +702,7 @@ define(["dojo/_base/declare",
                     var oldConsumer = null;
                     for (var j = 0; j < this._previousConsumers.length; j++)
                     {
-                        if (this._previousConsumers[j].id == consumer.id)
+                        if (this._previousConsumers[j].id === consumer.id)
                         {
                             oldConsumer = this._previousConsumers[j];
                             break;

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/c977f76f/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js
----------------------------------------------------------------------
diff --git a/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js b/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js
index eac5398..ba28dbb 100644
--- a/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js
+++ b/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js
@@ -35,6 +35,7 @@ define(["dojo/parser",
         "qpid/management/query/QueryGrid",
         "dojox/grid/EnhancedGrid",
         "qpid/management/editVirtualHost",
+        "qpid/common/StatisticsWidget",
         "dojo/text!showVirtualHost.html",
         "dojo/domReady!"],
     function (parser,
@@ -54,6 +55,7 @@ define(["dojo/parser",
               QueryGrid,
               EnhancedGrid,
               editVirtualHost,
+              StatisticsWidget,
               template)
     {
 
@@ -236,17 +238,13 @@ define(["dojo/parser",
                 }
             }
 
+            this.virtualhostStatisticsNode = findNode("virtualhostStatistics");
+
             storeNodes(["name",
                         "type",
                         "state",
                         "durable",
                         "lifetimePolicy",
-                        "msgInRate",
-                        "bytesInRate",
-                        "bytesInRateUnits",
-                        "msgOutRate",
-                        "bytesOutRate",
-                        "bytesOutRateUnits",
                         "virtualHostDetailsContainer",
                         "connectionThreadPoolSize",
                         "housekeepingCheckPeriod",
@@ -458,15 +456,21 @@ define(["dojo/parser",
                 .then(function (data)
                 {
                     thisObj.vhostData = data[0] || {
-                            name: thisObj.modelObj.name,
-                            statistics: {
-                                messagesIn: 0,
-                                bytesIn: 0,
-                                messagesOut: 0,
-                                bytesOut: 0
-                            }
+                            name: thisObj.modelObj.name
                         };
 
+                    if (!thisObj.virtualhostStatistics)
+                    {
+                        thisObj.virtualhostStatistics = new StatisticsWidget({
+                            category:  "VirtualHost",
+                            type: thisObj.vhostData.type,
+                            management: thisObj.management,
+                            defaultStatistics: ["messagesIn", "messagesOut", "totalDepthOfQueuesMessages"]
+                        });
+                        thisObj.virtualhostStatistics.placeAt(thisObj.virtualhostStatisticsNode);
+                        thisObj.virtualhostStatistics.startup();
+                    }
+
                     if (callback)
                     {
                         callback();
@@ -498,53 +502,21 @@ define(["dojo/parser",
         Updater.prototype._update = function ()
         {
             var thisObj = this;
-            this.tabObject.startButton.set("disabled", !this.vhostData.state || this.vhostData.state != "STOPPED");
-            this.tabObject.stopButton.set("disabled", !this.vhostData.state || this.vhostData.state != "ACTIVE");
-            this.tabObject.editButton.set("disabled", !this.vhostData.state || this.vhostData.state == "UNAVAILABLE");
-            this.tabObject.downloadButton.set("disabled", !this.vhostData.state || this.vhostData.state != "ACTIVE");
+            this.tabObject.startButton.set("disabled", !this.vhostData.state || this.vhostData.state !== "STOPPED");
+            this.tabObject.stopButton.set("disabled", !this.vhostData.state || this.vhostData.state !== "ACTIVE");
+            this.tabObject.editButton.set("disabled", !this.vhostData.state || this.vhostData.state === "UNAVAILABLE");
+            this.tabObject.downloadButton.set("disabled", !this.vhostData.state || this.vhostData.state !== "ACTIVE");
             this.tabObject.deleteButton.set("disabled", !this.vhostData.state);
 
-            util.flattenStatistics(thisObj.vhostData);
             var queues = thisObj.vhostData["queues"];
             var exchanges = thisObj.vhostData["exchanges"];
 
-            thisObj.updateHeader();
-
-            var stats = thisObj.vhostData["statistics"];
+            thisObj.virtualhostStatistics.update(thisObj.vhostData.statistics);
+            thisObj.virtualhostStatistics.resize();
 
-            var sampleTime = new Date();
-            var messageIn = stats["messagesIn"];
-            var bytesIn = stats["bytesIn"];
-            var messageOut = stats["messagesOut"];
-            var bytesOut = stats["bytesOut"];
-
-            if (thisObj.sampleTime)
-            {
-                var samplePeriod = sampleTime.getTime() - thisObj.sampleTime.getTime();
-
-                var msgInRate = (1000 * (messageIn - thisObj.messageIn)) / samplePeriod;
-                var msgOutRate = (1000 * (messageOut - thisObj.messageOut)) / samplePeriod;
-                var bytesInRate = (1000 * (bytesIn - thisObj.bytesIn)) / samplePeriod;
-                var bytesOutRate = (1000 * (bytesOut - thisObj.bytesOut)) / samplePeriod;
-
-                thisObj.msgInRate.innerHTML = msgInRate.toFixed(0);
-                var bytesInFormat = formatter.formatBytes(bytesInRate);
-                thisObj.bytesInRate.innerHTML = "(" + bytesInFormat.value;
-                thisObj.bytesInRateUnits.innerHTML = bytesInFormat.units + "/s)";
-
-                thisObj.msgOutRate.innerHTML = msgOutRate.toFixed(0);
-                var bytesOutFormat = formatter.formatBytes(bytesOutRate);
-                thisObj.bytesOutRate.innerHTML = "(" + bytesOutFormat.value;
-                thisObj.bytesOutRateUnits.innerHTML = bytesOutFormat.units + "/s)";
-            }
-
-            thisObj.sampleTime = sampleTime;
-            thisObj.messageIn = messageIn;
-            thisObj.bytesIn = bytesIn;
-            thisObj.messageOut = messageOut;
-            thisObj.bytesOut = bytesOut;
+            thisObj.updateHeader();
 
-            this._updateGrids(thisObj.vhostData)
+            this._updateGrids(thisObj.vhostData);
 
             if (thisObj.details)
             {
@@ -579,7 +551,7 @@ define(["dojo/parser",
                     var oldConnection = null;
                     for (var j = 0; j < this._previousConsumers.length; j++)
                     {
-                        if (this._previousConsumers[j].id == connection.id)
+                        if (this._previousConsumers[j].id === connection.id)
                         {
                             oldConnection = this._previousConsumers[j];
                             break;
@@ -614,8 +586,8 @@ define(["dojo/parser",
 
         Updater.prototype._updateGrids = function (data)
         {
-            this.virtualHostChildren.style.display = data.state == "ACTIVE" ? "block" : "none";
-            if (data.state == "ACTIVE")
+            this.virtualHostChildren.style.display = data.state === "ACTIVE" ? "block" : "none";
+            if (data.state === "ACTIVE")
             {
                 util.updateUpdatableStore(this.queuesGrid, data.queues);
                 util.updateUpdatableStore(this.exchangesGrid, data.exchanges);

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/c977f76f/broker-plugins/management-http/src/main/java/resources/showBroker.html
----------------------------------------------------------------------
diff --git a/broker-plugins/management-http/src/main/java/resources/showBroker.html b/broker-plugins/management-http/src/main/java/resources/showBroker.html
index e176292..9132abe 100644
--- a/broker-plugins/management-http/src/main/java/resources/showBroker.html
+++ b/broker-plugins/management-http/src/main/java/resources/showBroker.html
@@ -62,6 +62,8 @@
             </div>
             <br/>
         </div>
+        <br/>
+        <div id="showBroker.statistics"></div>
         <div class="dijitDialogPaneActionBar">
             <button data-dojo-type="dijit.form.Button" class="editBroker">Edit</button>
             <button data-dojo-type="dijit.form.Button" class="restartBroker">Restart</button>
@@ -69,12 +71,10 @@
                 <span>Diagnostics</span>
                 <div data-dojo-type="dijit.Menu">
                     <div data-dojo-type="dijit.MenuItem"
-                         data-dojo-props="iconClass: 'downloadLogsIcon'">Download JVM thread-dump</div>
+                    data-dojo-props="iconClass: 'downloadLogsIcon'">Download JVM thread-dump</div>
                 </div>
             </div>
         </div>
-        <br/>
-        <div id="showBroker.statistics"></div>
     </div>
     <br/>
     <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Virtual Hosts'">

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/c977f76f/broker-plugins/management-http/src/main/java/resources/showExchange.html
----------------------------------------------------------------------
diff --git a/broker-plugins/management-http/src/main/java/resources/showExchange.html b/broker-plugins/management-http/src/main/java/resources/showExchange.html
index 4a75e6c..d25c9a6 100644
--- a/broker-plugins/management-http/src/main/java/resources/showExchange.html
+++ b/broker-plugins/management-http/src/main/java/resources/showExchange.html
@@ -48,35 +48,18 @@
                     <div class="alternateBinding formValue-valueCell"></div>
                 </div>
             </div>
-            <div class="alignRight">
-                <div class="clear">
-                    <div class="formLabel-labelCell">Inbound:</div>
-                    <div class="formValue-valueCell">
-                        <span class="msgInRate"></span>
-                        <span> msg/s</span>
-                        <span class="bytesInRate">(</span>
-                        <span class="bytesInRateUnits">)</span>
-                    </div>
-                </div>
-                <div class="clear">
-                    <div class="formLabel-labelCell">Dropped:</div>
-                    <div class="formValue-valueCell">
-                        <span class="msgDropRate"></span>
-                        <span> msg/s</span>
-                        <span class="bytesDropRate">(</span>
-                        <span class="bytesDropRateUnits">)</span>
-                    </div>
-                </div>
-            </div>
         </div>
 
         <div class="clear"></div>
     </div>
+    <br/>
+    <div class="exchangeStatistics"></div>
     <div class="dijitDialogPaneActionBar">
         <button data-dojo-type="dijit.form.Button" class="editExchangeButton" type="button">Edit Exchange</button>
         <button data-dojo-type="dijit.form.Button" class="deleteExchangeButton" type="button">Delete Exchange</button>
     </div>
     <br/>
+    <br/>
     <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Bindings'">
         <div class="bindings"></div>
         <button data-dojo-type="dijit.form.Button" class="addBindingButton">Add Binding</button>

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/c977f76f/broker-plugins/management-http/src/main/java/resources/showQueue.html
----------------------------------------------------------------------
diff --git a/broker-plugins/management-http/src/main/java/resources/showQueue.html b/broker-plugins/management-http/src/main/java/resources/showQueue.html
index 72f8ab1..6886324 100644
--- a/broker-plugins/management-http/src/main/java/resources/showQueue.html
+++ b/broker-plugins/management-http/src/main/java/resources/showQueue.html
@@ -61,52 +61,6 @@
                 </div>
             </div>
         </div>
-        <div class="alignRight">
-            <div class="clear">
-                <div class="formLabel-labelCell">Inbound:</div>
-                <div class="formValue-valueCell">
-                    <span class="msgInRate"></span>
-                    <span> msg/s</span>
-                    <span class="bytesInRate"></span>
-                    <span class="bytesInRateUnits"></span>
-                </div>
-            </div>
-            <div class="clear">
-                <div class="formLabel-labelCell">Outbound:</div>
-                <div class="formValue-valueCell">
-                    <span class="msgOutRate"></span>
-                    <span> msg/s</span>
-                    <span class="bytesOutRate"></span>
-                    <span class="bytesOutRateUnits"></span>
-                </div>
-            </div>
-            <div class="clear">
-                <div class="formLabel-labelCell">Queue Depth:</div>
-                <div class="formValue-valueCell">
-                    <span class="queueDepthMessagesIncludingHeader"></span>
-                    <span> msgs</span>
-                    <span class="queueDepthBytesIncludingHeader">(</span>
-                    <span class="queueDepthBytesUnitsIncludingHeader">)</span>
-                </div>
-            </div>
-            <div class="clear">
-                <div class="formLabel-labelCell">Pre-fetched:</div>
-                <div class="formValue-valueCell">
-                    <span class="unacknowledgedMessages"></span>
-                    <span> msgs</span>
-                    <span class="unacknowledgedBytes">(</span>
-                    <span class="unacknowledgedBytesUnits">)</span>
-                </div>
-            </div>
-            <div class="clear">
-                <div class="formLabel-labelCell">Oldest Message Age:</div>
-                <div class="formValue-valueCell">
-                    <span class="oldestMessageAge"></span>
-                    <span> secs</span>
-                </div>
-            </div>
-        </div>
-        <div class="clear"></div>
         <div class="clear">
             <div class="formLabel-labelCell">Enforced Max. Ttl(ms):</div>
             <div class="maximumMessageTtl"></div>
@@ -147,6 +101,8 @@
         </div>
         <div class="clear"></div>
     </div>
+    <br/>
+    <div class="queueStatistics"></div>
     <div class="dijitDialogPaneActionBar">
         <button data-dojo-type="dijit.form.Button" class="editQueueButton" type="button">Edit Queue</button>
         <button data-dojo-type="dijit.form.Button" class="deleteQueueButton" type="button">Delete Queue</button>
@@ -169,7 +125,6 @@
         <button data-dojo-type="dijit.form.Button" class="copyMessagesButton" type="button">Copy Messages</button>
         <button data-dojo-type="dijit.form.Button" class="refreshMessagesButton" type="button">Refresh</button>
     </div>
-
     <br/>
     <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Alerting Thresholds', open: false">
       <div class="clear">

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/c977f76f/broker-plugins/management-http/src/main/java/resources/showVirtualHost.html
----------------------------------------------------------------------
diff --git a/broker-plugins/management-http/src/main/java/resources/showVirtualHost.html b/broker-plugins/management-http/src/main/java/resources/showVirtualHost.html
index db2781d..e40dd19 100644
--- a/broker-plugins/management-http/src/main/java/resources/showVirtualHost.html
+++ b/broker-plugins/management-http/src/main/java/resources/showVirtualHost.html
@@ -32,26 +32,6 @@
                 <div class="type formValue-valueCell"></div>
             </div>
         </div>
-        <div class="alignRight">
-            <div class="clear">
-                <div class="formLabel-labelCell">Inbound:</div>
-                <div class="formValue-valueCell">
-                    <span class="msgInRate"></span>
-                    <span> msg/s</span>
-                    <span class="bytesInRate"></span>
-                    <span class="bytesInRateUnits"></span>
-                </div>
-            </div>
-            <div class="clear">
-                <div class="formLabel-labelCell">Outbound:</div>
-                <div class="formValue-valueCell">
-                    <span class="msgOutRate"></span>
-                    <span> msg/s</span>
-                    <span class="bytesOutRate"></span>
-                    <span class="bytesOutRateUnits"></span>
-                </div>
-            </div>
-        </div>
         <div class="clear"></div>
         <div class="clear">
             <div class="formLabel-labelCell">State:</div>
@@ -109,7 +89,8 @@
         </div>
 
     </div>
-
+    <br/>
+    <div class="virtualhostStatistics"></div>
     <div class="dijitDialogPaneActionBar">
         <div class="alignRight">
             <button data-dojo-type="dijit.form.Button" class="startButton" type="button" data-dojo-props="disabled: true">Start</button>
@@ -120,7 +101,6 @@
         </div>
         <div class="clear"></div>
     </div>
-
     <br/>
     <div class="virtualHostChildren">
         <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Exchanges'">


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org