You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by on...@apache.org on 2014/05/29 19:45:10 UTC
[1/8] AMBARI-5928. Create and populate Metrics section of a slider
app. (onechiporenko)
Repository: ambari
Updated Branches:
refs/heads/branch-1.6.0.slider 71aa9236d -> 79f3a1a3d
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/contrib/views/slider/src/main/resources/ui/app/assets/data/apptypes/all_fields.json
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/assets/data/apptypes/all_fields.json b/contrib/views/slider/src/main/resources/ui/app/assets/data/apptypes/all_fields.json
index 56fe759..68fef3c 100644
--- a/contrib/views/slider/src/main/resources/ui/app/assets/data/apptypes/all_fields.json
+++ b/contrib/views/slider/src/main/resources/ui/app/assets/data/apptypes/all_fields.json
@@ -60,17 +60,6 @@
"maxInstanceCount" : 0,
"yarnMemory" : 1024,
"yarnCpuCores" : 1
- },
- {
- "id" : "ACCUMULO_CLIENT",
- "name" : "ACCUMULO_CLIENT",
- "category" : "CLIENT",
- "displayName" : "ACCUMULO_CLIENT",
- "priority" : 0,
- "instanceCount" : 0,
- "maxInstanceCount" : 0,
- "yarnMemory" : 1024,
- "yarnCpuCores" : 1
}
],
"typeDescription" : "The Apache Accumulo sorted, distributed key/value store is a robust,\n scalable, high performance data storage system that features cell-based\n access control and customizable server-side processing. It is based on\n Google's BigTable design and is built on top of Apache Hadoop,\n Zookeeper, and Thrift.\n Requirements:\n 1. Ensure parent dir for path (accumulo-site/instance.dfs.dir) is accessible to the App owner.",
@@ -122,7 +111,7 @@
}
},
{
- "href" : "http://c6401:8080/api/v1/views/SLIDER/versions/1.0.0/instances/SLIDER_1/apptypes/HBASE",
+ "href" : "http://162.216.148.58:8080/api/v1/views/SLIDER/versions/1.0.0/instances/SLIDER_1/apptypes/HBASE",
"id" : "HBASE",
"instance_name" : "SLIDER_1",
"typeComponents" : [
@@ -147,25 +136,278 @@
"maxInstanceCount" : 0,
"yarnMemory" : 1024,
"yarnCpuCores" : 1
- },
- {
- "id" : "HBASE_CLIENT",
- "name" : "HBASE_CLIENT",
- "category" : "CLIENT",
- "displayName" : "HBASE_CLIENT",
- "priority" : 0,
- "instanceCount" : 0,
- "maxInstanceCount" : 0,
- "yarnMemory" : 1024,
- "yarnCpuCores" : 1
}
],
"typeDescription" : "Apache HBase is the Hadoop database, a distributed, scalable, big data store.\n Requirements:\n 1. Ensure parent dir for path (hbase-site/hbase.rootdir) is accessible to the App owner.\n 2. Ensure ZK root (hbase-site/zookeeper.znode.parent) is unique for the App instance.",
"typeName" : "HBASE",
- "typePackageFileName" : "hbase_v096 (1).zip",
+ "typePackageFileName" : "hbase_v096.zip",
"typeVersion" : "0.96.0.2.1.1",
"version" : "1.0.0",
"view_name" : "SLIDER",
+ "gangliaMetrics" : {
+ "Component" : {
+ "HBASE_MASTER" : {
+ "ClusterId" : {
+ "metric" : "Hadoop:service=HBase,name=Master,sub=Server.tag.clusterId",
+ "pointInTime" : true,
+ "temporal" : false,
+ "keyName" : "Hadoop:service=HBase,name=Master,sub=Server",
+ "matchers" : [
+ [
+ "tag",
+ "clusterId"
+ ],
+ [
+ "tag.clusterId"
+ ]
+ ]
+ },
+ "DeadRegionServers" : {
+ "metric" : "Hadoop:service=HBase,name=Master,sub=Server.numDeadRegionServers",
+ "pointInTime" : true,
+ "temporal" : false,
+ "keyName" : "Hadoop:service=HBase,name=Master,sub=Server",
+ "matchers" : [
+ [
+ "numDeadRegionServers"
+ ]
+ ]
+ },
+ "IsActiveMaster" : {
+ "metric" : "Hadoop:service=HBase,name=Master,sub=Server.tag.isActiveMaster",
+ "pointInTime" : true,
+ "temporal" : false,
+ "keyName" : "Hadoop:service=HBase,name=Master,sub=Server",
+ "matchers" : [
+ [
+ "tag",
+ "isActiveMaster"
+ ],
+ [
+ "tag.isActiveMaster"
+ ]
+ ]
+ },
+ "MasterActiveTime" : {
+ "metric" : "Hadoop:service=HBase,name=Master,sub=Server.masterActiveTime",
+ "pointInTime" : true,
+ "temporal" : false,
+ "keyName" : "Hadoop:service=HBase,name=Master,sub=Server",
+ "matchers" : [
+ [
+ "masterActiveTime"
+ ]
+ ]
+ },
+ "MasterStartTime" : {
+ "metric" : "Hadoop:service=HBase,name=Master,sub=Server.masterStartTime",
+ "pointInTime" : true,
+ "temporal" : false,
+ "keyName" : "Hadoop:service=HBase,name=Master,sub=Server",
+ "matchers" : [
+ [
+ "masterStartTime"
+ ]
+ ]
+ },
+ "RegionServers" : {
+ "metric" : "Hadoop:service=HBase,name=Master,sub=Server.numRegionServers",
+ "pointInTime" : true,
+ "temporal" : false,
+ "keyName" : "Hadoop:service=HBase,name=Master,sub=Server",
+ "matchers" : [
+ [
+ "numRegionServers"
+ ]
+ ]
+ },
+ "ServerName" : {
+ "metric" : "Hadoop:service=HBase,name=Master,sub=Server.tag.serverName",
+ "pointInTime" : true,
+ "temporal" : false,
+ "keyName" : "Hadoop:service=HBase,name=Master,sub=Server",
+ "matchers" : [
+ [
+ "tag",
+ "serverName"
+ ],
+ [
+ "tag.serverName"
+ ]
+ ]
+ },
+ "ZookeeperQuorum" : {
+ "metric" : "Hadoop:service=HBase,name=Master,sub=Server.tag.zookeeperQuorum",
+ "pointInTime" : true,
+ "temporal" : false,
+ "keyName" : "Hadoop:service=HBase,name=Master,sub=Server",
+ "matchers" : [
+ [
+ "tag",
+ "zookeeperQuorum"
+ ],
+ [
+ "tag.zookeeperQuorum"
+ ]
+ ]
+ },
+ "cluster_requests" : {
+ "metric" : "Hadoop:service=HBase,name=Master,sub=Server.clusterRequests",
+ "pointInTime" : true,
+ "temporal" : false,
+ "keyName" : "Hadoop:service=HBase,name=Master,sub=Server",
+ "matchers" : [
+ [
+ "clusterRequests"
+ ]
+ ]
+ },
+ "metricAverageLoad" : {
+ "metric" : "Hadoop:service=HBase,name=Master,sub=Server.averageLoad",
+ "pointInTime" : true,
+ "temporal" : false,
+ "keyName" : "Hadoop:service=HBase,name=Master,sub=Server",
+ "matchers" : [
+ [
+ "averageLoad"
+ ]
+ ]
+ }
+ }
+ }
+ },
+ "jmxMetrics" : {
+ "Component" : {
+ "HBASE_MASTER" : {
+ "ClusterId" : {
+ "metric" : "Hadoop:service=HBase,name=Master,sub=Server.tag.clusterId",
+ "pointInTime" : true,
+ "temporal" : false,
+ "keyName" : "Hadoop:service=HBase,name=Master,sub=Server",
+ "matchers" : [
+ [
+ "tag",
+ "clusterId"
+ ],
+ [
+ "tag.clusterId"
+ ]
+ ]
+ },
+ "DeadRegionServers" : {
+ "metric" : "Hadoop:service=HBase,name=Master,sub=Server.numDeadRegionServers",
+ "pointInTime" : true,
+ "temporal" : false,
+ "keyName" : "Hadoop:service=HBase,name=Master,sub=Server",
+ "matchers" : [
+ [
+ "numDeadRegionServers"
+ ]
+ ]
+ },
+ "IsActiveMaster" : {
+ "metric" : "Hadoop:service=HBase,name=Master,sub=Server.tag.isActiveMaster",
+ "pointInTime" : true,
+ "temporal" : false,
+ "keyName" : "Hadoop:service=HBase,name=Master,sub=Server",
+ "matchers" : [
+ [
+ "tag",
+ "isActiveMaster"
+ ],
+ [
+ "tag.isActiveMaster"
+ ]
+ ]
+ },
+ "MasterActiveTime" : {
+ "metric" : "Hadoop:service=HBase,name=Master,sub=Server.masterActiveTime",
+ "pointInTime" : true,
+ "temporal" : false,
+ "keyName" : "Hadoop:service=HBase,name=Master,sub=Server",
+ "matchers" : [
+ [
+ "masterActiveTime"
+ ]
+ ]
+ },
+ "MasterStartTime" : {
+ "metric" : "Hadoop:service=HBase,name=Master,sub=Server.masterStartTime",
+ "pointInTime" : true,
+ "temporal" : false,
+ "keyName" : "Hadoop:service=HBase,name=Master,sub=Server",
+ "matchers" : [
+ [
+ "masterStartTime"
+ ]
+ ]
+ },
+ "RegionServers" : {
+ "metric" : "Hadoop:service=HBase,name=Master,sub=Server.numRegionServers",
+ "pointInTime" : true,
+ "temporal" : false,
+ "keyName" : "Hadoop:service=HBase,name=Master,sub=Server",
+ "matchers" : [
+ [
+ "numRegionServers"
+ ]
+ ]
+ },
+ "ServerName" : {
+ "metric" : "Hadoop:service=HBase,name=Master,sub=Server.tag.serverName",
+ "pointInTime" : true,
+ "temporal" : false,
+ "keyName" : "Hadoop:service=HBase,name=Master,sub=Server",
+ "matchers" : [
+ [
+ "tag",
+ "serverName"
+ ],
+ [
+ "tag.serverName"
+ ]
+ ]
+ },
+ "ZookeeperQuorum" : {
+ "metric" : "Hadoop:service=HBase,name=Master,sub=Server.tag.zookeeperQuorum",
+ "pointInTime" : true,
+ "temporal" : false,
+ "keyName" : "Hadoop:service=HBase,name=Master,sub=Server",
+ "matchers" : [
+ [
+ "tag",
+ "zookeeperQuorum"
+ ],
+ [
+ "tag.zookeeperQuorum"
+ ]
+ ]
+ },
+ "cluster_requests" : {
+ "metric" : "Hadoop:service=HBase,name=Master,sub=Server.clusterRequests",
+ "pointInTime" : true,
+ "temporal" : false,
+ "keyName" : "Hadoop:service=HBase,name=Master,sub=Server",
+ "matchers" : [
+ [
+ "clusterRequests"
+ ]
+ ]
+ },
+ "metricAverageLoad" : {
+ "metric" : "Hadoop:service=HBase,name=Master,sub=Server.averageLoad",
+ "pointInTime" : true,
+ "temporal" : false,
+ "keyName" : "Hadoop:service=HBase,name=Master,sub=Server",
+ "matchers" : [
+ [
+ "averageLoad"
+ ]
+ ]
+ }
+ }
+ }
+ },
"typeConfigs" : {
"agent.conf" : "/slider/agent/conf/agent.ini",
"application.def" : "/slider/hbase_v096.zip",
@@ -221,9 +463,11 @@
}
},
{
- "href" : "http://c6401:8080/api/v1/views/SLIDER/versions/1.0.0/instances/SLIDER_1/apptypes/STORM",
+ "href" : "http://162.216.148.58:8080/api/v1/views/SLIDER/versions/1.0.0/instances/SLIDER_1/apptypes/STORM",
+ "gangliaMetrics" : null,
"id" : "STORM",
"instance_name" : "SLIDER_1",
+ "jmxMetrics" : null,
"typeComponents" : [
{
"id" : "NIMBUS",
@@ -393,4 +637,4 @@
}
}
]
-}
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app_controller.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app_controller.js b/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app_controller.js
index 06af9f3..77bf0a0 100644
--- a/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app_controller.js
+++ b/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app_controller.js
@@ -105,7 +105,6 @@ App.SliderAppController = Ember.ObjectController.extend({
},
/**
- * Do request to delete current slider's app
* Do request to <strong>freeze</strong> current slider's app
* @returns {$.ajax}
* @method freeze
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js b/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js
index 66b97bd..64c8385 100644
--- a/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js
+++ b/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js
@@ -102,7 +102,28 @@ var urls = {
data: JSON.stringify(data.data)
}
}
+ },
+
+ 'metrics': {
+ real: 'apps/{id}/metrics/{metric}',
+ mock: '/data/metrics/metric.json'
+ },
+
+ 'metrics2': {
+ real: 'apps/{id}/metrics/{metric}',
+ mock: '/data/metrics/metric2.json'
+ },
+
+ 'metrics3': {
+ real: 'apps/{id}/metrics/{metric}',
+ mock: '/data/metrics/metric3.json'
+ },
+
+ 'metrics4': {
+ real: 'apps/{id}/metrics/{metric}',
+ mock: '/data/metrics/metric4.json'
}
+
};
/**
* Replace data-placeholders to its values
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/contrib/views/slider/src/main/resources/ui/app/helpers/helper.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/helpers/helper.js b/contrib/views/slider/src/main/resources/ui/app/helpers/helper.js
index 75323c2..bfa0a68 100644
--- a/contrib/views/slider/src/main/resources/ui/app/helpers/helper.js
+++ b/contrib/views/slider/src/main/resources/ui/app/helpers/helper.js
@@ -24,4 +24,45 @@ String.prototype.format = function () {
});
};
+/**
+ * Helper function for bound property helper registration
+ * @memberof App
+ * @method registerBoundHelper
+ * @param name {String} name of helper
+ * @param view {Em.View} view
+ */
+App.registerBoundHelper = function(name, view) {
+ Ember.Handlebars.registerHelper(name, function(property, options) {
+ options.hash.contentBinding = property;
+ return Ember.Handlebars.helpers.view.call(this, view, options);
+ });
+};
+
+
+/**
+ * Return formatted string with inserted <code>wbr</code>-tag after each dot
+ *
+ * @param {String} content
+ *
+ * Examples:
+ *
+ * returns 'apple'
+ * {{formatWordBreak 'apple'}}
+ *
+ * returns 'apple.<wbr />banana'
+ * {{formatWordBreak 'apple.banana'}}
+ *
+ * returns 'apple.<wbr />banana.<wbr />uranium'
+ * {{formatWordBreak 'apple.banana.uranium'}}
+ */
+App.registerBoundHelper('formatWordBreak', Em.View.extend({
+ tagName: 'span',
+ template: Ember.Handlebars.compile('{{{view.result}}}'),
+ /**
+ * @type {string}
+ */
+ result: function() {
+ return this.get('content') && this.get('content').replace(/\//g, '/<wbr />');
+ }.property('content')
+}));
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/contrib/views/slider/src/main/resources/ui/app/mappers/slider_apps_mapper.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/mappers/slider_apps_mapper.js b/contrib/views/slider/src/main/resources/ui/app/mappers/slider_apps_mapper.js
index 5194c99..4f69ba2 100644
--- a/contrib/views/slider/src/main/resources/ui/app/mappers/slider_apps_mapper.js
+++ b/contrib/views/slider/src/main/resources/ui/app/mappers/slider_apps_mapper.js
@@ -112,6 +112,13 @@ App.SliderAppsMapper = App.Mapper.createWithMixins(App.RunPeriodically, {
return quickLinks.mapProperty('id');
},
+ parseObject: function(o) {
+ if (Ember.typeOf(o) !== 'object') return [];
+ return Ember.keys(o).map(function(key) {
+ return {key: key, value: o[key]};
+ });
+ },
+
/**
* Parse loaded data
* Load <code>App.SliderApp</code> model
@@ -124,8 +131,9 @@ App.SliderAppsMapper = App.Mapper.createWithMixins(App.RunPeriodically, {
data.items.forEach(function(app) {
var componentsId = app.components ? self.parseComponents(app) : [],
- configs = app.configs ? self.parseConfigs(app) : {};
- quickLinks = self.parseQuickLinks(app);
+ configs = app.configs ? self.parseConfigs(app) : {},
+ quickLinks = self.parseQuickLinks(app),
+ jmx = self.parseObject(app.jmx);
apps.push(
Ember.Object.create({
@@ -141,6 +149,7 @@ App.SliderAppsMapper = App.Mapper.createWithMixins(App.RunPeriodically, {
components: componentsId,
quickLinks: quickLinks,
configs: configs,
+ jmx: jmx,
runtimeProperties: app.configs
})
);
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/contrib/views/slider/src/main/resources/ui/app/models/slider_app.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/models/slider_app.js b/contrib/views/slider/src/main/resources/ui/app/models/slider_app.js
index 14c4a32..f82adcf 100644
--- a/contrib/views/slider/src/main/resources/ui/app/models/slider_app.js
+++ b/contrib/views/slider/src/main/resources/ui/app/models/slider_app.js
@@ -92,6 +92,8 @@ App.SliderApp = DS.Model.extend({
*/
configs: DS.attr('object'),
+ jmx: DS.attr('object'),
+
/**
* Global configs
* @type {{key: string, value: *}[]}
@@ -99,7 +101,7 @@ App.SliderApp = DS.Model.extend({
globals: function() {
var c = this.get('configs.global');
return this.mapObject(c);
- }.property('configs.global'),
+ }.property('configs.@each'),
/**
* HBase-Site configs
@@ -108,7 +110,7 @@ App.SliderApp = DS.Model.extend({
hbaseSite: function() {
var c = this.get('configs.hbase-site');
return this.mapObject(c);
- }.property('configs.hbase-site'),
+ }.property('configs.@each'),
/**
* Configs which are not in global or hbase-site
@@ -124,7 +126,15 @@ App.SliderApp = DS.Model.extend({
ret = ret.concat(self.mapObject(c[key]));
});
return ret;
- }.property('configs'),
+ }.property('configs.@each'),
+
+ /**
+ * Display metrics only for running apps
+ * @type {boolean}
+ */
+ showMetrics: function() {
+ return App.SliderApp.Status.running === this.get('status');
+ }.property('status'),
/**
* Map object to array
@@ -151,4 +161,4 @@ App.SliderApp.Status = {
new_saving: "NEW_SAVING",
running: "RUNNING" ,
submitted:"SUBMITTED"
-};
\ No newline at end of file
+};
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/contrib/views/slider/src/main/resources/ui/app/routes/main.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/routes/main.js b/contrib/views/slider/src/main/resources/ui/app/routes/main.js
index f875ffa..07babda 100644
--- a/contrib/views/slider/src/main/resources/ui/app/routes/main.js
+++ b/contrib/views/slider/src/main/resources/ui/app/routes/main.js
@@ -18,6 +18,10 @@
App.IndexRoute = Ember.Route.extend({
+ model: function () {
+ return this.modelFor('sliderApps');
+ },
+
redirect: function () {
this.transitionTo('slider_apps');
}
@@ -40,7 +44,7 @@ App.SliderAppsRoute = Ember.Route.extend({
App.SliderAppRoute = Ember.Route.extend({
model: function(params) {
- return this.store.find('sliderApp', params.slider_app_id);
+ return this.store.all('sliderApp', params.slider_app_id);
}
});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/contrib/views/slider/src/main/resources/ui/app/styles/application.less
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/styles/application.less b/contrib/views/slider/src/main/resources/ui/app/styles/application.less
index cbf466c..a4347b9 100644
--- a/contrib/views/slider/src/main/resources/ui/app/styles/application.less
+++ b/contrib/views/slider/src/main/resources/ui/app/styles/application.less
@@ -504,4 +504,94 @@ a {
}
.modal-backdrop.in {
opacity:0;
-}
\ No newline at end of file
+}
+
+/**
+ * App Summary Page
+ */
+.app_summary {
+ .container {
+ padding-left: 0;
+ }
+}
+
+
+.chart-container {
+ cursor: default;
+
+ position: relative;
+ margin: 20px 15px 0px 15px;
+
+ .chart {
+ position: relative;
+ z-index: 1;
+ }
+ .chart-y-axis {
+ position: absolute;
+ top: 0;
+ bottom: 0px;
+ width: 100px;
+ z-index: 2;
+ margin-top: 15px;
+ }
+ .chart-x-axis {
+ position: absolute;
+ top: 180px;
+ left: 35%;
+ width: 30%;
+ z-index: 2;
+ }
+ .x_tick {
+ margin-top: 5px;
+ .title {
+ padding: 0 2px 0 2px;
+ opacity: 1 !important;
+ top: 148px;
+ }
+ }
+ svg {
+ g {
+ g:nth-child(1) {
+ display: none;
+ }
+ }
+ }
+ text {
+ font-weight: 700;
+ opacity: 1 !important;
+ }
+ .chart-legend {
+ font-family: 'Courier New';
+ position: absolute;
+ top: 180px;
+ z-index: 3;
+ }
+ .rickshaw_legend {
+ background-color: #999 !important;
+ li:hover {
+ background-color: #999 !important;
+ }
+ }
+ .rickshaw_legend:empty {
+ padding: 0;
+ }
+ .rickshaw_graph {
+ .x_tick {
+ .title {
+ bottom: -6px;
+ opacity: 0.75;
+ }
+ }
+ }
+ .chart-overlay {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ width: 100%;
+ z-index: 5;
+ }
+ .chart-title {
+ text-align: center;
+ margin-top: 20px;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/configs.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/configs.hbs b/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/configs.hbs
index 5e07e57..520ed45 100644
--- a/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/configs.hbs
+++ b/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/configs.hbs
@@ -29,7 +29,7 @@
{{#each model.otherConfigs}}
<tr>
<td>{{key}}</td>
- <td>{{value}}</td>
+ <td>{{formatWordBreak value}}</td>
</tr>
{{/each}}
</tbody>
@@ -50,7 +50,7 @@
{{#each model.globals}}
<tr>
<td>{{key}}</td>
- <td>{{value}}</td>
+ <td>{{formatWordBreak value}}</td>
</tr>
{{/each}}
</tbody>
@@ -71,10 +71,10 @@
{{#each model.hbaseSite}}
<tr>
<td>{{key}}</td>
- <td>{{value}}</td>
+ <td>{{formatWordBreak value}}</td>
</tr>
{{/each}}
</tbody>
</table>
{{/bs-panel}}
-{{/if}}
\ No newline at end of file
+{{/if}}
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/summary.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/summary.hbs b/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/summary.hbs
index fab5ea8..dbf6f62 100644
--- a/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/summary.hbs
+++ b/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/summary.hbs
@@ -15,6 +15,27 @@
* See the License for the specific language governing permissions and
* limitations under the License.
}}
-Summary
-{{model.id}}
\ No newline at end of file
+<div class="container">
+ <div class="row">
+ <div class="col-md-6">
+ {{#bs-panel heading="Summary"}}
+ {{/bs-panel}}
+ </div>
+ <div class="col-md-6">
+ {{#bs-panel heading="Components"}}
+ {{/bs-panel}}
+ </div>
+ </div>
+ {{#if controller.model.showMetrics}}
+ {{#bs-panel heading="Metrics"}}
+ {{#each graphs in view.parentView.graphs}}
+ <div class="row">
+ {{#each graph in graphs}}
+ <div class="col-md-3">{{view graph}}</div>
+ {{/each}}
+ </div>
+ {{/each}}
+ {{/bs-panel}}
+ {{/if}}
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/contrib/views/slider/src/main/resources/ui/config.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/config.js b/contrib/views/slider/src/main/resources/ui/config.js
index 8ba0087..978d984 100755
--- a/contrib/views/slider/src/main/resources/ui/config.js
+++ b/contrib/views/slider/src/main/resources/ui/config.js
@@ -28,8 +28,15 @@ exports.config = {
},
order: {
before: [
+ 'vendor/scripts/common/d3.v2.js',
+ 'vendor/scripts/common/cubism.v1.js',
+ 'vendor/scripts/common/rickshaw.js',
'vendor/scripts/common/console-polyfill.js',
'vendor/scripts/common/jquery.js',
+ 'vendor/scripts/common/jquery.ui.core.js',
+ 'vendor/scripts/common/jquery.ui.widget.js',
+ 'vendor/scripts/common/jquery.ui.mouse.js',
+ 'vendor/scripts/common/jquery.ui.sortable.js',
'vendor/scripts/common/handlebars.js',
'vendor/scripts/development/ember.js',
'vendor/scripts/production/ember-data.js',
@@ -49,6 +56,8 @@ exports.config = {
},
order: {
before: [
+ 'vendor/styles/cubism.css',
+ 'vendor/styles/rickshaw.css',
'vendor/styles/bootstrap.css',
'vendor/styles/font-awesome.css',
'vendor/styles/font-awesome-ie7.css'
@@ -75,6 +84,9 @@ exports.config = {
},
order: {
before: [
+ 'vendor/scripts/common/d3.v2.js',
+ 'vendor/scripts/common/cubism.v1.js',
+ 'vendor/scripts/common/rickshaw.js',
'vendor/scripts/common/console-polyfill.js',
'vendor/scripts/common/jquery.js',
'vendor/scripts/common/handlebars.js',
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/contrib/views/slider/src/main/resources/ui/package.json
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/package.json b/contrib/views/slider/src/main/resources/ui/package.json
index 2d2ea16..daf0943 100755
--- a/contrib/views/slider/src/main/resources/ui/package.json
+++ b/contrib/views/slider/src/main/resources/ui/package.json
@@ -26,7 +26,6 @@
"stylus-brunch": "~1.7.0",
"uglify-js-brunch": "~1.7.0",
"clean-css-brunch": "~1.7.0",
- "auto-reload-brunch": "~1.7.0",
"ember-handlebars-brunch": "git://github.com/fuseelements/ember-handlebars-brunch#fix/ember-1.3.0"
},
"devDependencies": {
[6/8] AMBARI-5928. Create and populate Metrics section of a slider
app. (onechiporenko)
Posted by on...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/ambari-web/contrib/views/slider/src/main/resources/ui/app/assets/data/metrics/metric3.json
----------------------------------------------------------------------
diff --git a/ambari-web/contrib/views/slider/src/main/resources/ui/app/assets/data/metrics/metric3.json b/ambari-web/contrib/views/slider/src/main/resources/ui/app/assets/data/metrics/metric3.json
new file mode 100644
index 0000000..83b4121
--- /dev/null
+++ b/ambari-web/contrib/views/slider/src/main/resources/ui/app/assets/data/metrics/metric3.json
@@ -0,0 +1,1856 @@
+{
+ "metrics" : {
+ "dfs" : {
+ "namenode" : {
+ "CreateFileOps" : [
+ [
+ 0.0,
+ 1401359340
+ ],
+ [
+ 0.0,
+ 1401359355
+ ],
+ [
+ 0.0,
+ 1401359370
+ ],
+ [
+ 0.0,
+ 1401359385
+ ],
+ [
+ 0.0,
+ 1401359400
+ ],
+ [
+ 0.0,
+ 1401359415
+ ],
+ [
+ 0.0,
+ 1401359430
+ ],
+ [
+ 0.0,
+ 1401359445
+ ],
+ [
+ 0.0,
+ 1401359460
+ ],
+ [
+ 0.0,
+ 1401359475
+ ],
+ [
+ 0.0,
+ 1401359490
+ ],
+ [
+ 0.0,
+ 1401359505
+ ],
+ [
+ 0.0,
+ 1401359520
+ ],
+ [
+ 0.0,
+ 1401359535
+ ],
+ [
+ 0.0,
+ 1401359550
+ ],
+ [
+ 0.0,
+ 1401359565
+ ],
+ [
+ 0.0,
+ 1401359580
+ ],
+ [
+ 0.0,
+ 1401359595
+ ],
+ [
+ 0.0,
+ 1401359610
+ ],
+ [
+ 0.0,
+ 1401359625
+ ],
+ [
+ 0.0,
+ 1401359640
+ ],
+ [
+ 0.0,
+ 1401359655
+ ],
+ [
+ 0.0,
+ 1401359670
+ ],
+ [
+ 0.0,
+ 1401359685
+ ],
+ [
+ 0.0,
+ 1401359700
+ ],
+ [
+ 0.0,
+ 1401359715
+ ],
+ [
+ 0.0,
+ 1401359730
+ ],
+ [
+ 0.0,
+ 1401359745
+ ],
+ [
+ 0.0,
+ 1401359760
+ ],
+ [
+ 0.0,
+ 1401359775
+ ],
+ [
+ 0.0,
+ 1401359790
+ ],
+ [
+ 0.0,
+ 1401359805
+ ],
+ [
+ 0.0,
+ 1401359820
+ ],
+ [
+ 0.0,
+ 1401359835
+ ],
+ [
+ 0.0,
+ 1401359850
+ ],
+ [
+ 0.0,
+ 1401359865
+ ],
+ [
+ 0.0,
+ 1401359880
+ ],
+ [
+ 0.0,
+ 1401359895
+ ],
+ [
+ 0.0,
+ 1401359910
+ ],
+ [
+ 0.0,
+ 1401359925
+ ],
+ [
+ 0.0,
+ 1401359940
+ ],
+ [
+ 0.0,
+ 1401359955
+ ],
+ [
+ 0.0,
+ 1401359970
+ ],
+ [
+ 0.0,
+ 1401359985
+ ],
+ [
+ 0.0,
+ 1401360000
+ ],
+ [
+ 0.0,
+ 1401360015
+ ],
+ [
+ 0.0,
+ 1401360030
+ ],
+ [
+ 0.0,
+ 1401360045
+ ],
+ [
+ 0.0,
+ 1401360060
+ ],
+ [
+ 0.0,
+ 1401360075
+ ],
+ [
+ 0.0,
+ 1401360090
+ ],
+ [
+ 0.0,
+ 1401360105
+ ],
+ [
+ 0.0,
+ 1401360120
+ ],
+ [
+ 0.0,
+ 1401360135
+ ],
+ [
+ 0.0,
+ 1401360150
+ ],
+ [
+ 0.0,
+ 1401360165
+ ],
+ [
+ 0.0,
+ 1401360180
+ ],
+ [
+ 0.0,
+ 1401360195
+ ],
+ [
+ 0.0,
+ 1401360210
+ ],
+ [
+ 0.0,
+ 1401360225
+ ],
+ [
+ 0.0,
+ 1401360240
+ ],
+ [
+ 0.0,
+ 1401360255
+ ],
+ [
+ 0.0,
+ 1401360270
+ ],
+ [
+ 0.0,
+ 1401360285
+ ],
+ [
+ 0.0,
+ 1401360300
+ ],
+ [
+ 0.0,
+ 1401360315
+ ],
+ [
+ 0.0,
+ 1401360330
+ ],
+ [
+ 0.0,
+ 1401360345
+ ],
+ [
+ 0.0,
+ 1401360360
+ ],
+ [
+ 0.0,
+ 1401360375
+ ],
+ [
+ 0.0,
+ 1401360390
+ ],
+ [
+ 0.0,
+ 1401360405
+ ],
+ [
+ 0.0,
+ 1401360420
+ ],
+ [
+ 0.0,
+ 1401360435
+ ],
+ [
+ 0.0,
+ 1401360450
+ ],
+ [
+ 0.0,
+ 1401360465
+ ],
+ [
+ 0.0,
+ 1401360480
+ ],
+ [
+ 0.0,
+ 1401360495
+ ],
+ [
+ 0.0,
+ 1401360510
+ ],
+ [
+ 0.0,
+ 1401360525
+ ],
+ [
+ 0.0,
+ 1401360540
+ ],
+ [
+ 0.0,
+ 1401360555
+ ],
+ [
+ 0.0,
+ 1401360570
+ ],
+ [
+ 0.0,
+ 1401360585
+ ],
+ [
+ 0.0,
+ 1401360600
+ ],
+ [
+ 0.0,
+ 1401360615
+ ],
+ [
+ 0.0,
+ 1401360630
+ ],
+ [
+ 0.0,
+ 1401360645
+ ],
+ [
+ 0.0,
+ 1401360660
+ ],
+ [
+ 0.0,
+ 1401360675
+ ],
+ [
+ 0.0,
+ 1401360690
+ ],
+ [
+ 0.0,
+ 1401360705
+ ],
+ [
+ 0.0,
+ 1401360720
+ ],
+ [
+ 0.0,
+ 1401360735
+ ],
+ [
+ 0.0,
+ 1401360750
+ ],
+ [
+ 0.0,
+ 1401360765
+ ],
+ [
+ 0.0,
+ 1401360780
+ ],
+ [
+ 0.0,
+ 1401360795
+ ],
+ [
+ 0.0,
+ 1401360810
+ ],
+ [
+ 0.0,
+ 1401360825
+ ],
+ [
+ 0.0,
+ 1401360840
+ ],
+ [
+ 0.0,
+ 1401360855
+ ],
+ [
+ 0.0,
+ 1401360870
+ ],
+ [
+ 0.0,
+ 1401360885
+ ],
+ [
+ 0.0,
+ 1401360900
+ ],
+ [
+ 0.0,
+ 1401360915
+ ],
+ [
+ 0.0,
+ 1401360930
+ ],
+ [
+ 0.0,
+ 1401360945
+ ],
+ [
+ 0.0,
+ 1401360960
+ ],
+ [
+ 0.0,
+ 1401360975
+ ],
+ [
+ 0.0,
+ 1401360990
+ ],
+ [
+ 0.0,
+ 1401361005
+ ],
+ [
+ 0.0,
+ 1401361020
+ ],
+ [
+ 0.0,
+ 1401361035
+ ],
+ [
+ 0.0,
+ 1401361050
+ ],
+ [
+ 0.0,
+ 1401361065
+ ],
+ [
+ 0.0,
+ 1401361080
+ ],
+ [
+ 0.0,
+ 1401361095
+ ],
+ [
+ 0.0,
+ 1401361110
+ ],
+ [
+ 0.0,
+ 1401361125
+ ],
+ [
+ 0.0,
+ 1401361140
+ ],
+ [
+ 0.0,
+ 1401361155
+ ],
+ [
+ 0.0,
+ 1401361170
+ ],
+ [
+ 0.0,
+ 1401361185
+ ],
+ [
+ 0.0,
+ 1401361200
+ ],
+ [
+ 0.0,
+ 1401361215
+ ],
+ [
+ 0.0,
+ 1401361230
+ ],
+ [
+ 0.0,
+ 1401361245
+ ],
+ [
+ 0.0,
+ 1401361260
+ ],
+ [
+ 0.0,
+ 1401361275
+ ],
+ [
+ 0.0,
+ 1401361290
+ ],
+ [
+ 0.0,
+ 1401361305
+ ],
+ [
+ 0.0,
+ 1401361320
+ ],
+ [
+ 0.0,
+ 1401361335
+ ],
+ [
+ 0.0,
+ 1401361350
+ ],
+ [
+ 0.0,
+ 1401361365
+ ],
+ [
+ 0.0,
+ 1401361380
+ ],
+ [
+ 0.0,
+ 1401361395
+ ],
+ [
+ 0.0,
+ 1401361410
+ ],
+ [
+ 0.0,
+ 1401361425
+ ],
+ [
+ 0.0,
+ 1401361440
+ ],
+ [
+ 0.0,
+ 1401361455
+ ],
+ [
+ 0.0,
+ 1401361470
+ ],
+ [
+ 0.0,
+ 1401361485
+ ],
+ [
+ 0.0,
+ 1401361500
+ ],
+ [
+ 0.0,
+ 1401361515
+ ],
+ [
+ 0.0,
+ 1401361530
+ ],
+ [
+ 0.0,
+ 1401361545
+ ],
+ [
+ 0.0,
+ 1401361560
+ ],
+ [
+ 0.0,
+ 1401361575
+ ],
+ [
+ 0.0,
+ 1401361590
+ ],
+ [
+ 0.0,
+ 1401361605
+ ],
+ [
+ 0.0,
+ 1401361620
+ ],
+ [
+ 0.0,
+ 1401361635
+ ],
+ [
+ 0.0,
+ 1401361650
+ ],
+ [
+ 0.0,
+ 1401361665
+ ],
+ [
+ 0.0,
+ 1401361680
+ ],
+ [
+ 0.0,
+ 1401361695
+ ],
+ [
+ 0.0,
+ 1401361710
+ ],
+ [
+ 0.0,
+ 1401361725
+ ],
+ [
+ 0.0,
+ 1401361740
+ ],
+ [
+ 0.0,
+ 1401361755
+ ],
+ [
+ 0.0,
+ 1401361770
+ ],
+ [
+ 0.0,
+ 1401361785
+ ],
+ [
+ 0.0,
+ 1401361800
+ ],
+ [
+ 0.0,
+ 1401361815
+ ],
+ [
+ 0.0,
+ 1401361830
+ ],
+ [
+ 0.0,
+ 1401361845
+ ],
+ [
+ 0.0,
+ 1401361860
+ ],
+ [
+ 0.0,
+ 1401361875
+ ],
+ [
+ 0.0,
+ 1401361890
+ ],
+ [
+ 0.0,
+ 1401361905
+ ],
+ [
+ 0.0,
+ 1401361920
+ ],
+ [
+ 0.0,
+ 1401361935
+ ],
+ [
+ 0.08,
+ 1401361950
+ ],
+ [
+ 0.0533333333333,
+ 1401361965
+ ],
+ [
+ 0.0,
+ 1401361980
+ ],
+ [
+ 0.0,
+ 1401361995
+ ],
+ [
+ 0.0,
+ 1401362010
+ ],
+ [
+ 0.0,
+ 1401362025
+ ],
+ [
+ 0.0,
+ 1401362040
+ ],
+ [
+ 0.0,
+ 1401362055
+ ],
+ [
+ 0.0,
+ 1401362070
+ ],
+ [
+ 0.0,
+ 1401362085
+ ],
+ [
+ 0.0,
+ 1401362100
+ ],
+ [
+ 0.0,
+ 1401362115
+ ],
+ [
+ 0.0,
+ 1401362130
+ ],
+ [
+ 0.0,
+ 1401362145
+ ],
+ [
+ 0.0,
+ 1401362160
+ ],
+ [
+ 0.0,
+ 1401362175
+ ],
+ [
+ 0.0,
+ 1401362190
+ ],
+ [
+ 0.0,
+ 1401362205
+ ],
+ [
+ 0.0,
+ 1401362220
+ ],
+ [
+ 0.0,
+ 1401362235
+ ],
+ [
+ 0.0,
+ 1401362250
+ ],
+ [
+ 0.0,
+ 1401362265
+ ],
+ [
+ 0.0,
+ 1401362280
+ ],
+ [
+ 0.0,
+ 1401362295
+ ],
+ [
+ 0.0,
+ 1401362310
+ ],
+ [
+ 0.0,
+ 1401362325
+ ],
+ [
+ 0.0,
+ 1401362340
+ ],
+ [
+ 0.0,
+ 1401362355
+ ],
+ [
+ 0.0,
+ 1401362370
+ ],
+ [
+ 0.0,
+ 1401362385
+ ],
+ [
+ 0.0,
+ 1401362400
+ ],
+ [
+ 0.0,
+ 1401362415
+ ],
+ [
+ 0.0,
+ 1401362430
+ ],
+ [
+ 0.0,
+ 1401362445
+ ],
+ [
+ 0.0,
+ 1401362460
+ ],
+ [
+ 0.0,
+ 1401362475
+ ],
+ [
+ 0.0,
+ 1401362490
+ ],
+ [
+ 0.0,
+ 1401362505
+ ],
+ [
+ 0.0,
+ 1401362520
+ ],
+ [
+ 0.0,
+ 1401362535
+ ],
+ [
+ 0.0,
+ 1401362550
+ ],
+ [
+ 0.0,
+ 1401362565
+ ],
+ [
+ 0.0,
+ 1401362580
+ ],
+ [
+ 0.0,
+ 1401362595
+ ],
+ [
+ 0.0,
+ 1401362610
+ ],
+ [
+ 0.0,
+ 1401362625
+ ],
+ [
+ 0.0,
+ 1401362640
+ ],
+ [
+ 0.0,
+ 1401362655
+ ],
+ [
+ 0.0,
+ 1401362670
+ ],
+ [
+ 0.0,
+ 1401362685
+ ]
+ ],
+ "FileInfoOps" : [
+ [
+ 0.0,
+ 1401359340
+ ],
+ [
+ 0.0,
+ 1401359355
+ ],
+ [
+ 0.0,
+ 1401359370
+ ],
+ [
+ 0.0,
+ 1401359385
+ ],
+ [
+ 0.0,
+ 1401359400
+ ],
+ [
+ 0.0,
+ 1401359415
+ ],
+ [
+ 0.0,
+ 1401359430
+ ],
+ [
+ 0.0,
+ 1401359445
+ ],
+ [
+ 0.0,
+ 1401359460
+ ],
+ [
+ 0.0,
+ 1401359475
+ ],
+ [
+ 0.0,
+ 1401359490
+ ],
+ [
+ 0.0,
+ 1401359505
+ ],
+ [
+ 0.0177777777778,
+ 1401359520
+ ],
+ [
+ 0.115555555556,
+ 1401359535
+ ],
+ [
+ 0.0,
+ 1401359550
+ ],
+ [
+ 0.0,
+ 1401359565
+ ],
+ [
+ 0.0,
+ 1401359580
+ ],
+ [
+ 0.0,
+ 1401359595
+ ],
+ [
+ 0.0,
+ 1401359610
+ ],
+ [
+ 0.0,
+ 1401359625
+ ],
+ [
+ 0.0,
+ 1401359640
+ ],
+ [
+ 0.0,
+ 1401359655
+ ],
+ [
+ 0.0,
+ 1401359670
+ ],
+ [
+ 0.0,
+ 1401359685
+ ],
+ [
+ 0.0,
+ 1401359700
+ ],
+ [
+ 0.0,
+ 1401359715
+ ],
+ [
+ 0.0,
+ 1401359730
+ ],
+ [
+ 0.0,
+ 1401359745
+ ],
+ [
+ 0.0,
+ 1401359760
+ ],
+ [
+ 0.0,
+ 1401359775
+ ],
+ [
+ 0.0,
+ 1401359790
+ ],
+ [
+ 0.0,
+ 1401359805
+ ],
+ [
+ 0.025,
+ 1401359820
+ ],
+ [
+ 0.108333333333,
+ 1401359835
+ ],
+ [
+ 0.0,
+ 1401359850
+ ],
+ [
+ 0.0,
+ 1401359865
+ ],
+ [
+ 0.0,
+ 1401359880
+ ],
+ [
+ 0.0,
+ 1401359895
+ ],
+ [
+ 0.0,
+ 1401359910
+ ],
+ [
+ 0.0,
+ 1401359925
+ ],
+ [
+ 0.0,
+ 1401359940
+ ],
+ [
+ 0.0,
+ 1401359955
+ ],
+ [
+ 0.0,
+ 1401359970
+ ],
+ [
+ 0.0,
+ 1401359985
+ ],
+ [
+ 0.0,
+ 1401360000
+ ],
+ [
+ 0.0,
+ 1401360015
+ ],
+ [
+ 0.0,
+ 1401360030
+ ],
+ [
+ 0.0,
+ 1401360045
+ ],
+ [
+ 0.0,
+ 1401360060
+ ],
+ [
+ 0.0,
+ 1401360075
+ ],
+ [
+ 0.0,
+ 1401360090
+ ],
+ [
+ 0.0,
+ 1401360105
+ ],
+ [
+ 0.0,
+ 1401360120
+ ],
+ [
+ 0.133333333333,
+ 1401360135
+ ],
+ [
+ 0.0,
+ 1401360150
+ ],
+ [
+ 0.0,
+ 1401360165
+ ],
+ [
+ 0.0,
+ 1401360180
+ ],
+ [
+ 0.0,
+ 1401360195
+ ],
+ [
+ 0.0,
+ 1401360210
+ ],
+ [
+ 0.0,
+ 1401360225
+ ],
+ [
+ 0.0,
+ 1401360240
+ ],
+ [
+ 0.0,
+ 1401360255
+ ],
+ [
+ 0.0,
+ 1401360270
+ ],
+ [
+ 0.0,
+ 1401360285
+ ],
+ [
+ 0.0,
+ 1401360300
+ ],
+ [
+ 0.0,
+ 1401360315
+ ],
+ [
+ 0.0,
+ 1401360330
+ ],
+ [
+ 0.0,
+ 1401360345
+ ],
+ [
+ 0.0,
+ 1401360360
+ ],
+ [
+ 0.0,
+ 1401360375
+ ],
+ [
+ 0.0,
+ 1401360390
+ ],
+ [
+ 0.0,
+ 1401360405
+ ],
+ [
+ 0.108333333333,
+ 1401360420
+ ],
+ [
+ 0.025,
+ 1401360435
+ ],
+ [
+ 0.0,
+ 1401360450
+ ],
+ [
+ 0.0,
+ 1401360465
+ ],
+ [
+ 0.0,
+ 1401360480
+ ],
+ [
+ 0.0,
+ 1401360495
+ ],
+ [
+ 0.0,
+ 1401360510
+ ],
+ [
+ 0.0,
+ 1401360525
+ ],
+ [
+ 0.0,
+ 1401360540
+ ],
+ [
+ 0.0,
+ 1401360555
+ ],
+ [
+ 0.0,
+ 1401360570
+ ],
+ [
+ 0.0,
+ 1401360585
+ ],
+ [
+ 0.0,
+ 1401360600
+ ],
+ [
+ 0.0,
+ 1401360615
+ ],
+ [
+ 0.0,
+ 1401360630
+ ],
+ [
+ 0.0,
+ 1401360645
+ ],
+ [
+ 0.0,
+ 1401360660
+ ],
+ [
+ 0.0,
+ 1401360675
+ ],
+ [
+ 0.0,
+ 1401360690
+ ],
+ [
+ 0.0,
+ 1401360705
+ ],
+ [
+ 0.0,
+ 1401360720
+ ],
+ [
+ 0.12380952381,
+ 1401360735
+ ],
+ [
+ 0.00952380952381,
+ 1401360750
+ ],
+ [
+ 0.0,
+ 1401360765
+ ],
+ [
+ 0.0,
+ 1401360780
+ ],
+ [
+ 0.0,
+ 1401360795
+ ],
+ [
+ 0.0,
+ 1401360810
+ ],
+ [
+ 0.0,
+ 1401360825
+ ],
+ [
+ 0.0,
+ 1401360840
+ ],
+ [
+ 0.0,
+ 1401360855
+ ],
+ [
+ 0.0,
+ 1401360870
+ ],
+ [
+ 0.0,
+ 1401360885
+ ],
+ [
+ 0.0,
+ 1401360900
+ ],
+ [
+ 0.0,
+ 1401360915
+ ],
+ [
+ 0.0,
+ 1401360930
+ ],
+ [
+ 0.0,
+ 1401360945
+ ],
+ [
+ 0.0,
+ 1401360960
+ ],
+ [
+ 0.0,
+ 1401360975
+ ],
+ [
+ 0.0,
+ 1401360990
+ ],
+ [
+ 0.0,
+ 1401361005
+ ],
+ [
+ 0.0,
+ 1401361020
+ ],
+ [
+ 0.115555555556,
+ 1401361035
+ ],
+ [
+ 0.0177777777778,
+ 1401361050
+ ],
+ [
+ 0.0,
+ 1401361065
+ ],
+ [
+ 0.0,
+ 1401361080
+ ],
+ [
+ 0.0,
+ 1401361095
+ ],
+ [
+ 0.0,
+ 1401361110
+ ],
+ [
+ 0.0,
+ 1401361125
+ ],
+ [
+ 0.0,
+ 1401361140
+ ],
+ [
+ 0.0,
+ 1401361155
+ ],
+ [
+ 0.0,
+ 1401361170
+ ],
+ [
+ 0.0,
+ 1401361185
+ ],
+ [
+ 0.0,
+ 1401361200
+ ],
+ [
+ 0.0,
+ 1401361215
+ ],
+ [
+ 0.0,
+ 1401361230
+ ],
+ [
+ 0.0,
+ 1401361245
+ ],
+ [
+ 0.0,
+ 1401361260
+ ],
+ [
+ 0.0,
+ 1401361275
+ ],
+ [
+ 0.0,
+ 1401361290
+ ],
+ [
+ 0.0,
+ 1401361305
+ ],
+ [
+ 0.0888888888889,
+ 1401361320
+ ],
+ [
+ 0.0444444444444,
+ 1401361335
+ ],
+ [
+ 0.0,
+ 1401361350
+ ],
+ [
+ 0.0,
+ 1401361365
+ ],
+ [
+ 0.0,
+ 1401361380
+ ],
+ [
+ 0.0,
+ 1401361395
+ ],
+ [
+ 0.0,
+ 1401361410
+ ],
+ [
+ 0.0,
+ 1401361425
+ ],
+ [
+ 0.0,
+ 1401361440
+ ],
+ [
+ 0.0,
+ 1401361455
+ ],
+ [
+ 0.0,
+ 1401361470
+ ],
+ [
+ 0.0,
+ 1401361485
+ ],
+ [
+ 0.0,
+ 1401361500
+ ],
+ [
+ 0.0,
+ 1401361515
+ ],
+ [
+ 0.0,
+ 1401361530
+ ],
+ [
+ 0.0,
+ 1401361545
+ ],
+ [
+ 0.0,
+ 1401361560
+ ],
+ [
+ 0.0,
+ 1401361575
+ ],
+ [
+ 0.0,
+ 1401361590
+ ],
+ [
+ 0.0,
+ 1401361605
+ ],
+ [
+ 0.075,
+ 1401361620
+ ],
+ [
+ 0.0583333333333,
+ 1401361635
+ ],
+ [
+ 0.0,
+ 1401361650
+ ],
+ [
+ 0.0,
+ 1401361665
+ ],
+ [
+ 0.0,
+ 1401361680
+ ],
+ [
+ 0.0,
+ 1401361695
+ ],
+ [
+ 0.0,
+ 1401361710
+ ],
+ [
+ 0.0,
+ 1401361725
+ ],
+ [
+ 0.0,
+ 1401361740
+ ],
+ [
+ 0.0,
+ 1401361755
+ ],
+ [
+ 0.0,
+ 1401361770
+ ],
+ [
+ 0.0,
+ 1401361785
+ ],
+ [
+ 0.0,
+ 1401361800
+ ],
+ [
+ 0.0,
+ 1401361815
+ ],
+ [
+ 0.0,
+ 1401361830
+ ],
+ [
+ 0.0,
+ 1401361845
+ ],
+ [
+ 0.0,
+ 1401361860
+ ],
+ [
+ 0.0,
+ 1401361875
+ ],
+ [
+ 0.0,
+ 1401361890
+ ],
+ [
+ 0.0,
+ 1401361905
+ ],
+ [
+ 0.08,
+ 1401361920
+ ],
+ [
+ 0.0533333333333,
+ 1401361935
+ ],
+ [
+ 0.24,
+ 1401361950
+ ],
+ [
+ 0.16,
+ 1401361965
+ ],
+ [
+ 0.0,
+ 1401361980
+ ],
+ [
+ 0.0,
+ 1401361995
+ ],
+ [
+ 0.0,
+ 1401362010
+ ],
+ [
+ 0.0,
+ 1401362025
+ ],
+ [
+ 0.0,
+ 1401362040
+ ],
+ [
+ 0.0,
+ 1401362055
+ ],
+ [
+ 0.0,
+ 1401362070
+ ],
+ [
+ 0.0,
+ 1401362085
+ ],
+ [
+ 0.0,
+ 1401362100
+ ],
+ [
+ 0.0,
+ 1401362115
+ ],
+ [
+ 0.0,
+ 1401362130
+ ],
+ [
+ 0.0,
+ 1401362145
+ ],
+ [
+ 0.0,
+ 1401362160
+ ],
+ [
+ 0.0,
+ 1401362175
+ ],
+ [
+ 0.0,
+ 1401362190
+ ],
+ [
+ 0.0,
+ 1401362205
+ ],
+ [
+ 0.106666666667,
+ 1401362220
+ ],
+ [
+ 0.0266666666667,
+ 1401362235
+ ],
+ [
+ 0.0,
+ 1401362250
+ ],
+ [
+ 0.0,
+ 1401362265
+ ],
+ [
+ 0.0,
+ 1401362280
+ ],
+ [
+ 0.0,
+ 1401362295
+ ],
+ [
+ 0.0,
+ 1401362310
+ ],
+ [
+ 0.0,
+ 1401362325
+ ],
+ [
+ 0.0,
+ 1401362340
+ ],
+ [
+ 0.0,
+ 1401362355
+ ],
+ [
+ 0.0,
+ 1401362370
+ ],
+ [
+ 0.0,
+ 1401362385
+ ],
+ [
+ 0.0,
+ 1401362400
+ ],
+ [
+ 0.0,
+ 1401362415
+ ],
+ [
+ 0.0,
+ 1401362430
+ ],
+ [
+ 0.0,
+ 1401362445
+ ],
+ [
+ 0.0,
+ 1401362460
+ ],
+ [
+ 0.0,
+ 1401362475
+ ],
+ [
+ 0.0,
+ 1401362490
+ ],
+ [
+ 0.0,
+ 1401362505
+ ],
+ [
+ 0.0,
+ 1401362520
+ ],
+ [
+ 0.115555555556,
+ 1401362535
+ ],
+ [
+ 0.0177777777778,
+ 1401362550
+ ],
+ [
+ 0.0,
+ 1401362565
+ ],
+ [
+ 0.106666666667,
+ 1401362580
+ ],
+ [
+ 0.0266666666667,
+ 1401362595
+ ],
+ [
+ 0.0,
+ 1401362610
+ ],
+ [
+ 0.0,
+ 1401362625
+ ],
+ [
+ 0.0,
+ 1401362640
+ ],
+ [
+ 0.0,
+ 1401362655
+ ],
+ [
+ 0.0,
+ 1401362670
+ ],
+ [
+ 0.0,
+ 1401362685
+ ],
+ [
+ 0.0,
+ 1401362700
+ ],
+ [
+ 0.0,
+ 1401362715
+ ],
+ [
+ 0.0,
+ 1401362730
+ ],
+ [
+ 0.0,
+ 1401362745
+ ],
+ [
+ 0.0,
+ 1401362760
+ ],
+ [
+ 0.0,
+ 1401362775
+ ],
+ [
+ 0.0,
+ 1401362790
+ ],
+ [
+ 0.0,
+ 1401362805
+ ],
+ [
+ 0.0888888888889,
+ 1401362820
+ ],
+ [
+ 0.0444444444444,
+ 1401362835
+ ],
+ [
+ 0.0,
+ 1401362850
+ ],
+ [
+ 0.0,
+ 1401362865
+ ],
+ [
+ 0.0,
+ 1401362880
+ ]
+ ]
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/ambari-web/contrib/views/slider/src/main/resources/ui/app/assets/data/metrics/metric4.json
----------------------------------------------------------------------
diff --git a/ambari-web/contrib/views/slider/src/main/resources/ui/app/assets/data/metrics/metric4.json b/ambari-web/contrib/views/slider/src/main/resources/ui/app/assets/data/metrics/metric4.json
new file mode 100644
index 0000000..ec74f7d
--- /dev/null
+++ b/ambari-web/contrib/views/slider/src/main/resources/ui/app/assets/data/metrics/metric4.json
@@ -0,0 +1,968 @@
+{
+ "metrics" : {
+ "rpc" : {
+ "RpcQueueTime_avg_time" : [
+ [
+ 0.0,
+ 1401359595
+ ],
+ [
+ 0.0666666666667,
+ 1401359610
+ ],
+ [
+ 0.933333333333,
+ 1401359625
+ ],
+ [
+ 0.0333333333333,
+ 1401359640
+ ],
+ [
+ 0.466666666667,
+ 1401359655
+ ],
+ [
+ 0.0,
+ 1401359670
+ ],
+ [
+ 0.0666666666667,
+ 1401359685
+ ],
+ [
+ 0.933333333333,
+ 1401359700
+ ],
+ [
+ 0.477777777778,
+ 1401359715
+ ],
+ [
+ 0.466666666667,
+ 1401359730
+ ],
+ [
+ 0.933333333333,
+ 1401359745
+ ],
+ [
+ 0.477777777778,
+ 1401359760
+ ],
+ [
+ 0.311111111111,
+ 1401359775
+ ],
+ [
+ 0.0,
+ 1401359790
+ ],
+ [
+ 0.0,
+ 1401359805
+ ],
+ [
+ 0.0,
+ 1401359820
+ ],
+ [
+ 0.0333333333333,
+ 1401359835
+ ],
+ [
+ 0.216666666667,
+ 1401359850
+ ],
+ [
+ 0.0,
+ 1401359865
+ ],
+ [
+ 0.0266666666667,
+ 1401359880
+ ],
+ [
+ 0.36,
+ 1401359895
+ ],
+ [
+ 0.8,
+ 1401359910
+ ],
+ [
+ 0.0,
+ 1401359925
+ ],
+ [
+ 0.0666666666667,
+ 1401359940
+ ],
+ [
+ 0.5,
+ 1401359955
+ ],
+ [
+ 0.5,
+ 1401359970
+ ],
+ [
+ 0.0,
+ 1401359985
+ ],
+ [
+ 0.0,
+ 1401360000
+ ],
+ [
+ 0.5,
+ 1401360015
+ ],
+ [
+ 0.0,
+ 1401360030
+ ],
+ [
+ 0.0,
+ 1401360045
+ ],
+ [
+ 0.0,
+ 1401360060
+ ],
+ [
+ 0.0,
+ 1401360075
+ ],
+ [
+ 0.0,
+ 1401360090
+ ],
+ [
+ 0.0,
+ 1401360105
+ ],
+ [
+ 0.0,
+ 1401360120
+ ],
+ [
+ 0.333333333333,
+ 1401360135
+ ],
+ [
+ 0.5,
+ 1401360150
+ ],
+ [
+ 0.0333333333333,
+ 1401360165
+ ],
+ [
+ 0.0,
+ 1401360180
+ ],
+ [
+ 0.933333333333,
+ 1401360195
+ ],
+ [
+ 0.422222222222,
+ 1401360210
+ ],
+ [
+ 0.0444444444444,
+ 1401360225
+ ],
+ [
+ 0.0,
+ 1401360240
+ ],
+ [
+ 0.0,
+ 1401360255
+ ],
+ [
+ 0.433333333333,
+ 1401360270
+ ],
+ [
+ 0.5,
+ 1401360285
+ ],
+ [
+ 0.0333333333333,
+ 1401360300
+ ],
+ [
+ 0.0,
+ 1401360315
+ ],
+ [
+ 0.0,
+ 1401360330
+ ],
+ [
+ 0.8,
+ 1401360345
+ ],
+ [
+ 0.2,
+ 1401360360
+ ],
+ [
+ 0.0,
+ 1401360375
+ ],
+ [
+ 0.866666666667,
+ 1401360390
+ ],
+ [
+ 0.133333333333,
+ 1401360405
+ ],
+ [
+ 0.0,
+ 1401360420
+ ],
+ [
+ 0.0,
+ 1401360435
+ ],
+ [
+ 0.0,
+ 1401360450
+ ],
+ [
+ 0.0,
+ 1401360465
+ ],
+ [
+ 0.0,
+ 1401360480
+ ],
+ [
+ 0.4,
+ 1401360495
+ ],
+ [
+ 0.9,
+ 1401360510
+ ],
+ [
+ 1.0,
+ 1401360525
+ ],
+ [
+ 0.266666666667,
+ 1401360540
+ ],
+ [
+ 0.0,
+ 1401360555
+ ],
+ [
+ 0.0,
+ 1401360570
+ ],
+ [
+ 0.0,
+ 1401360585
+ ],
+ [
+ 0.0,
+ 1401360600
+ ],
+ [
+ 0.4,
+ 1401360615
+ ],
+ [
+ 0.9,
+ 1401360630
+ ],
+ [
+ 0.2,
+ 1401360645
+ ],
+ [
+ 0.0,
+ 1401360660
+ ],
+ [
+ 0.0,
+ 1401360675
+ ],
+ [
+ 0.0,
+ 1401360690
+ ],
+ [
+ 0.8,
+ 1401360705
+ ],
+ [
+ 0.566666666667,
+ 1401360720
+ ],
+ [
+ 0.0666666666667,
+ 1401360735
+ ],
+ [
+ 0.0,
+ 1401360750
+ ],
+ [
+ 0.0,
+ 1401360765
+ ],
+ [
+ 0.0,
+ 1401360780
+ ],
+ [
+ 0.0,
+ 1401360795
+ ],
+ [
+ 0.0,
+ 1401360810
+ ],
+ [
+ 0.0,
+ 1401360825
+ ],
+ [
+ 0.0,
+ 1401360840
+ ],
+ [
+ 0.0,
+ 1401360855
+ ],
+ [
+ 0.0,
+ 1401360870
+ ],
+ [
+ 0.733333333333,
+ 1401360885
+ ],
+ [
+ 0.4,
+ 1401360900
+ ],
+ [
+ 0.8,
+ 1401360915
+ ],
+ [
+ 0.266666666667,
+ 1401360930
+ ],
+ [
+ 0.4,
+ 1401360945
+ ],
+ [
+ 0.9,
+ 1401360960
+ ],
+ [
+ 0.2,
+ 1401360975
+ ],
+ [
+ 0.4,
+ 1401360990
+ ],
+ [
+ 0.1,
+ 1401361005
+ ],
+ [
+ 0.0,
+ 1401361020
+ ],
+ [
+ 0.0,
+ 1401361035
+ ],
+ [
+ 0.0,
+ 1401361050
+ ],
+ [
+ 0.0,
+ 1401361065
+ ],
+ [
+ 0.0,
+ 1401361080
+ ],
+ [
+ 0.0,
+ 1401361095
+ ],
+ [
+ 0.0,
+ 1401361110
+ ],
+ [
+ 0.0,
+ 1401361125
+ ],
+ [
+ 0.0,
+ 1401361140
+ ],
+ [
+ 0.0,
+ 1401361155
+ ],
+ [
+ 0.0,
+ 1401361170
+ ],
+ [
+ 0.733333333333,
+ 1401361185
+ ],
+ [
+ 0.333333333333,
+ 1401361200
+ ],
+ [
+ 0.0,
+ 1401361215
+ ],
+ [
+ 0.333333333333,
+ 1401361230
+ ],
+ [
+ 0.866666666667,
+ 1401361245
+ ],
+ [
+ 0.266666666667,
+ 1401361260
+ ],
+ [
+ 0.0,
+ 1401361275
+ ],
+ [
+ 0.733333333333,
+ 1401361290
+ ],
+ [
+ 0.633333333333,
+ 1401361305
+ ],
+ [
+ 0.833333333333,
+ 1401361320
+ ],
+ [
+ 0.333333333333,
+ 1401361335
+ ],
+ [
+ 0.0,
+ 1401361350
+ ],
+ [
+ 0.0,
+ 1401361365
+ ],
+ [
+ 0.183333333333,
+ 1401361380
+ ],
+ [
+ 0.75,
+ 1401361395
+ ],
+ [
+ 0.266666666667,
+ 1401361410
+ ],
+ [
+ 0.666666666667,
+ 1401361425
+ ],
+ [
+ 0.333333333333,
+ 1401361440
+ ],
+ [
+ 0.0,
+ 1401361455
+ ],
+ [
+ 0.6,
+ 1401361470
+ ],
+ [
+ 0.466666666667,
+ 1401361485
+ ],
+ [
+ 0.6,
+ 1401361500
+ ],
+ [
+ 0.4,
+ 1401361515
+ ],
+ [
+ 0.0,
+ 1401361530
+ ],
+ [
+ 0.0,
+ 1401361545
+ ],
+ [
+ 0.0,
+ 1401361560
+ ],
+ [
+ 0.0,
+ 1401361575
+ ],
+ [
+ 0.0,
+ 1401361590
+ ],
+ [
+ 0.0,
+ 1401361605
+ ],
+ [
+ 0.0,
+ 1401361620
+ ],
+ [
+ 0.533333333333,
+ 1401361635
+ ],
+ [
+ 0.4,
+ 1401361650
+ ],
+ [
+ 0.0,
+ 1401361665
+ ],
+ [
+ 0.0,
+ 1401361680
+ ],
+ [
+ 0.0,
+ 1401361695
+ ],
+ [
+ 0.0,
+ 1401361710
+ ],
+ [
+ 0.0,
+ 1401361725
+ ],
+ [
+ 0.0,
+ 1401361740
+ ],
+ [
+ 0.0,
+ 1401361755
+ ],
+ [
+ 0.0,
+ 1401361770
+ ],
+ [
+ 0.0,
+ 1401361785
+ ],
+ [
+ 0.0,
+ 1401361800
+ ],
+ [
+ 0.0,
+ 1401361815
+ ],
+ [
+ 0.666666666667,
+ 1401361830
+ ],
+ [
+ 0.333333333333,
+ 1401361845
+ ],
+ [
+ 0.0,
+ 1401361860
+ ],
+ [
+ 0.0,
+ 1401361875
+ ],
+ [
+ 0.333333333333,
+ 1401361890
+ ],
+ [
+ 0.2,
+ 1401361905
+ ],
+ [
+ 0.6,
+ 1401361920
+ ],
+ [
+ 0.4,
+ 1401361935
+ ],
+ [
+ 0.0,
+ 1401361950
+ ],
+ [
+ 0.0,
+ 1401361965
+ ],
+ [
+ 0.6,
+ 1401361980
+ ],
+ [
+ 0.4,
+ 1401361995
+ ],
+ [
+ 0.0,
+ 1401362010
+ ],
+ [
+ 0.0,
+ 1401362025
+ ],
+ [
+ 0.0,
+ 1401362040
+ ],
+ [
+ 0.0,
+ 1401362055
+ ],
+ [
+ 0.0,
+ 1401362070
+ ],
+ [
+ 0.0,
+ 1401362085
+ ],
+ [
+ 0.666666666667,
+ 1401362100
+ ],
+ [
+ 0.333333333333,
+ 1401362115
+ ],
+ [
+ 0.0,
+ 1401362130
+ ],
+ [
+ 0.0,
+ 1401362145
+ ],
+ [
+ 0.183333333333,
+ 1401362160
+ ],
+ [
+ 0.0833333333333,
+ 1401362175
+ ],
+ [
+ 0.0,
+ 1401362190
+ ],
+ [
+ 0.0,
+ 1401362205
+ ],
+ [
+ 0.8,
+ 1401362220
+ ],
+ [
+ 0.2,
+ 1401362235
+ ],
+ [
+ 0.0,
+ 1401362250
+ ],
+ [
+ 0.0,
+ 1401362265
+ ],
+ [
+ 0.0,
+ 1401362280
+ ],
+ [
+ 0.0,
+ 1401362295
+ ],
+ [
+ 0.0,
+ 1401362310
+ ],
+ [
+ 0.0,
+ 1401362325
+ ],
+ [
+ 0.0,
+ 1401362340
+ ],
+ [
+ 0.0,
+ 1401362355
+ ],
+ [
+ 0.8,
+ 1401362370
+ ],
+ [
+ 0.2,
+ 1401362385
+ ],
+ [
+ 0.0,
+ 1401362400
+ ],
+ [
+ 0.0,
+ 1401362415
+ ],
+ [
+ 0.366666666667,
+ 1401362430
+ ],
+ [
+ 0.1,
+ 1401362445
+ ],
+ [
+ 0.0,
+ 1401362460
+ ],
+ [
+ 0.0,
+ 1401362475
+ ],
+ [
+ 0.0,
+ 1401362490
+ ],
+ [
+ 0.0,
+ 1401362505
+ ],
+ [
+ 0.288888888889,
+ 1401362520
+ ],
+ [
+ 0.0444444444444,
+ 1401362535
+ ],
+ [
+ 0.0,
+ 1401362550
+ ],
+ [
+ 0.8,
+ 1401362565
+ ],
+ [
+ 0.2,
+ 1401362580
+ ],
+ [
+ 0.0,
+ 1401362595
+ ],
+ [
+ 0.366666666667,
+ 1401362610
+ ],
+ [
+ 0.133333333333,
+ 1401362625
+ ],
+ [
+ 0.0,
+ 1401362640
+ ],
+ [
+ 0.0,
+ 1401362655
+ ],
+ [
+ 0.0,
+ 1401362670
+ ],
+ [
+ 0.0,
+ 1401362685
+ ],
+ [
+ 0.0,
+ 1401362700
+ ],
+ [
+ 0.0,
+ 1401362715
+ ],
+ [
+ 0.0,
+ 1401362730
+ ],
+ [
+ 0.0,
+ 1401362745
+ ],
+ [
+ 0.6,
+ 1401362760
+ ],
+ [
+ 0.333333333333,
+ 1401362775
+ ],
+ [
+ 0.3,
+ 1401362790
+ ],
+ [
+ 0.166666666667,
+ 1401362805
+ ],
+ [
+ 0.0,
+ 1401362820
+ ],
+ [
+ 0.0,
+ 1401362835
+ ],
+ [
+ 0.0,
+ 1401362850
+ ],
+ [
+ 0.0,
+ 1401362865
+ ],
+ [
+ 0.0,
+ 1401362880
+ ],
+ [
+ 0.0,
+ 1401362895
+ ],
+ [
+ 0.0,
+ 1401362910
+ ],
+ [
+ 0.0,
+ 1401362925
+ ],
+ [
+ 0.0,
+ 1401362940
+ ],
+ [
+ 0.0,
+ 1401362955
+ ],
+ [
+ 0.0,
+ 1401362970
+ ],
+ [
+ 0.0,
+ 1401362985
+ ],
+ [
+ 0.666666666667,
+ 1401363000
+ ],
+ [
+ 0.266666666667,
+ 1401363015
+ ],
+ [
+ 0.0,
+ 1401363030
+ ],
+ [
+ 0.0,
+ 1401363045
+ ],
+ [
+ 0.166666666667,
+ 1401363060
+ ],
+ [
+ 0.0833333333333,
+ 1401363075
+ ],
+ [
+ 0.0,
+ 1401363090
+ ],
+ [
+ 0.0,
+ 1401363105
+ ],
+ [
+ 0.0,
+ 1401363120
+ ],
+ [
+ 0.0,
+ 1401363135
+ ],
+ [
+ 0.166666666667,
+ 1401363150
+ ],
+ [
+ 0.0833333333333,
+ 1401363165
+ ],
+ [
+ 0.222222222222,
+ 1401363180
+ ]
+ ]
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/ambari-web/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app/summary_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app/summary_controller.js b/ambari-web/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app/summary_controller.js
new file mode 100644
index 0000000..7e8d6e6
--- /dev/null
+++ b/ambari-web/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app/summary_controller.js
@@ -0,0 +1,23 @@
+/**
+ * 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.
+ */
+
+App.SliderAppSummaryController = Ember.Controller.extend({
+
+
+
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/ambari-web/contrib/views/slider/src/main/resources/ui/app/helpers/string_utils.js
----------------------------------------------------------------------
diff --git a/ambari-web/contrib/views/slider/src/main/resources/ui/app/helpers/string_utils.js b/ambari-web/contrib/views/slider/src/main/resources/ui/app/helpers/string_utils.js
new file mode 100644
index 0000000..9675f49
--- /dev/null
+++ b/ambari-web/contrib/views/slider/src/main/resources/ui/app/helpers/string_utils.js
@@ -0,0 +1,163 @@
+/**
+ * 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.
+ */
+
+module.exports = {
+
+ pad: function(str, len, pad, dir) {
+
+ var STR_PAD_LEFT = 1;
+ var STR_PAD_RIGHT = 2;
+ var STR_PAD_BOTH = 3;
+
+ if (typeof(len) == "undefined") { len = 0; }
+ if (typeof(pad) == "undefined") { pad = ' '; }
+ if (typeof(dir) == "undefined") { dir = STR_PAD_RIGHT; }
+
+ if (len + 1 >= str.length) {
+
+ switch (dir){
+
+ case STR_PAD_LEFT:
+ str = Array(len + 1 - str.length).join(pad) + str;
+ break;
+
+ case STR_PAD_BOTH:
+ var padlen = len - str.length;
+ var right = Math.ceil((padlen) / 2);
+ var left = padlen - right;
+ str = Array(left+1).join(pad) + str + Array(right+1).join(pad);
+ break;
+
+ default:
+ str = str + Array(len + 1 - str.length).join(pad);
+ break;
+
+ } // switch
+
+ }
+ return str;
+
+ },
+ underScoreToCamelCase: function(name){
+ function replacer(str, p1, p2, offset, s) {
+ return str[1].toUpperCase();
+ }
+ return name.replace(/_\w/g,replacer);
+ },
+
+ /**
+ * Forces given string into upper camel-case representation. The first
+ * character of each word will be capitalized with the rest in lower case.
+ */
+ getCamelCase : function(name) {
+ if (name != null) {
+ return name.toLowerCase().replace(/(\b\w)/g, function(f) {
+ return f.toUpperCase();
+ })
+ }
+ return name;
+ },
+
+ /**
+ * Compare two versions by following rules:
+ * first higher than second then return 1
+ * first lower than second then return -1
+ * first equal to second then return 0
+ * @param first {string}
+ * @param second {string}
+ * @return {number}
+ */
+ compareVersions: function(first, second){
+ if (!(typeof first === 'string' && typeof second === 'string')) {
+ return false;
+ }
+ if (first === '' || second === '') {
+ return false;
+ }
+ var firstNumbers = first.split('.');
+ var secondNumbers = second.split('.');
+ var length = 0;
+ var i = 0;
+ var result = false;
+ if(firstNumbers.length === secondNumbers.length) {
+ length = firstNumbers.length;
+ } else if(firstNumbers.length < secondNumbers.length){
+ length = secondNumbers.length;
+ } else {
+ length = firstNumbers.length;
+ }
+
+ while(i < length && !result){
+ firstNumbers[i] = (firstNumbers[i] === undefined) ? 0 : window.parseInt(firstNumbers[i]);
+ secondNumbers[i] = (secondNumbers[i] === undefined) ? 0 : window.parseInt(secondNumbers[i]);
+ if(firstNumbers[i] > secondNumbers[i]){
+ result = 1;
+ break;
+ } else if(firstNumbers[i] === secondNumbers[i]){
+ result = 0;
+ } else if(firstNumbers[i] < secondNumbers[i]){
+ result = -1;
+ break;
+ }
+ i++;
+ }
+ return result;
+ },
+
+ isSingleLine: function(string){
+ return String(string).trim().indexOf("\n") == -1;
+ },
+ /**
+ * transform array of objects into CSV format content
+ * @param array
+ * @return {Array}
+ */
+ arrayToCSV: function(array){
+ var content = "";
+ array.forEach(function(item){
+ var row = [];
+ for(var i in item){
+ if(item.hasOwnProperty(i)){
+ row.push(item[i]);
+ }
+ }
+ content += row.join(',') + '\n';
+ });
+ return content;
+ },
+
+ /**
+ * Extracts filename from linux/unix path
+ * @param path
+ * @return {string}: filename
+ */
+ getFileFromPath: function(path) {
+ if (!path || typeof path !== 'string') {
+ return '';
+ }
+ return path.replace(/^.*[\/]/, '');
+ },
+
+ getPath: function(path) {
+ if (!path || typeof path !== 'string' || path[0] != '/') {
+ return '';
+ }
+ var last_slash = path.lastIndexOf('/');
+ return (last_slash!=0)?path.substr(0,last_slash):'/';
+ }
+};
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/ambari-web/contrib/views/slider/src/main/resources/ui/app/templates/common/chart.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/contrib/views/slider/src/main/resources/ui/app/templates/common/chart.hbs b/ambari-web/contrib/views/slider/src/main/resources/ui/app/templates/common/chart.hbs
new file mode 100644
index 0000000..1a7e393
--- /dev/null
+++ b/ambari-web/contrib/views/slider/src/main/resources/ui/app/templates/common/chart.hbs
@@ -0,0 +1,26 @@
+{{!
+* 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.
+}}
+
+<div {{bind-attr class=":time-label"}}>{{view.parentView.currentTimeState.name}}</div>
+<div {{bind-attr id="view.containerId"}} {{bind-attr class="view.containerClass :chart-container"}}>
+ <div {{bind-attr id="view.yAxisId"}} {{bind-attr class="view.yAxisClass :chart-y-axis"}}></div>
+ <div {{bind-attr id="view.xAxisId"}} {{bind-attr class="view.xAxisClass :chart-x-axis"}}></div>
+ <div {{bind-attr id="view.legendId"}} {{bind-attr class="view.legendClass :chart-legend"}}></div>
+ <div {{bind-attr id="view.chartId"}} {{bind-attr class="view.chartClass :chart"}}></div>
+ <div {{bind-attr id="view.titleId"}} {{bind-attr class="view.titleClass :chart-title"}}>{{view.title}}</div>
+</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/common/chart_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/common/chart_view.js b/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/common/chart_view.js
new file mode 100644
index 0000000..4af203b
--- /dev/null
+++ b/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/common/chart_view.js
@@ -0,0 +1,915 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+var string_utils = require('helpers/string_utils');
+
+/**
+ * @class
+ *
+ * This is a view which GETs data from a URL and shows it as a time based line
+ * graph. Time is shown on the X axis with data series shown on Y axis. It
+ * optionally also has the ability to auto refresh itself over a given time
+ * interval.
+ *
+ * This is an abstract class which is meant to be extended.
+ *
+ * Extending classes should override the following:
+ * <ul>
+ * <li>url - from where the data can be retrieved
+ * <li>title - Title to be displayed when showing the chart
+ * <li>id - which uniquely identifies this chart in any page
+ * <li>#transformToSeries(jsonData) - function to map server data into graph
+ * series
+ * </ul>
+ *
+ * Extending classes could optionally override the following:
+ * <ul>
+ * <li>#colorForSeries(series) - function to get custom colors per series
+ * </ul>
+ *
+ * @extends Ember.Object
+ * @extends Ember.View
+ */
+App.ChartView = Ember.View.extend({
+
+ templateName: 'common/chart',
+
+ /**
+ * The URL from which data can be retrieved.
+ *
+ * This property must be provided for the graph to show properly.
+ *
+ * @type String
+ * @default null
+ */
+ url: null,
+
+ /**
+ * A unique ID for this chart.
+ *
+ * @type String
+ * @default null
+ */
+ id: null,
+
+ /**
+ * Title to be shown under the chart.
+ *
+ * @type String
+ * @default null
+ */
+ title: null,
+
+ /**
+ * @private
+ *
+ * @type Rickshaw.Graph
+ * @default null
+ */
+ _graph: null,
+
+ /**
+ * Array of classnames for each series (in widget)
+ * @type Rickshaw.Graph
+ */
+ _popupGraph: null,
+
+ /**
+ * Array of classnames for each series
+ * @type Array
+ */
+ _seriesProperties: null,
+
+ /**
+ * Array of classnames for each series (in widget)
+ * @type Array
+ */
+ _seriesPropertiesWidget: null,
+
+ /**
+ * Renderer type
+ * See <code>Rickshaw.Graph.Renderer</code> for more info
+ * @type String
+ */
+ renderer: 'area',
+
+ /**
+ * Suffix used in DOM-elements selectors
+ * @type String
+ */
+ popupSuffix: '-popup',
+
+ /**
+ * Is popup for current graph open
+ * @type Boolean
+ */
+ isPopup: false,
+
+ /**
+ * Is graph ready
+ * @type Boolean
+ */
+ isReady: false,
+
+ /**
+ * Is popup-graph ready
+ * @type Boolean
+ */
+ isPopupReady: false,
+
+ /**
+ * Is data for graph available
+ * @type Boolean
+ */
+ hasData: true,
+
+ containerId: null,
+ containerClass: null,
+ yAxisId: null,
+ yAxisClass: null,
+ xAxisId: null,
+ xAxisClass: null,
+ legendId: null,
+ legendClass: null,
+ chartId: null,
+ chartClass: null,
+ titleId: null,
+ titleClass: null,
+
+ didInsertElement: function() {
+ var id = this.get('id');
+ var idTemplate = id + '-{element}';
+
+ this.set('containerId', idTemplate.replace('{element}', 'container'));
+ this.set('containerClass', 'chart-container');
+ this.set('yAxisId', idTemplate.replace('{element}', 'yaxis'));
+ this.set('yAxisClass', this.get('yAxisId'));
+ this.set('xAxisId', idTemplate.replace('{element}', 'xaxis'));
+ this.set('xAxisClass', this.get('xAxisId'));
+ this.set('legendId', idTemplate.replace('{element}', 'legend'));
+ this.set('legendClass', this.get('legendId'));
+ this.set('chartId', idTemplate.replace('{element}', 'chart'));
+ this.set('chartClass', this.get('chartId'));
+ this.set('titleId', idTemplate.replace('{element}', 'title'));
+ this.set('titleClass', this.get('titleId'));
+ this.loadData();
+ },
+
+
+ loadData: function() {
+ App.ajax.send({
+ name: this.get('ajaxIndex'),
+ sender: this,
+ data: this.getDataForAjaxRequest(),
+ success: '_refreshGraph',
+ error: 'loadDataErrorCallback'
+ });
+ },
+
+ getDataForAjaxRequest: function() {
+ return {};
+ },
+
+ loadDataErrorCallback: function(xhr, textStatus, errorThrown) {
+ this.set('isReady', true);
+ if (xhr.readyState == 4 && xhr.status) {
+ textStatus = xhr.status + " " + textStatus;
+ }
+ this._showMessage('warn', 'graphs.error.title', textStatus + ' ' + errorThrown);
+ this.set('isPopup', false);
+ this.set('hasData', false);
+ },
+
+ /**
+ * Shows a yellow warning message in place of the chart.
+ *
+ * @param type Can be any of 'warn', 'error', 'info', 'success'
+ * @param title Bolded title for the message
+ * @param message String representing the message
+ * @type: Function
+ */
+ _showMessage: function(type, title, message) {
+ var chartOverlay = '#' + this.id;
+ var chartOverlayId = chartOverlay + '-chart';
+ var chartOverlayY = chartOverlay + '-yaxis';
+ var chartOverlayX = chartOverlay + '-xaxis';
+ var chartOverlayLegend = chartOverlay + '-legend';
+ var chartOverlayTimeline = chartOverlay + '-timeline';
+ if (this.get('isPopup')) {
+ chartOverlayId += this.get('popupSuffix');
+ chartOverlayY += this.get('popupSuffix');
+ chartOverlayX += this.get('popupSuffix');
+ chartOverlayLegend += this.get('popupSuffix');
+ chartOverlayTimeline += this.get('popupSuffix');
+ }
+ var typeClass;
+ switch (type) {
+ case 'error':
+ typeClass = 'alert-error';
+ break;
+ case 'success':
+ typeClass = 'alert-success';
+ break;
+ case 'info':
+ typeClass = 'alert-info';
+ break;
+ default:
+ typeClass = '';
+ break;
+ }
+ $(chartOverlayId+', '+chartOverlayY+', '+chartOverlayX+', '+chartOverlayLegend+', '+chartOverlayTimeline).html('');
+ $(chartOverlayId).append('<div class=\"alert '+typeClass+'\"><strong>'+title+'</strong> '+message+'</div>');
+ },
+
+ /**
+ * Transforms the JSON data retrieved from the server into the series
+ * format that Rickshaw.Graph understands.
+ *
+ * The series object is generally in the following format: [ { name :
+ * "Series 1", data : [ { x : 0, y : 0 }, { x : 1, y : 1 } ] } ]
+ *
+ * Extending classes should override this method.
+ *
+ * @param seriesData
+ * Data retrieved from the server
+ * @param displayName
+ * Graph title
+ * @type: Function
+ *
+ */
+ transformData: function (seriesData, displayName) {
+ var seriesArray = [];
+ if (seriesData != null) {
+ // Is it a string?
+ if ("string" == typeof seriesData) {
+ seriesData = JSON.parse(seriesData);
+ }
+ // Is it a number?
+ if ("number" == typeof seriesData) {
+ // Same number applies to all time.
+ var number = seriesData;
+ seriesData = [];
+ seriesData.push([number, (new Date().getTime())-(60*60)]);
+ seriesData.push([number, (new Date().getTime())]);
+ }
+ // We have valid data
+ var series = {};
+ series.name = displayName;
+ series.data = [];
+ for ( var index = 0; index < seriesData.length; index++) {
+ series.data.push({
+ x: seriesData[index][1],
+ y: seriesData[index][0]
+ });
+ }
+ return series;
+ }
+ return null;
+ },
+
+ /**
+ * Provides the formatter to use in displaying Y axis.
+ *
+ * Uses the App.ChartLinearTimeView.DefaultFormatter which shows 10K,
+ * 300M etc.
+ *
+ * @type Function
+ */
+ yAxisFormatter: function(y) {
+ return App.ChartView.DefaultFormatter(y);
+ },
+
+ /**
+ * Provides the color (in any HTML color format) to use for a particular
+ * series.
+ * May be redefined in child views
+ *
+ * @param series
+ * Series for which color is being requested
+ * @return color String. Returning null allows this chart to pick a color
+ * from palette.
+ * @default null
+ * @type Function
+ */
+ colorForSeries: function (series) {
+ return null;
+ },
+
+ /**
+ * Check whether seriesData is correct data for chart drawing
+ * @param {Array} seriesData
+ * @return {Boolean}
+ */
+ checkSeries : function(seriesData) {
+ if(!seriesData || !seriesData.length) {
+ return false;
+ }
+ var result = true;
+ seriesData.forEach(function(item) {
+ if(!item.data || !item.data.length || !item.data[0] || typeof item.data[0].x === 'undefined') {
+ result = false;
+ }
+ });
+ return result;
+ },
+
+ /**
+ * @private
+ *
+ * Refreshes the graph with the latest JSON data.
+ *
+ * @type Function
+ */
+ _refreshGraph: function (jsonData) {
+ if(this.get('isDestroyed')){
+ return;
+ }
+ var seriesData = this.transformToSeries(jsonData);
+
+ //if graph opened as modal popup
+ var popup_path = $("#" + this.get('id') + "-container" + this.get('popupSuffix'));
+ var graph_container = $("#" + this.get('id') + "-container");
+ if(popup_path.length) {
+ popup_path.children().each(function () {
+ $(this).children().remove();
+ });
+ this.set('isPopup', true);
+ }
+ else {
+ graph_container.children().each(function (index, value) {
+ $(value).children().remove();
+ });
+ }
+ if (this.checkSeries(seriesData)) {
+ // Check container exists (may be not, if we go to another page and wait while graphs loading)
+ if (graph_container.length) {
+ this.draw(seriesData);
+ this.set('hasData', true);
+ //move yAxis value lower to make them fully visible
+ $("#" + this.id + "-container").find('.y_axis text').attr('y',8);
+ }
+ }
+ else {
+ this.set('isReady', true);
+ //if Axis X time interval is default(60 minutes)
+ if(this.get('timeUnitSeconds') === 3600){
+ this._showMessage('info', this.t('graphs.noData.title'), this.t('graphs.noData.message'));
+ this.set('hasData', false);
+ }
+ else {
+ this._showMessage('info', this.t('graphs.noData.title'), this.t('graphs.noDataAtTime.message'));
+ }
+ this.set('isPopup', false);
+ }
+ },
+
+ /**
+ * Returns a custom time unit, that depends on X axis interval length, for the graph's X axis.
+ * This is needed as Rickshaw's default time X axis uses UTC time, which can be confusing
+ * for users expecting locale specific time.
+ *
+ * If <code>null</code> is returned, Rickshaw's default time unit is used.
+ *
+ * @type Function
+ * @return Rickshaw.Fixtures.Time
+ */
+ localeTimeUnit: function(timeUnitSeconds) {
+ var timeUnit = new Rickshaw.Fixtures.Time();
+ switch (timeUnitSeconds){
+ case 604800:
+ timeUnit = timeUnit.unit('day');
+ break;
+ case 2592000:
+ timeUnit = timeUnit.unit('week');
+ break;
+ case 31104000:
+ timeUnit = timeUnit.unit('month');
+ break;
+ default:
+ timeUnit = {
+ name: timeUnitSeconds / 240 + ' minute',
+ seconds: timeUnitSeconds / 4,
+ formatter: function (d) {
+ return d.toLocaleString().match(/(\d+:\d+):/)[1];
+ }
+ };
+ }
+ return timeUnit;
+ },
+
+ /**
+ * temporary fix for incoming data for graph
+ * to shift data time to correct time point
+ * @param {Array} data
+ */
+ dataShiftFix: function(data) {
+ var nowTime = Math.round((new Date().getTime()) / 1000);
+ data.forEach(function(series){
+ var l = series.data.length;
+ var shiftDiff = nowTime - series.data[l - 1].x;
+ if(shiftDiff > 3600){
+ for(var i = 0;i < l;i++){
+ series.data[i].x = series.data[i].x + shiftDiff;
+ }
+ series.data.unshift({
+ x: nowTime - this.get('timeUnitSeconds'),
+ y: 0
+ });
+ }
+ }, this);
+ },
+
+ /**
+ * calculate statistic data for popup legend and set proper colors for series
+ * @param {Array} data
+ */
+ dataPreProcess: function(data) {
+ var self = this;
+ var palette = new Rickshaw.Color.Palette({ scheme: 'munin'});
+ // Format series for display
+ var series_min_length = 100000000;
+ data.forEach(function (series, index) {
+ var seriesColor = self.colorForSeries(series);
+ if (seriesColor == null) {
+ seriesColor = palette.color();
+ }
+ series.color = seriesColor;
+ series.stroke = 'rgba(0,0,0,0.3)';
+ if (this.get('isPopup')) {
+ // calculate statistic data for popup legend
+ var avg = 0;
+ var min = Number.MAX_VALUE;
+ var max = Number.MIN_VALUE;
+ for (var i = 0; i < series.data.length; i++) {
+ avg += series.data[i]['y'];
+ if (series.data[i]['y'] < min) {
+ min = series.data[i]['y'];
+ }
+ else {
+ if (series.data[i]['y'] > max) {
+ max = series.data[i]['y'];
+ }
+ }
+ }
+ series.name = string_utils.pad(series.name, 30, ' ', 2) +
+ string_utils.pad('min', 5, ' ', 3) +
+ string_utils.pad(this.get('yAxisFormatter')(min), 12, ' ', 3) +
+ string_utils.pad('avg', 5, ' ', 3) +
+ string_utils.pad(this.get('yAxisFormatter')(avg/series.data.length), 12, ' ', 3) +
+ string_utils.pad('max', 12, ' ', 3) +
+ string_utils.pad(this.get('yAxisFormatter')(max), 5, ' ', 3);
+ }
+ if (series.data.length < series_min_length) {
+ series_min_length = series.data.length;
+ }
+ }.bind(this));
+
+ // All series should have equal length
+ data.forEach(function(series, index) {
+ if (series.data.length > series_min_length) {
+ series.data.length = series_min_length;
+ }
+ });
+ },
+
+ draw: function(seriesData) {
+ var self = this;
+ var isPopup = this.get('isPopup');
+ var p = isPopup ? this.get('popupSuffix') : '';
+
+ this.dataShiftFix(seriesData);
+ this.dataPreProcess(seriesData);
+
+ var chartId = "#" + this.get('id') + "-chart" + p;
+ var chartOverlayId = "#" + this.get('id') + "-container" + p;
+ var xaxisElementId = "#" + this.get('id') + "-xaxis" + p;
+ var yaxisElementId = "#" + this.get('id') + "-yaxis" + p;
+ var legendElementId = "#" + this.get('id') + "-legend" + p;
+
+ var chartElement = document.querySelector(chartId);
+ var overlayElement = document.querySelector(chartOverlayId);
+ var xaxisElement = document.querySelector(xaxisElementId);
+ var yaxisElement = document.querySelector(yaxisElementId);
+ var legendElement = document.querySelector(legendElementId);
+
+ var height = 150;
+ var width = 400;
+ var diff = 32;
+
+ if(this.get('inWidget')) {
+ height = 105; // for widgets view
+ diff = 22;
+ }
+ if (isPopup) {
+ height = 180;
+ width = 670;
+ }
+ else {
+ // If not in popup, the width could vary.
+ // We determine width based on div's size.
+ var thisElement = this.get('element');
+ if (thisElement!=null) {
+ var calculatedWidth = $(thisElement).width();
+ if (calculatedWidth > diff) {
+ width = calculatedWidth - diff;
+ }
+ }
+ }
+
+ var _graph = new Rickshaw.Graph({
+ height: height,
+ width: width,
+ element: chartElement,
+ series: seriesData,
+ interpolation: 'step-after',
+ stroke: true,
+ renderer: this.get('renderer'),
+ strokeWidth: (this.get('renderer') != 'area' ? 2 : 1)
+ });
+
+ if (this.get('renderer') === 'area') {
+ _graph.renderer.unstack = false;
+ }
+
+ new Rickshaw.Graph.Axis.Time({
+ graph: _graph,
+ timeUnit: this.localeTimeUnit(this.get('timeUnitSeconds'))
+ });
+
+ new Rickshaw.Graph.Axis.Y({
+ tickFormat: this.yAxisFormatter,
+ element: yaxisElement,
+ orientation: (isPopup ? 'left' : 'right'),
+ graph: _graph
+ });
+
+ var legend = new Rickshaw.Graph.Legend({
+ graph: _graph,
+ element: legendElement
+ });
+
+ new Rickshaw.Graph.Behavior.Series.Toggle({
+ graph: _graph,
+ legend: legend
+ });
+
+ new Rickshaw.Graph.Behavior.Series.Order({
+ graph: _graph,
+ legend: legend
+ });
+
+ if (!isPopup) {
+ overlayElement.addEventListener('mousemove', function () {
+ $(xaxisElement).removeClass('hide');
+ $(legendElement).removeClass('hide');
+ $(chartElement).children("div").removeClass('hide');
+ });
+ overlayElement.addEventListener('mouseout', function () {
+ $(legendElement).addClass('hide');
+ });
+ _graph.onUpdate(function () {
+ $(legendElement).addClass('hide');
+ });
+ }
+
+ //show the graph when it's loaded
+ _graph.onUpdate(function() {
+ self.set('isReady', true);
+ });
+ _graph.render();
+
+ if (isPopup) {
+ new Rickshaw.Graph.HoverDetail({
+ graph: _graph,
+ yFormatter:function (y) {
+ return self.yAxisFormatter(y);
+ },
+ xFormatter:function (x) {
+ return (new Date(x * 1000)).toLocaleTimeString();
+ },
+ formatter:function (series, x, y, formattedX, formattedY, d) {
+ return formattedY + '<br />' + formattedX;
+ }
+ });
+ }
+
+ _graph = this.updateSeriesInGraph(_graph);
+ if (isPopup) {
+ //show the graph when it's loaded
+ _graph.onUpdate(function() {
+ self.set('isPopupReady', true);
+ });
+ _graph.update();
+
+ var selector = '#'+this.get('id')+'-container'+this.get('popupSuffix');
+ $(selector + ' li.line').click(function() {
+ var series = [];
+ $(selector + ' a.action').each(function(index, v) {
+ series[index] = v.parentNode.classList;
+ });
+ self.set('_seriesProperties', series);
+ });
+
+ this.set('_popupGraph', _graph);
+ }
+ else {
+ _graph.update();
+ var selector = '#'+this.get('id')+'-container';
+ $(selector + ' li.line').click(function() {
+ var series = [];
+ $(selector + ' a.action').each(function(index, v) {
+ series[index] = v.parentNode.classList;
+ });
+ self.set('_seriesPropertiesWidget', series);
+ });
+
+ this.set('_graph', _graph);
+ }
+ },
+
+ /**
+ *
+ * @param {Rickshaw.Graph} graph
+ * @returns {Rickshaw.Graph}
+ */
+ updateSeriesInGraph: function(graph) {
+ var id = this.get('id');
+ var isPopup = this.get('isPopup');
+ var popupSuffix = this.get('popupSuffix');
+ var _series = isPopup ? this.get('_seriesProperties') : this.get('_seriesPropertiesWidget');
+ graph.series.forEach(function(series, index) {
+ if (_series !== null && _series[index] !== null && _series[index] !== undefined ) {
+ if(_series[_series.length - index - 1].length > 1) {
+ var s = '#' + id + '-container' + (isPopup ? popupSuffix : '') + ' a.action:eq(' + (_series.length - index - 1) + ')';
+ $(s).parent('li').addClass('disabled');
+ series.disable();
+ }
+ }
+ });
+ return graph;
+ },
+
+ showGraphInPopup: function() {
+ if(!this.get('hasData')) {
+ return;
+ }
+
+ this.set('isPopup', true);
+ var self = this;
+
+ App.ModalPopup.show({
+ bodyClass: Em.View.extend({
+
+ containerId: null,
+ containerClass: null,
+ yAxisId: null,
+ yAxisClass: null,
+ xAxisId: null,
+ xAxisClass: null,
+ legendId: null,
+ legendClass: null,
+ chartId: null,
+ chartClass: null,
+ titleId: null,
+ titleClass: null,
+
+ isReady: function() {
+ return this.get('parentView.graph.isPopupReady');
+ }.property('parentView.graph.isPopupReady'),
+
+ didInsertElement: function() {
+ $('#modal').addClass('modal-graph-line');
+ var popupSuffix = this.get('parentView.graph.popupSuffix');
+ var id = this.get('parentView.graph.id');
+ var idTemplate = id + '-{element}' + popupSuffix;
+
+ this.set('containerId', idTemplate.replace('{element}', 'container'));
+ this.set('containerClass', 'chart-container' + popupSuffix);
+ this.set('yAxisId', idTemplate.replace('{element}', 'yaxis'));
+ this.set('yAxisClass', this.get('yAxisId').replace(popupSuffix, ''));
+ this.set('xAxisId', idTemplate.replace('{element}', 'xaxis'));
+ this.set('xAxisClass', this.get('xAxisId').replace(popupSuffix, ''));
+ this.set('legendId', idTemplate.replace('{element}', 'legend'));
+ this.set('legendClass', this.get('legendId').replace(popupSuffix, ''));
+ this.set('chartId', idTemplate.replace('{element}', 'chart'));
+ this.set('chartClass', this.get('chartId').replace(popupSuffix, ''));
+ this.set('titleId', idTemplate.replace('{element}', 'title'));
+ this.set('titleClass', this.get('titleId').replace(popupSuffix, ''));
+ },
+
+ templateName: require('templates/common/chart/linear_time'),
+ /**
+ * check is time paging feature is enable for graph
+ */
+ isTimePagingEnable: function() {
+ return !self.get('isTimePagingDisable');
+ }.property(),
+ rightArrowVisible: function() {
+ return (this.get('isReady') && (this.get('parentView.currentTimeIndex') != 0));
+ }.property('isReady', 'parentView.currentTimeIndex'),
+ leftArrowVisible: function() {
+ return (this.get('isReady') && (this.get('parentView.currentTimeIndex') != 7));
+ }.property('isReady', 'parentView.currentTimeIndex')
+ }),
+ header: this.get('title'),
+ /**
+ * App.ChartLinearTimeView
+ */
+ graph: self,
+ secondary: null,
+ onPrimary: function() {
+ this.hide();
+ self.set('isPopup', false);
+ self.set('timeUnitSeconds', 3600);
+ },
+ onClose: function() {
+ this.onPrimary();
+ },
+ /**
+ * move graph back by time
+ * @param event
+ */
+ switchTimeBack: function(event) {
+ var index = this.get('currentTimeIndex');
+ // 7 - number of last time state
+ if(index < 7) {
+ this.reloadGraphByTime(++index);
+ }
+ },
+ /**
+ * move graph forward by time
+ * @param event
+ */
+ switchTimeForward: function(event) {
+ var index = this.get('currentTimeIndex');
+ if(index > 0) {
+ this.reloadGraphByTime(--index);
+ }
+ },
+ /**
+ * reload graph depending on the time
+ * @param index
+ */
+ reloadGraphByTime: function(index) {
+ this.set('currentTimeIndex', index);
+ self.set('timeUnitSeconds', this.get('timeStates')[index].seconds);
+ self.loadData();
+ },
+ timeStates: [
+ {name: Em.I18n.t('graphs.timeRange.hour'), seconds: 3600},
+ {name: Em.I18n.t('graphs.timeRange.twoHours'), seconds: 7200},
+ {name: Em.I18n.t('graphs.timeRange.fourHours'), seconds: 14400},
+ {name: Em.I18n.t('graphs.timeRange.twelveHours'), seconds: 43200},
+ {name: Em.I18n.t('graphs.timeRange.day'), seconds: 86400},
+ {name: Em.I18n.t('graphs.timeRange.week'), seconds: 604800},
+ {name: Em.I18n.t('graphs.timeRange.month'), seconds: 2592000},
+ {name: Em.I18n.t('graphs.timeRange.year'), seconds: 31104000}
+ ],
+ currentTimeIndex: 0,
+ currentTimeState: function() {
+ return this.get('timeStates').objectAt(this.get('currentTimeIndex'));
+ }.property('currentTimeIndex')
+ });
+ Ember.run.next(function() {
+ self.loadData();
+ self.set('isPopupReady', false);
+ });
+ },
+ //60 minute interval on X axis.
+ timeUnitSeconds: 3600
+});
+
+/**
+ * A formatter which will turn a number into computer storage sizes of the
+ * format '23 GB' etc.
+ *
+ * @type {Function}
+ */
+App.ChartView.BytesFormatter = function (y) {
+ if (y == 0) return '0 B';
+ var value = Rickshaw.Fixtures.Number.formatBase1024KMGTP(y);
+ if (!y || y.length < 1) {
+ value = '0 B';
+ }
+ else {
+ if ("number" == typeof value) {
+ value = String(value);
+ }
+ if ("string" == typeof value) {
+ value = value.replace(/\.\d(\d+)/, function($0, $1){ // Remove only 1-digit after decimal part
+ return $0.replace($1, '');
+ });
+ // Either it ends with digit or ends with character
+ value = value.replace(/(\d$)/, '$1 '); // Ends with digit like '120'
+ value = value.replace(/([a-zA-Z]$)/, ' $1'); // Ends with character like
+ // '120M'
+ value = value + 'B'; // Append B to make B, MB, GB etc.
+ }
+ }
+ return value;
+};
+
+/**
+ * A formatter which will turn a number into percentage display like '42%'
+ *
+ * @type {Function}
+ */
+App.ChartView.PercentageFormatter = function (percentage) {
+ var value = percentage;
+ if (!value || value.length < 1) {
+ value = '0 %';
+ } else {
+ value = value.toFixed(3).replace(/0+$/, '').replace(/\.$/, '') + '%';
+ }
+ return value;
+};
+
+/**
+ * A formatter which will turn elapsed time into display time like '50 ms',
+ * '5s', '10 m', '3 hr' etc. Time is expected to be provided in milliseconds.
+ *
+ * @type {Function}
+ */
+App.ChartView.TimeElapsedFormatter = function (millis) {
+ var value = millis;
+ if (!value || value.length < 1) {
+ value = '0 ms';
+ } else if ("number" == typeof millis) {
+ var seconds = millis > 1000 ? Math.round(millis / 1000) : 0;
+ var minutes = seconds > 60 ? Math.round(seconds / 60) : 0;
+ var hours = minutes > 60 ? Math.round(minutes / 60) : 0;
+ var days = hours > 24 ? Math.round(hours / 24) : 0;
+ if (days > 0) {
+ value = days + ' d';
+ } else if (hours > 0) {
+ value = hours + ' hr';
+ } else if (minutes > 0) {
+ value = minutes + ' m';
+ } else if (seconds > 0) {
+ value = seconds + ' s';
+ } else if (millis > 0) {
+ value = millis.toFixed(3).replace(/0+$/, '').replace(/\.$/, '') + ' ms';
+ } else {
+ value = millis.toFixed(3).replace(/0+$/, '').replace(/\.$/, '') + ' ms';
+ }
+ }
+ return value;
+};
+
+/**
+ * The default formatter which uses Rickshaw.Fixtures.Number.formatKMBT
+ * which shows 10K, 300M etc.
+ *
+ * @type {Function}
+ */
+App.ChartView.DefaultFormatter = function(y) {
+ if(isNaN(y)){
+ return 0;
+ }
+ var value = Rickshaw.Fixtures.Number.formatKMBT(y);
+ if (value == '') return '0';
+ value = String(value);
+ var c = value[value.length - 1];
+ if (!isNaN(parseInt(c))) {
+ // c is digit
+ value = parseFloat(value).toFixed(3).replace(/0+$/, '').replace(/\.$/, '');
+ }
+ else {
+ // c in not digit
+ value = parseFloat(value.substr(0, value.length - 1)).toFixed(3).replace(/0+$/, '').replace(/\.$/, '') + c;
+ }
+ return value;
+};
+
+
+/**
+ * Creates and returns a formatter that can convert a 'value'
+ * to 'value units/s'.
+ *
+ * @param unitsPrefix Prefix which will be used in 'unitsPrefix/s'
+ * @param valueFormatter Value itself will need further processing
+ * via provided formatter. Ex: '10M requests/s'. Generally
+ * should be App.ChartLinearTimeView.DefaultFormatter.
+ * @return {Function}
+ */
+App.ChartView.CreateRateFormatter = function (unitsPrefix, valueFormatter) {
+ var suffix = " "+unitsPrefix+"/s";
+ return function (value) {
+ value = valueFormatter(value) + suffix;
+ return value;
+ };
+};
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/slider_app/metrics/metric2_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/slider_app/metrics/metric2_view.js b/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/slider_app/metrics/metric2_view.js
new file mode 100644
index 0000000..2838888
--- /dev/null
+++ b/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/slider_app/metrics/metric2_view.js
@@ -0,0 +1,63 @@
+/**
+ * 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.
+ */
+
+/**
+ * @class
+ *
+ * This is a view for showing cluster CPU metrics
+ *
+ * @extends App.ChartView
+ * @extends Ember.Object
+ * @extends Ember.View
+ */
+App.Metric2View = App.ChartView.extend({
+ id: "service-metrics-hdfs-jvm-threads",
+ title: 'jvm Threads',
+ renderer: 'line',
+
+ ajaxIndex: 'metrics2',
+
+ transformToSeries: function (jsonData) {
+ var seriesArray = [];
+ if (jsonData && jsonData.metrics && jsonData.metrics.jvm) {
+ for ( var name in jsonData.metrics.jvm) {
+ var displayName;
+ var seriesData = jsonData.metrics.jvm[name];
+ switch (name) {
+ case "threadsBlocked":
+ displayName = 'Threads Blocked';
+ break;
+ case "threadsWaiting":
+ displayName = 'Threads Waiting';
+ break;
+ case "threadsTimedWaiting":
+ displayName = 'Threads Timed Waiting';
+ break;
+ case "threadsRunnable":
+ displayName = 'Threads Runnable';
+ break;
+ default:
+ break;
+ }
+ if (seriesData) {
+ seriesArray.push(this.transformData(seriesData, displayName));
+ }
+ }
+ }
+ return seriesArray;
+ }
+});
[4/8] AMBARI-5928. Create and populate Metrics section of a slider
app. (onechiporenko)
Posted by on...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/d3.v2.js
----------------------------------------------------------------------
diff --git a/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/d3.v2.js b/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/d3.v2.js
new file mode 100644
index 0000000..991bd5e
--- /dev/null
+++ b/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/d3.v2.js
@@ -0,0 +1,7033 @@
+(function() {
+ function d3_class(ctor, properties) {
+ try {
+ for (var key in properties) {
+ Object.defineProperty(ctor.prototype, key, {
+ value: properties[key],
+ enumerable: false
+ });
+ }
+ } catch (e) {
+ ctor.prototype = properties;
+ }
+ }
+ function d3_arrayCopy(pseudoarray) {
+ var i = -1, n = pseudoarray.length, array = [];
+ while (++i < n) array.push(pseudoarray[i]);
+ return array;
+ }
+ function d3_arraySlice(pseudoarray) {
+ return Array.prototype.slice.call(pseudoarray);
+ }
+ function d3_Map() {}
+ function d3_identity(d) {
+ return d;
+ }
+ function d3_this() {
+ return this;
+ }
+ function d3_true() {
+ return true;
+ }
+ function d3_functor(v) {
+ return typeof v === "function" ? v : function() {
+ return v;
+ };
+ }
+ function d3_rebind(target, source, method) {
+ return function() {
+ var value = method.apply(source, arguments);
+ return arguments.length ? target : value;
+ };
+ }
+ function d3_number(x) {
+ return x != null && !isNaN(x);
+ }
+ function d3_zipLength(d) {
+ return d.length;
+ }
+ function d3_splitter(d) {
+ return d == null;
+ }
+ function d3_collapse(s) {
+ return s.trim().replace(/\s+/g, " ");
+ }
+ function d3_range_integerScale(x) {
+ var k = 1;
+ while (x * k % 1) k *= 10;
+ return k;
+ }
+ function d3_dispatch() {}
+ function d3_dispatch_event(dispatch) {
+ function event() {
+ var z = listeners, i = -1, n = z.length, l;
+ while (++i < n) if (l = z[i].on) l.apply(this, arguments);
+ return dispatch;
+ }
+ var listeners = [], listenerByName = new d3_Map;
+ event.on = function(name, listener) {
+ var l = listenerByName.get(name), i;
+ if (arguments.length < 2) return l && l.on;
+ if (l) {
+ l.on = null;
+ listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1));
+ listenerByName.remove(name);
+ }
+ if (listener) listeners.push(listenerByName.set(name, {
+ on: listener
+ }));
+ return dispatch;
+ };
+ return event;
+ }
+ function d3_format_precision(x, p) {
+ return p - (x ? 1 + Math.floor(Math.log(x + Math.pow(10, 1 + Math.floor(Math.log(x) / Math.LN10) - p)) / Math.LN10) : 1);
+ }
+ function d3_format_typeDefault(x) {
+ return x + "";
+ }
+ function d3_format_group(value) {
+ var i = value.lastIndexOf("."), f = i >= 0 ? value.substring(i) : (i = value.length, ""), t = [];
+ while (i > 0) t.push(value.substring(i -= 3, i + 3));
+ return t.reverse().join(",") + f;
+ }
+ function d3_formatPrefix(d, i) {
+ var k = Math.pow(10, Math.abs(8 - i) * 3);
+ return {
+ scale: i > 8 ? function(d) {
+ return d / k;
+ } : function(d) {
+ return d * k;
+ },
+ symbol: d
+ };
+ }
+ function d3_ease_clamp(f) {
+ return function(t) {
+ return t <= 0 ? 0 : t >= 1 ? 1 : f(t);
+ };
+ }
+ function d3_ease_reverse(f) {
+ return function(t) {
+ return 1 - f(1 - t);
+ };
+ }
+ function d3_ease_reflect(f) {
+ return function(t) {
+ return .5 * (t < .5 ? f(2 * t) : 2 - f(2 - 2 * t));
+ };
+ }
+ function d3_ease_identity(t) {
+ return t;
+ }
+ function d3_ease_poly(e) {
+ return function(t) {
+ return Math.pow(t, e);
+ };
+ }
+ function d3_ease_sin(t) {
+ return 1 - Math.cos(t * Math.PI / 2);
+ }
+ function d3_ease_exp(t) {
+ return Math.pow(2, 10 * (t - 1));
+ }
+ function d3_ease_circle(t) {
+ return 1 - Math.sqrt(1 - t * t);
+ }
+ function d3_ease_elastic(a, p) {
+ var s;
+ if (arguments.length < 2) p = .45;
+ if (arguments.length < 1) {
+ a = 1;
+ s = p / 4;
+ } else s = p / (2 * Math.PI) * Math.asin(1 / a);
+ return function(t) {
+ return 1 + a * Math.pow(2, 10 * -t) * Math.sin((t - s) * 2 * Math.PI / p);
+ };
+ }
+ function d3_ease_back(s) {
+ if (!s) s = 1.70158;
+ return function(t) {
+ return t * t * ((s + 1) * t - s);
+ };
+ }
+ function d3_ease_bounce(t) {
+ return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375;
+ }
+ function d3_eventCancel() {
+ d3.event.stopPropagation();
+ d3.event.preventDefault();
+ }
+ function d3_eventSource() {
+ var e = d3.event, s;
+ while (s = e.sourceEvent) e = s;
+ return e;
+ }
+ function d3_eventDispatch(target) {
+ var dispatch = new d3_dispatch, i = 0, n = arguments.length;
+ while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);
+ dispatch.of = function(thiz, argumentz) {
+ return function(e1) {
+ try {
+ var e0 = e1.sourceEvent = d3.event;
+ e1.target = target;
+ d3.event = e1;
+ dispatch[e1.type].apply(thiz, argumentz);
+ } finally {
+ d3.event = e0;
+ }
+ };
+ };
+ return dispatch;
+ }
+ function d3_transform(m) {
+ var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0;
+ if (r0[0] * r1[1] < r1[0] * r0[1]) {
+ r0[0] *= -1;
+ r0[1] *= -1;
+ kx *= -1;
+ kz *= -1;
+ }
+ this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_transformDegrees;
+ this.translate = [ m.e, m.f ];
+ this.scale = [ kx, ky ];
+ this.skew = ky ? Math.atan2(kz, ky) * d3_transformDegrees : 0;
+ }
+ function d3_transformDot(a, b) {
+ return a[0] * b[0] + a[1] * b[1];
+ }
+ function d3_transformNormalize(a) {
+ var k = Math.sqrt(d3_transformDot(a, a));
+ if (k) {
+ a[0] /= k;
+ a[1] /= k;
+ }
+ return k;
+ }
+ function d3_transformCombine(a, b, k) {
+ a[0] += k * b[0];
+ a[1] += k * b[1];
+ return a;
+ }
+ function d3_interpolateByName(name) {
+ return name == "transform" ? d3.interpolateTransform : d3.interpolate;
+ }
+ function d3_uninterpolateNumber(a, b) {
+ b = b - (a = +a) ? 1 / (b - a) : 0;
+ return function(x) {
+ return (x - a) * b;
+ };
+ }
+ function d3_uninterpolateClamp(a, b) {
+ b = b - (a = +a) ? 1 / (b - a) : 0;
+ return function(x) {
+ return Math.max(0, Math.min(1, (x - a) * b));
+ };
+ }
+ function d3_rgb(r, g, b) {
+ return new d3_Rgb(r, g, b);
+ }
+ function d3_Rgb(r, g, b) {
+ this.r = r;
+ this.g = g;
+ this.b = b;
+ }
+ function d3_rgb_hex(v) {
+ return v < 16 ? "0" + Math.max(0, v).toString(16) : Math.min(255, v).toString(16);
+ }
+ function d3_rgb_parse(format, rgb, hsl) {
+ var r = 0, g = 0, b = 0, m1, m2, name;
+ m1 = /([a-z]+)\((.*)\)/i.exec(format);
+ if (m1) {
+ m2 = m1[2].split(",");
+ switch (m1[1]) {
+ case "hsl":
+ {
+ return hsl(parseFloat(m2[0]), parseFloat(m2[1]) / 100, parseFloat(m2[2]) / 100);
+ }
+ case "rgb":
+ {
+ return rgb(d3_rgb_parseNumber(m2[0]), d3_rgb_parseNumber(m2[1]), d3_rgb_parseNumber(m2[2]));
+ }
+ }
+ }
+ if (name = d3_rgb_names.get(format)) return rgb(name.r, name.g, name.b);
+ if (format != null && format.charAt(0) === "#") {
+ if (format.length === 4) {
+ r = format.charAt(1);
+ r += r;
+ g = format.charAt(2);
+ g += g;
+ b = format.charAt(3);
+ b += b;
+ } else if (format.length === 7) {
+ r = format.substring(1, 3);
+ g = format.substring(3, 5);
+ b = format.substring(5, 7);
+ }
+ r = parseInt(r, 16);
+ g = parseInt(g, 16);
+ b = parseInt(b, 16);
+ }
+ return rgb(r, g, b);
+ }
+ function d3_rgb_hsl(r, g, b) {
+ var min = Math.min(r /= 255, g /= 255, b /= 255), max = Math.max(r, g, b), d = max - min, h, s, l = (max + min) / 2;
+ if (d) {
+ s = l < .5 ? d / (max + min) : d / (2 - max - min);
+ if (r == max) h = (g - b) / d + (g < b ? 6 : 0); else if (g == max) h = (b - r) / d + 2; else h = (r - g) / d + 4;
+ h *= 60;
+ } else {
+ s = h = 0;
+ }
+ return d3_hsl(h, s, l);
+ }
+ function d3_rgb_lab(r, g, b) {
+ r = d3_rgb_xyz(r);
+ g = d3_rgb_xyz(g);
+ b = d3_rgb_xyz(b);
+ var x = d3_xyz_lab((.4124564 * r + .3575761 * g + .1804375 * b) / d3_lab_X), y = d3_xyz_lab((.2126729 * r + .7151522 * g + .072175 * b) / d3_lab_Y), z = d3_xyz_lab((.0193339 * r + .119192 * g + .9503041 * b) / d3_lab_Z);
+ return d3_lab(116 * y - 16, 500 * (x - y), 200 * (y - z));
+ }
+ function d3_rgb_xyz(r) {
+ return (r /= 255) <= .04045 ? r / 12.92 : Math.pow((r + .055) / 1.055, 2.4);
+ }
+ function d3_rgb_parseNumber(c) {
+ var f = parseFloat(c);
+ return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f;
+ }
+ function d3_hsl(h, s, l) {
+ return new d3_Hsl(h, s, l);
+ }
+ function d3_Hsl(h, s, l) {
+ this.h = h;
+ this.s = s;
+ this.l = l;
+ }
+ function d3_hsl_rgb(h, s, l) {
+ function v(h) {
+ if (h > 360) h -= 360; else if (h < 0) h += 360;
+ if (h < 60) return m1 + (m2 - m1) * h / 60;
+ if (h < 180) return m2;
+ if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60;
+ return m1;
+ }
+ function vv(h) {
+ return Math.round(v(h) * 255);
+ }
+ var m1, m2;
+ h = h % 360;
+ if (h < 0) h += 360;
+ s = s < 0 ? 0 : s > 1 ? 1 : s;
+ l = l < 0 ? 0 : l > 1 ? 1 : l;
+ m2 = l <= .5 ? l * (1 + s) : l + s - l * s;
+ m1 = 2 * l - m2;
+ return d3_rgb(vv(h + 120), vv(h), vv(h - 120));
+ }
+ function d3_hcl(h, c, l) {
+ return new d3_Hcl(h, c, l);
+ }
+ function d3_Hcl(h, c, l) {
+ this.h = h;
+ this.c = c;
+ this.l = l;
+ }
+ function d3_hcl_lab(h, c, l) {
+ return d3_lab(l, Math.cos(h *= Math.PI / 180) * c, Math.sin(h) * c);
+ }
+ function d3_lab(l, a, b) {
+ return new d3_Lab(l, a, b);
+ }
+ function d3_Lab(l, a, b) {
+ this.l = l;
+ this.a = a;
+ this.b = b;
+ }
+ function d3_lab_rgb(l, a, b) {
+ var y = (l + 16) / 116, x = y + a / 500, z = y - b / 200;
+ x = d3_lab_xyz(x) * d3_lab_X;
+ y = d3_lab_xyz(y) * d3_lab_Y;
+ z = d3_lab_xyz(z) * d3_lab_Z;
+ return d3_rgb(d3_xyz_rgb(3.2404542 * x - 1.5371385 * y - .4985314 * z), d3_xyz_rgb(-.969266 * x + 1.8760108 * y + .041556 * z), d3_xyz_rgb(.0556434 * x - .2040259 * y + 1.0572252 * z));
+ }
+ function d3_lab_hcl(l, a, b) {
+ return d3_hcl(Math.atan2(b, a) / Math.PI * 180, Math.sqrt(a * a + b * b), l);
+ }
+ function d3_lab_xyz(x) {
+ return x > .206893034 ? x * x * x : (x - 4 / 29) / 7.787037;
+ }
+ function d3_xyz_lab(x) {
+ return x > .008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29;
+ }
+ function d3_xyz_rgb(r) {
+ return Math.round(255 * (r <= .00304 ? 12.92 * r : 1.055 * Math.pow(r, 1 / 2.4) - .055));
+ }
+ function d3_selection(groups) {
+ d3_arraySubclass(groups, d3_selectionPrototype);
+ return groups;
+ }
+ function d3_selection_selector(selector) {
+ return function() {
+ return d3_select(selector, this);
+ };
+ }
+ function d3_selection_selectorAll(selector) {
+ return function() {
+ return d3_selectAll(selector, this);
+ };
+ }
+ function d3_selection_attr(name, value) {
+ function attrNull() {
+ this.removeAttribute(name);
+ }
+ function attrNullNS() {
+ this.removeAttributeNS(name.space, name.local);
+ }
+ function attrConstant() {
+ this.setAttribute(name, value);
+ }
+ function attrConstantNS() {
+ this.setAttributeNS(name.space, name.local, value);
+ }
+ function attrFunction() {
+ var x = value.apply(this, arguments);
+ if (x == null) this.removeAttribute(name); else this.setAttribute(name, x);
+ }
+ function attrFunctionNS() {
+ var x = value.apply(this, arguments);
+ if (x == null) this.removeAttributeNS(name.space, name.local); else this.setAttributeNS(name.space, name.local, x);
+ }
+ name = d3.ns.qualify(name);
+ return value == null ? name.local ? attrNullNS : attrNull : typeof value === "function" ? name.local ? attrFunctionNS : attrFunction : name.local ? attrConstantNS : attrConstant;
+ }
+ function d3_selection_classedRe(name) {
+ return new RegExp("(?:^|\\s+)" + d3.requote(name) + "(?:\\s+|$)", "g");
+ }
+ function d3_selection_classed(name, value) {
+ function classedConstant() {
+ var i = -1;
+ while (++i < n) name[i](this, value);
+ }
+ function classedFunction() {
+ var i = -1, x = value.apply(this, arguments);
+ while (++i < n) name[i](this, x);
+ }
+ name = name.trim().split(/\s+/).map(d3_selection_classedName);
+ var n = name.length;
+ return typeof value === "function" ? classedFunction : classedConstant;
+ }
+ function d3_selection_classedName(name) {
+ var re = d3_selection_classedRe(name);
+ return function(node, value) {
+ if (c = node.classList) return value ? c.add(name) : c.remove(name);
+ var c = node.className, cb = c.baseVal != null, cv = cb ? c.baseVal : c;
+ if (value) {
+ re.lastIndex = 0;
+ if (!re.test(cv)) {
+ cv = d3_collapse(cv + " " + name);
+ if (cb) c.baseVal = cv; else node.className = cv;
+ }
+ } else if (cv) {
+ cv = d3_collapse(cv.replace(re, " "));
+ if (cb) c.baseVal = cv; else node.className = cv;
+ }
+ };
+ }
+ function d3_selection_style(name, value, priority) {
+ function styleNull() {
+ this.style.removeProperty(name);
+ }
+ function styleConstant() {
+ this.style.setProperty(name, value, priority);
+ }
+ function styleFunction() {
+ var x = value.apply(this, arguments);
+ if (x == null) this.style.removeProperty(name); else this.style.setProperty(name, x, priority);
+ }
+ return value == null ? styleNull : typeof value === "function" ? styleFunction : styleConstant;
+ }
+ function d3_selection_property(name, value) {
+ function propertyNull() {
+ delete this[name];
+ }
+ function propertyConstant() {
+ this[name] = value;
+ }
+ function propertyFunction() {
+ var x = value.apply(this, arguments);
+ if (x == null) delete this[name]; else this[name] = x;
+ }
+ return value == null ? propertyNull : typeof value === "function" ? propertyFunction : propertyConstant;
+ }
+ function d3_selection_dataNode(data) {
+ return {
+ __data__: data
+ };
+ }
+ function d3_selection_filter(selector) {
+ return function() {
+ return d3_selectMatches(this, selector);
+ };
+ }
+ function d3_selection_sortComparator(comparator) {
+ if (!arguments.length) comparator = d3.ascending;
+ return function(a, b) {
+ return comparator(a && a.__data__, b && b.__data__);
+ };
+ }
+ function d3_selection_on(type, listener, capture) {
+ function onRemove() {
+ var wrapper = this[name];
+ if (wrapper) {
+ this.removeEventListener(type, wrapper, wrapper.$);
+ delete this[name];
+ }
+ }
+ function onAdd() {
+ function wrapper(e) {
+ var o = d3.event;
+ d3.event = e;
+ args[0] = node.__data__;
+ try {
+ listener.apply(node, args);
+ } finally {
+ d3.event = o;
+ }
+ }
+ var node = this, args = arguments;
+ onRemove.call(this);
+ this.addEventListener(type, this[name] = wrapper, wrapper.$ = capture);
+ wrapper._ = listener;
+ }
+ var name = "__on" + type, i = type.indexOf(".");
+ if (i > 0) type = type.substring(0, i);
+ return listener ? onAdd : onRemove;
+ }
+ function d3_selection_each(groups, callback) {
+ for (var j = 0, m = groups.length; j < m; j++) {
+ for (var group = groups[j], i = 0, n = group.length, node; i < n; i++) {
+ if (node = group[i]) callback(node, i, j);
+ }
+ }
+ return groups;
+ }
+ function d3_selection_enter(selection) {
+ d3_arraySubclass(selection, d3_selection_enterPrototype);
+ return selection;
+ }
+ function d3_transition(groups, id, time) {
+ d3_arraySubclass(groups, d3_transitionPrototype);
+ var tweens = new d3_Map, event = d3.dispatch("start", "end"), ease = d3_transitionEase;
+ groups.id = id;
+ groups.time = time;
+ groups.tween = function(name, tween) {
+ if (arguments.length < 2) return tweens.get(name);
+ if (tween == null) tweens.remove(name); else tweens.set(name, tween);
+ return groups;
+ };
+ groups.ease = function(value) {
+ if (!arguments.length) return ease;
+ ease = typeof value === "function" ? value : d3.ease.apply(d3, arguments);
+ return groups;
+ };
+ groups.each = function(type, listener) {
+ if (arguments.length < 2) return d3_transition_each.call(groups, type);
+ event.on(type, listener);
+ return groups;
+ };
+ d3.timer(function(elapsed) {
+ return d3_selection_each(groups, function(node, i, j) {
+ function start(elapsed) {
+ if (lock.active > id) return stop();
+ lock.active = id;
+ tweens.forEach(function(key, value) {
+ if (value = value.call(node, d, i)) {
+ tweened.push(value);
+ }
+ });
+ event.start.call(node, d, i);
+ if (!tick(elapsed)) d3.timer(tick, 0, time);
+ return 1;
+ }
+ function tick(elapsed) {
+ if (lock.active !== id) return stop();
+ var t = (elapsed - delay) / duration, e = ease(t), n = tweened.length;
+ while (n > 0) {
+ tweened[--n].call(node, e);
+ }
+ if (t >= 1) {
+ stop();
+ d3_transitionId = id;
+ event.end.call(node, d, i);
+ d3_transitionId = 0;
+ return 1;
+ }
+ }
+ function stop() {
+ if (!--lock.count) delete node.__transition__;
+ return 1;
+ }
+ var tweened = [], delay = node.delay, duration = node.duration, lock = (node = node.node).__transition__ || (node.__transition__ = {
+ active: 0,
+ count: 0
+ }), d = node.__data__;
+ ++lock.count;
+ delay <= elapsed ? start(elapsed) : d3.timer(start, delay, time);
+ });
+ }, 0, time);
+ return groups;
+ }
+ function d3_transition_each(callback) {
+ var id = d3_transitionId, ease = d3_transitionEase, delay = d3_transitionDelay, duration = d3_transitionDuration;
+ d3_transitionId = this.id;
+ d3_transitionEase = this.ease();
+ d3_selection_each(this, function(node, i, j) {
+ d3_transitionDelay = node.delay;
+ d3_transitionDuration = node.duration;
+ callback.call(node = node.node, node.__data__, i, j);
+ });
+ d3_transitionId = id;
+ d3_transitionEase = ease;
+ d3_transitionDelay = delay;
+ d3_transitionDuration = duration;
+ return this;
+ }
+ function d3_tweenNull(d, i, a) {
+ return a != "" && d3_tweenRemove;
+ }
+ function d3_tweenByName(b, name) {
+ return d3.tween(b, d3_interpolateByName(name));
+ }
+ function d3_timer_step() {
+ var elapsed, now = Date.now(), t1 = d3_timer_queue;
+ while (t1) {
+ elapsed = now - t1.then;
+ if (elapsed >= t1.delay) t1.flush = t1.callback(elapsed);
+ t1 = t1.next;
+ }
+ var delay = d3_timer_flush() - now;
+ if (delay > 24) {
+ if (isFinite(delay)) {
+ clearTimeout(d3_timer_timeout);
+ d3_timer_timeout = setTimeout(d3_timer_step, delay);
+ }
+ d3_timer_interval = 0;
+ } else {
+ d3_timer_interval = 1;
+ d3_timer_frame(d3_timer_step);
+ }
+ }
+ function d3_timer_flush() {
+ var t0 = null, t1 = d3_timer_queue, then = Infinity;
+ while (t1) {
+ if (t1.flush) {
+ t1 = t0 ? t0.next = t1.next : d3_timer_queue = t1.next;
+ } else {
+ then = Math.min(then, t1.then + t1.delay);
+ t1 = (t0 = t1).next;
+ }
+ }
+ return then;
+ }
+ function d3_mousePoint(container, e) {
+ var svg = container.ownerSVGElement || container;
+ if (svg.createSVGPoint) {
+ var point = svg.createSVGPoint();
+ if (d3_mouse_bug44083 < 0 && (window.scrollX || window.scrollY)) {
+ svg = d3.select(document.body).append("svg").style("position", "absolute").style("top", 0).style("left", 0);
+ var ctm = svg[0][0].getScreenCTM();
+ d3_mouse_bug44083 = !(ctm.f || ctm.e);
+ svg.remove();
+ }
+ if (d3_mouse_bug44083) {
+ point.x = e.pageX;
+ point.y = e.pageY;
+ } else {
+ point.x = e.clientX;
+ point.y = e.clientY;
+ }
+ point = point.matrixTransform(container.getScreenCTM().inverse());
+ return [ point.x, point.y ];
+ }
+ var rect = container.getBoundingClientRect();
+ return [ e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop ];
+ }
+ function d3_noop() {}
+ function d3_scaleExtent(domain) {
+ var start = domain[0], stop = domain[domain.length - 1];
+ return start < stop ? [ start, stop ] : [ stop, start ];
+ }
+ function d3_scaleRange(scale) {
+ return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range());
+ }
+ function d3_scale_nice(domain, nice) {
+ var i0 = 0, i1 = domain.length - 1, x0 = domain[i0], x1 = domain[i1], dx;
+ if (x1 < x0) {
+ dx = i0, i0 = i1, i1 = dx;
+ dx = x0, x0 = x1, x1 = dx;
+ }
+ if (nice = nice(x1 - x0)) {
+ domain[i0] = nice.floor(x0);
+ domain[i1] = nice.ceil(x1);
+ }
+ return domain;
+ }
+ function d3_scale_niceDefault() {
+ return Math;
+ }
+ function d3_scale_linear(domain, range, interpolate, clamp) {
+ function rescale() {
+ var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear, uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber;
+ output = linear(domain, range, uninterpolate, interpolate);
+ input = linear(range, domain, uninterpolate, d3.interpolate);
+ return scale;
+ }
+ function scale(x) {
+ return output(x);
+ }
+ var output, input;
+ scale.invert = function(y) {
+ return input(y);
+ };
+ scale.domain = function(x) {
+ if (!arguments.length) return domain;
+ domain = x.map(Number);
+ return rescale();
+ };
+ scale.range = function(x) {
+ if (!arguments.length) return range;
+ range = x;
+ return rescale();
+ };
+ scale.rangeRound = function(x) {
+ return scale.range(x).interpolate(d3.interpolateRound);
+ };
+ scale.clamp = function(x) {
+ if (!arguments.length) return clamp;
+ clamp = x;
+ return rescale();
+ };
+ scale.interpolate = function(x) {
+ if (!arguments.length) return interpolate;
+ interpolate = x;
+ return rescale();
+ };
+ scale.ticks = function(m) {
+ return d3_scale_linearTicks(domain, m);
+ };
+ scale.tickFormat = function(m) {
+ return d3_scale_linearTickFormat(domain, m);
+ };
+ scale.nice = function() {
+ d3_scale_nice(domain, d3_scale_linearNice);
+ return rescale();
+ };
+ scale.copy = function() {
+ return d3_scale_linear(domain, range, interpolate, clamp);
+ };
+ return rescale();
+ }
+ function d3_scale_linearRebind(scale, linear) {
+ return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp");
+ }
+ function d3_scale_linearNice(dx) {
+ dx = Math.pow(10, Math.round(Math.log(dx) / Math.LN10) - 1);
+ return dx && {
+ floor: function(x) {
+ return Math.floor(x / dx) * dx;
+ },
+ ceil: function(x) {
+ return Math.ceil(x / dx) * dx;
+ }
+ };
+ }
+ function d3_scale_linearTickRange(domain, m) {
+ var extent = d3_scaleExtent(domain), span = extent[1] - extent[0], step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), err = m / span * step;
+ if (err <= .15) step *= 10; else if (err <= .35) step *= 5; else if (err <= .75) step *= 2;
+ extent[0] = Math.ceil(extent[0] / step) * step;
+ extent[1] = Math.floor(extent[1] / step) * step + step * .5;
+ extent[2] = step;
+ return extent;
+ }
+ function d3_scale_linearTicks(domain, m) {
+ return d3.range.apply(d3, d3_scale_linearTickRange(domain, m));
+ }
+ function d3_scale_linearTickFormat(domain, m) {
+ return d3.format(",." + Math.max(0, -Math.floor(Math.log(d3_scale_linearTickRange(domain, m)[2]) / Math.LN10 + .01)) + "f");
+ }
+ function d3_scale_bilinear(domain, range, uninterpolate, interpolate) {
+ var u = uninterpolate(domain[0], domain[1]), i = interpolate(range[0], range[1]);
+ return function(x) {
+ return i(u(x));
+ };
+ }
+ function d3_scale_polylinear(domain, range, uninterpolate, interpolate) {
+ var u = [], i = [], j = 0, k = Math.min(domain.length, range.length) - 1;
+ if (domain[k] < domain[0]) {
+ domain = domain.slice().reverse();
+ range = range.slice().reverse();
+ }
+ while (++j <= k) {
+ u.push(uninterpolate(domain[j - 1], domain[j]));
+ i.push(interpolate(range[j - 1], range[j]));
+ }
+ return function(x) {
+ var j = d3.bisect(domain, x, 1, k) - 1;
+ return i[j](u[j](x));
+ };
+ }
+ function d3_scale_log(linear, log) {
+ function scale(x) {
+ return linear(log(x));
+ }
+ var pow = log.pow;
+ scale.invert = function(x) {
+ return pow(linear.invert(x));
+ };
+ scale.domain = function(x) {
+ if (!arguments.length) return linear.domain().map(pow);
+ log = x[0] < 0 ? d3_scale_logn : d3_scale_logp;
+ pow = log.pow;
+ linear.domain(x.map(log));
+ return scale;
+ };
+ scale.nice = function() {
+ linear.domain(d3_scale_nice(linear.domain(), d3_scale_niceDefault));
+ return scale;
+ };
+ scale.ticks = function() {
+ var extent = d3_scaleExtent(linear.domain()), ticks = [];
+ if (extent.every(isFinite)) {
+ var i = Math.floor(extent[0]), j = Math.ceil(extent[1]), u = pow(extent[0]), v = pow(extent[1]);
+ if (log === d3_scale_logn) {
+ ticks.push(pow(i));
+ for (; i++ < j; ) for (var k = 9; k > 0; k--) ticks.push(pow(i) * k);
+ } else {
+ for (; i < j; i++) for (var k = 1; k < 10; k++) ticks.push(pow(i) * k);
+ ticks.push(pow(i));
+ }
+ for (i = 0; ticks[i] < u; i++) {}
+ for (j = ticks.length; ticks[j - 1] > v; j--) {}
+ ticks = ticks.slice(i, j);
+ }
+ return ticks;
+ };
+ scale.tickFormat = function(n, format) {
+ if (arguments.length < 2) format = d3_scale_logFormat;
+ if (arguments.length < 1) return format;
+ var k = Math.max(.1, n / scale.ticks().length), f = log === d3_scale_logn ? (e = -1e-12, Math.floor) : (e = 1e-12, Math.ceil), e;
+ return function(d) {
+ return d / pow(f(log(d) + e)) <= k ? format(d) : "";
+ };
+ };
+ scale.copy = function() {
+ return d3_scale_log(linear.copy(), log);
+ };
+ return d3_scale_linearRebind(scale, linear);
+ }
+ function d3_scale_logp(x) {
+ return Math.log(x < 0 ? 0 : x) / Math.LN10;
+ }
+ function d3_scale_logn(x) {
+ return -Math.log(x > 0 ? 0 : -x) / Math.LN10;
+ }
+ function d3_scale_pow(linear, exponent) {
+ function scale(x) {
+ return linear(powp(x));
+ }
+ var powp = d3_scale_powPow(exponent), powb = d3_scale_powPow(1 / exponent);
+ scale.invert = function(x) {
+ return powb(linear.invert(x));
+ };
+ scale.domain = function(x) {
+ if (!arguments.length) return linear.domain().map(powb);
+ linear.domain(x.map(powp));
+ return scale;
+ };
+ scale.ticks = function(m) {
+ return d3_scale_linearTicks(scale.domain(), m);
+ };
+ scale.tickFormat = function(m) {
+ return d3_scale_linearTickFormat(scale.domain(), m);
+ };
+ scale.nice = function() {
+ return scale.domain(d3_scale_nice(scale.domain(), d3_scale_linearNice));
+ };
+ scale.exponent = function(x) {
+ if (!arguments.length) return exponent;
+ var domain = scale.domain();
+ powp = d3_scale_powPow(exponent = x);
+ powb = d3_scale_powPow(1 / exponent);
+ return scale.domain(domain);
+ };
+ scale.copy = function() {
+ return d3_scale_pow(linear.copy(), exponent);
+ };
+ return d3_scale_linearRebind(scale, linear);
+ }
+ function d3_scale_powPow(e) {
+ return function(x) {
+ return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e);
+ };
+ }
+ function d3_scale_ordinal(domain, ranger) {
+ function scale(x) {
+ return range[((index.get(x) || index.set(x, domain.push(x))) - 1) % range.length];
+ }
+ function steps(start, step) {
+ return d3.range(domain.length).map(function(i) {
+ return start + step * i;
+ });
+ }
+ var index, range, rangeBand;
+ scale.domain = function(x) {
+ if (!arguments.length) return domain;
+ domain = [];
+ index = new d3_Map;
+ var i = -1, n = x.length, xi;
+ while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi));
+ return scale[ranger.t].apply(scale, ranger.a);
+ };
+ scale.range = function(x) {
+ if (!arguments.length) return range;
+ range = x;
+ rangeBand = 0;
+ ranger = {
+ t: "range",
+ a: arguments
+ };
+ return scale;
+ };
+ scale.rangePoints = function(x, padding) {
+ if (arguments.length < 2) padding = 0;
+ var start = x[0], stop = x[1], step = (stop - start) / (Math.max(1, domain.length - 1) + padding);
+ range = steps(domain.length < 2 ? (start + stop) / 2 : start + step * padding / 2, step);
+ rangeBand = 0;
+ ranger = {
+ t: "rangePoints",
+ a: arguments
+ };
+ return scale;
+ };
+ scale.rangeBands = function(x, padding, outerPadding) {
+ if (arguments.length < 2) padding = 0;
+ if (arguments.length < 3) outerPadding = padding;
+ var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = (stop - start) / (domain.length - padding + 2 * outerPadding);
+ range = steps(start + step * outerPadding, step);
+ if (reverse) range.reverse();
+ rangeBand = step * (1 - padding);
+ ranger = {
+ t: "rangeBands",
+ a: arguments
+ };
+ return scale;
+ };
+ scale.rangeRoundBands = function(x, padding, outerPadding) {
+ if (arguments.length < 2) padding = 0;
+ if (arguments.length < 3) outerPadding = padding;
+ var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = Math.floor((stop - start) / (domain.length - padding + 2 * outerPadding)), error = stop - start - (domain.length - padding) * step;
+ range = steps(start + Math.round(error / 2), step);
+ if (reverse) range.reverse();
+ rangeBand = Math.round(step * (1 - padding));
+ ranger = {
+ t: "rangeRoundBands",
+ a: arguments
+ };
+ return scale;
+ };
+ scale.rangeBand = function() {
+ return rangeBand;
+ };
+ scale.rangeExtent = function() {
+ return d3_scaleExtent(ranger.a[0]);
+ };
+ scale.copy = function() {
+ return d3_scale_ordinal(domain, ranger);
+ };
+ return scale.domain(domain);
+ }
+ function d3_scale_quantile(domain, range) {
+ function rescale() {
+ var k = 0, n = domain.length, q = range.length;
+ thresholds = [];
+ while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q);
+ return scale;
+ }
+ function scale(x) {
+ if (isNaN(x = +x)) return NaN;
+ return range[d3.bisect(thresholds, x)];
+ }
+ var thresholds;
+ scale.domain = function(x) {
+ if (!arguments.length) return domain;
+ domain = x.filter(function(d) {
+ return !isNaN(d);
+ }).sort(d3.ascending);
+ return rescale();
+ };
+ scale.range = function(x) {
+ if (!arguments.length) return range;
+ range = x;
+ return rescale();
+ };
+ scale.quantiles = function() {
+ return thresholds;
+ };
+ scale.copy = function() {
+ return d3_scale_quantile(domain, range);
+ };
+ return rescale();
+ }
+ function d3_scale_quantize(x0, x1, range) {
+ function scale(x) {
+ return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))];
+ }
+ function rescale() {
+ kx = range.length / (x1 - x0);
+ i = range.length - 1;
+ return scale;
+ }
+ var kx, i;
+ scale.domain = function(x) {
+ if (!arguments.length) return [ x0, x1 ];
+ x0 = +x[0];
+ x1 = +x[x.length - 1];
+ return rescale();
+ };
+ scale.range = function(x) {
+ if (!arguments.length) return range;
+ range = x;
+ return rescale();
+ };
+ scale.copy = function() {
+ return d3_scale_quantize(x0, x1, range);
+ };
+ return rescale();
+ }
+ function d3_scale_threshold(domain, range) {
+ function scale(x) {
+ return range[d3.bisect(domain, x)];
+ }
+ scale.domain = function(_) {
+ if (!arguments.length) return domain;
+ domain = _;
+ return scale;
+ };
+ scale.range = function(_) {
+ if (!arguments.length) return range;
+ range = _;
+ return scale;
+ };
+ scale.copy = function() {
+ return d3_scale_threshold(domain, range);
+ };
+ return scale;
+ }
+ function d3_scale_identity(domain) {
+ function identity(x) {
+ return +x;
+ }
+ identity.invert = identity;
+ identity.domain = identity.range = function(x) {
+ if (!arguments.length) return domain;
+ domain = x.map(identity);
+ return identity;
+ };
+ identity.ticks = function(m) {
+ return d3_scale_linearTicks(domain, m);
+ };
+ identity.tickFormat = function(m) {
+ return d3_scale_linearTickFormat(domain, m);
+ };
+ identity.copy = function() {
+ return d3_scale_identity(domain);
+ };
+ return identity;
+ }
+ function d3_svg_arcInnerRadius(d) {
+ return d.innerRadius;
+ }
+ function d3_svg_arcOuterRadius(d) {
+ return d.outerRadius;
+ }
+ function d3_svg_arcStartAngle(d) {
+ return d.startAngle;
+ }
+ function d3_svg_arcEndAngle(d) {
+ return d.endAngle;
+ }
+ function d3_svg_line(projection) {
+ function line(data) {
+ function segment() {
+ segments.push("M", interpolate(projection(points), tension));
+ }
+ var segments = [], points = [], i = -1, n = data.length, d, fx = d3_functor(x), fy = d3_functor(y);
+ while (++i < n) {
+ if (defined.call(this, d = data[i], i)) {
+ points.push([ +fx.call(this, d, i), +fy.call(this, d, i) ]);
+ } else if (points.length) {
+ segment();
+ points = [];
+ }
+ }
+ if (points.length) segment();
+ return segments.length ? segments.join("") : null;
+ }
+ var x = d3_svg_lineX, y = d3_svg_lineY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, tension = .7;
+ line.x = function(_) {
+ if (!arguments.length) return x;
+ x = _;
+ return line;
+ };
+ line.y = function(_) {
+ if (!arguments.length) return y;
+ y = _;
+ return line;
+ };
+ line.defined = function(_) {
+ if (!arguments.length) return defined;
+ defined = _;
+ return line;
+ };
+ line.interpolate = function(_) {
+ if (!arguments.length) return interpolateKey;
+ if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key;
+ return line;
+ };
+ line.tension = function(_) {
+ if (!arguments.length) return tension;
+ tension = _;
+ return line;
+ };
+ return line;
+ }
+ function d3_svg_lineX(d) {
+ return d[0];
+ }
+ function d3_svg_lineY(d) {
+ return d[1];
+ }
+ function d3_svg_lineLinear(points) {
+ return points.join("L");
+ }
+ function d3_svg_lineLinearClosed(points) {
+ return d3_svg_lineLinear(points) + "Z";
+ }
+ function d3_svg_lineStepBefore(points) {
+ var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ];
+ while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]);
+ return path.join("");
+ }
+ function d3_svg_lineStepAfter(points) {
+ var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ];
+ while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]);
+ return path.join("");
+ }
+ function d3_svg_lineCardinalOpen(points, tension) {
+ return points.length < 4 ? d3_svg_lineLinear(points) : points[1] + d3_svg_lineHermite(points.slice(1, points.length - 1), d3_svg_lineCardinalTangents(points, tension));
+ }
+ function d3_svg_lineCardinalClosed(points, tension) {
+ return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite((points.push(points[0]), points), d3_svg_lineCardinalTangents([ points[points.length - 2] ].concat(points, [ points[1] ]), tension));
+ }
+ function d3_svg_lineCardinal(points, tension, closed) {
+ return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineCardinalTangents(points, tension));
+ }
+ function d3_svg_lineHermite(points, tangents) {
+ if (tangents.length < 1 || points.length != tangents.length && points.length != tangents.length + 2) {
+ return d3_svg_lineLinear(points);
+ }
+ var quad = points.length != tangents.length, path = "", p0 = points[0], p = points[1], t0 = tangents[0], t = t0, pi = 1;
+ if (quad) {
+ path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3) + "," + p[0] + "," + p[1];
+ p0 = points[1];
+ pi = 2;
+ }
+ if (tangents.length > 1) {
+ t = tangents[1];
+ p = points[pi];
+ pi++;
+ path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1]) + "," + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1];
+ for (var i = 2; i < tangents.length; i++, pi++) {
+ p = points[pi];
+ t = tangents[i];
+ path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1];
+ }
+ }
+ if (quad) {
+ var lp = points[pi];
+ path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3) + "," + lp[0] + "," + lp[1];
+ }
+ return path;
+ }
+ function d3_svg_lineCardinalTangents(points, tension) {
+ var tangents = [], a = (1 - tension) / 2, p0, p1 = points[0], p2 = points[1], i = 1, n = points.length;
+ while (++i < n) {
+ p0 = p1;
+ p1 = p2;
+ p2 = points[i];
+ tangents.push([ a * (p2[0] - p0[0]), a * (p2[1] - p0[1]) ]);
+ }
+ return tangents;
+ }
+ function d3_svg_lineBasis(points) {
+ if (points.length < 3) return d3_svg_lineLinear(points);
+ var i = 1, n = points.length, pi = points[0], x0 = pi[0], y0 = pi[1], px = [ x0, x0, x0, (pi = points[1])[0] ], py = [ y0, y0, y0, pi[1] ], path = [ x0, ",", y0 ];
+ d3_svg_lineBasisBezier(path, px, py);
+ while (++i < n) {
+ pi = points[i];
+ px.shift();
+ px.push(pi[0]);
+ py.shift();
+ py.push(pi[1]);
+ d3_svg_lineBasisBezier(path, px, py);
+ }
+ i = -1;
+ while (++i < 2) {
+ px.shift();
+ px.push(pi[0]);
+ py.shift();
+ py.push(pi[1]);
+ d3_svg_lineBasisBezier(path, px, py);
+ }
+ return path.join("");
+ }
+ function d3_svg_lineBasisOpen(points) {
+ if (points.length < 4) return d3_svg_lineLinear(points);
+ var path = [], i = -1, n = points.length, pi, px = [ 0 ], py = [ 0 ];
+ while (++i < 3) {
+ pi = points[i];
+ px.push(pi[0]);
+ py.push(pi[1]);
+ }
+ path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px) + "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py));
+ --i;
+ while (++i < n) {
+ pi = points[i];
+ px.shift();
+ px.push(pi[0]);
+ py.shift();
+ py.push(pi[1]);
+ d3_svg_lineBasisBezier(path, px, py);
+ }
+ return path.join("");
+ }
+ function d3_svg_lineBasisClosed(points) {
+ var path, i = -1, n = points.length, m = n + 4, pi, px = [], py = [];
+ while (++i < 4) {
+ pi = points[i % n];
+ px.push(pi[0]);
+ py.push(pi[1]);
+ }
+ path = [ d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ];
+ --i;
+ while (++i < m) {
+ pi = points[i % n];
+ px.shift();
+ px.push(pi[0]);
+ py.shift();
+ py.push(pi[1]);
+ d3_svg_lineBasisBezier(path, px, py);
+ }
+ return path.join("");
+ }
+ function d3_svg_lineBundle(points, tension) {
+ var n = points.length - 1;
+ if (n) {
+ var x0 = points[0][0], y0 = points[0][1], dx = points[n][0] - x0, dy = points[n][1] - y0, i = -1, p, t;
+ while (++i <= n) {
+ p = points[i];
+ t = i / n;
+ p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx);
+ p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy);
+ }
+ }
+ return d3_svg_lineBasis(points);
+ }
+ function d3_svg_lineDot4(a, b) {
+ return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
+ }
+ function d3_svg_lineBasisBezier(path, x, y) {
+ path.push("C", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y));
+ }
+ function d3_svg_lineSlope(p0, p1) {
+ return (p1[1] - p0[1]) / (p1[0] - p0[0]);
+ }
+ function d3_svg_lineFiniteDifferences(points) {
+ var i = 0, j = points.length - 1, m = [], p0 = points[0], p1 = points[1], d = m[0] = d3_svg_lineSlope(p0, p1);
+ while (++i < j) {
+ m[i] = (d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]))) / 2;
+ }
+ m[i] = d;
+ return m;
+ }
+ function d3_svg_lineMonotoneTangents(points) {
+ var tangents = [], d, a, b, s, m = d3_svg_lineFiniteDifferences(points), i = -1, j = points.length - 1;
+ while (++i < j) {
+ d = d3_svg_lineSlope(points[i], points[i + 1]);
+ if (Math.abs(d) < 1e-6) {
+ m[i] = m[i + 1] = 0;
+ } else {
+ a = m[i] / d;
+ b = m[i + 1] / d;
+ s = a * a + b * b;
+ if (s > 9) {
+ s = d * 3 / Math.sqrt(s);
+ m[i] = s * a;
+ m[i + 1] = s * b;
+ }
+ }
+ }
+ i = -1;
+ while (++i <= j) {
+ s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i]));
+ tangents.push([ s || 0, m[i] * s || 0 ]);
+ }
+ return tangents;
+ }
+ function d3_svg_lineMonotone(points) {
+ return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points));
+ }
+ function d3_svg_lineRadial(points) {
+ var point, i = -1, n = points.length, r, a;
+ while (++i < n) {
+ point = points[i];
+ r = point[0];
+ a = point[1] + d3_svg_arcOffset;
+ point[0] = r * Math.cos(a);
+ point[1] = r * Math.sin(a);
+ }
+ return points;
+ }
+ function d3_svg_area(projection) {
+ function area(data) {
+ function segment() {
+ segments.push("M", interpolate(projection(points1), tension), L, interpolateReverse(projection(points0.reverse()), tension), "Z");
+ }
+ var segments = [], points0 = [], points1 = [], i = -1, n = data.length, d, fx0 = d3_functor(x0), fy0 = d3_functor(y0), fx1 = x0 === x1 ? function() {
+ return x;
+ } : d3_functor(x1), fy1 = y0 === y1 ? function() {
+ return y;
+ } : d3_functor(y1), x, y;
+ while (++i < n) {
+ if (defined.call(this, d = data[i], i)) {
+ points0.push([ x = +fx0.call(this, d, i), y = +fy0.call(this, d, i) ]);
+ points1.push([ +fx1.call(this, d, i), +fy1.call(this, d, i) ]);
+ } else if (points0.length) {
+ segment();
+ points0 = [];
+ points1 = [];
+ }
+ }
+ if (points0.length) segment();
+ return segments.length ? segments.join("") : null;
+ }
+ var x0 = d3_svg_lineX, x1 = d3_svg_lineX, y0 = 0, y1 = d3_svg_lineY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, interpolateReverse = interpolate, L = "L", tension = .7;
+ area.x = function(_) {
+ if (!arguments.length) return x1;
+ x0 = x1 = _;
+ return area;
+ };
+ area.x0 = function(_) {
+ if (!arguments.length) return x0;
+ x0 = _;
+ return area;
+ };
+ area.x1 = function(_) {
+ if (!arguments.length) return x1;
+ x1 = _;
+ return area;
+ };
+ area.y = function(_) {
+ if (!arguments.length) return y1;
+ y0 = y1 = _;
+ return area;
+ };
+ area.y0 = function(_) {
+ if (!arguments.length) return y0;
+ y0 = _;
+ return area;
+ };
+ area.y1 = function(_) {
+ if (!arguments.length) return y1;
+ y1 = _;
+ return area;
+ };
+ area.defined = function(_) {
+ if (!arguments.length) return defined;
+ defined = _;
+ return area;
+ };
+ area.interpolate = function(_) {
+ if (!arguments.length) return interpolateKey;
+ if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key;
+ interpolateReverse = interpolate.reverse || interpolate;
+ L = interpolate.closed ? "M" : "L";
+ return area;
+ };
+ area.tension = function(_) {
+ if (!arguments.length) return tension;
+ tension = _;
+ return area;
+ };
+ return area;
+ }
+ function d3_svg_chordSource(d) {
+ return d.source;
+ }
+ function d3_svg_chordTarget(d) {
+ return d.target;
+ }
+ function d3_svg_chordRadius(d) {
+ return d.radius;
+ }
+ function d3_svg_chordStartAngle(d) {
+ return d.startAngle;
+ }
+ function d3_svg_chordEndAngle(d) {
+ return d.endAngle;
+ }
+ function d3_svg_diagonalProjection(d) {
+ return [ d.x, d.y ];
+ }
+ function d3_svg_diagonalRadialProjection(projection) {
+ return function() {
+ var d = projection.apply(this, arguments), r = d[0], a = d[1] + d3_svg_arcOffset;
+ return [ r * Math.cos(a), r * Math.sin(a) ];
+ };
+ }
+ function d3_svg_symbolSize() {
+ return 64;
+ }
+ function d3_svg_symbolType() {
+ return "circle";
+ }
+ function d3_svg_symbolCircle(size) {
+ var r = Math.sqrt(size / Math.PI);
+ return "M0," + r + "A" + r + "," + r + " 0 1,1 0," + -r + "A" + r + "," + r + " 0 1,1 0," + r + "Z";
+ }
+ function d3_svg_axisX(selection, x) {
+ selection.attr("transform", function(d) {
+ return "translate(" + x(d) + ",0)";
+ });
+ }
+ function d3_svg_axisY(selection, y) {
+ selection.attr("transform", function(d) {
+ return "translate(0," + y(d) + ")";
+ });
+ }
+ function d3_svg_axisSubdivide(scale, ticks, m) {
+ subticks = [];
+ if (m && ticks.length > 1) {
+ var extent = d3_scaleExtent(scale.domain()), subticks, i = -1, n = ticks.length, d = (ticks[1] - ticks[0]) / ++m, j, v;
+ while (++i < n) {
+ for (j = m; --j > 0; ) {
+ if ((v = +ticks[i] - j * d) >= extent[0]) {
+ subticks.push(v);
+ }
+ }
+ }
+ for (--i, j = 0; ++j < m && (v = +ticks[i] + j * d) < extent[1]; ) {
+ subticks.push(v);
+ }
+ }
+ return subticks;
+ }
+ function d3_behavior_zoomDelta() {
+ if (!d3_behavior_zoomDiv) {
+ d3_behavior_zoomDiv = d3.select("body").append("div").style("visibility", "hidden").style("top", 0).style("height", 0).style("width", 0).style("overflow-y", "scroll").append("div").style("height", "2000px").node().parentNode;
+ }
+ var e = d3.event, delta;
+ try {
+ d3_behavior_zoomDiv.scrollTop = 1e3;
+ d3_behavior_zoomDiv.dispatchEvent(e);
+ delta = 1e3 - d3_behavior_zoomDiv.scrollTop;
+ } catch (error) {
+ delta = e.wheelDelta || -e.detail * 5;
+ }
+ return delta;
+ }
+ function d3_layout_bundlePath(link) {
+ var start = link.source, end = link.target, lca = d3_layout_bundleLeastCommonAncestor(start, end), points = [ start ];
+ while (start !== lca) {
+ start = start.parent;
+ points.push(start);
+ }
+ var k = points.length;
+ while (end !== lca) {
+ points.splice(k, 0, end);
+ end = end.parent;
+ }
+ return points;
+ }
+ function d3_layout_bundleAncestors(node) {
+ var ancestors = [], parent = node.parent;
+ while (parent != null) {
+ ancestors.push(node);
+ node = parent;
+ parent = parent.parent;
+ }
+ ancestors.push(node);
+ return ancestors;
+ }
+ function d3_layout_bundleLeastCommonAncestor(a, b) {
+ if (a === b) return a;
+ var aNodes = d3_layout_bundleAncestors(a), bNodes = d3_layout_bundleAncestors(b), aNode = aNodes.pop(), bNode = bNodes.pop(), sharedNode = null;
+ while (aNode === bNode) {
+ sharedNode = aNode;
+ aNode = aNodes.pop();
+ bNode = bNodes.pop();
+ }
+ return sharedNode;
+ }
+ function d3_layout_forceDragstart(d) {
+ d.fixed |= 2;
+ }
+ function d3_layout_forceDragend(d) {
+ d.fixed &= 1;
+ }
+ function d3_layout_forceMouseover(d) {
+ d.fixed |= 4;
+ }
+ function d3_layout_forceMouseout(d) {
+ d.fixed &= 3;
+ }
+ function d3_layout_forceAccumulate(quad, alpha, charges) {
+ var cx = 0, cy = 0;
+ quad.charge = 0;
+ if (!quad.leaf) {
+ var nodes = quad.nodes, n = nodes.length, i = -1, c;
+ while (++i < n) {
+ c = nodes[i];
+ if (c == null) continue;
+ d3_layout_forceAccumulate(c, alpha, charges);
+ quad.charge += c.charge;
+ cx += c.charge * c.cx;
+ cy += c.charge * c.cy;
+ }
+ }
+ if (quad.point) {
+ if (!quad.leaf) {
+ quad.point.x += Math.random() - .5;
+ quad.point.y += Math.random() - .5;
+ }
+ var k = alpha * charges[quad.point.index];
+ quad.charge += quad.pointCharge = k;
+ cx += k * quad.point.x;
+ cy += k * quad.point.y;
+ }
+ quad.cx = cx / quad.charge;
+ quad.cy = cy / quad.charge;
+ }
+ function d3_layout_forceLinkDistance(link) {
+ return 20;
+ }
+ function d3_layout_forceLinkStrength(link) {
+ return 1;
+ }
+ function d3_layout_stackX(d) {
+ return d.x;
+ }
+ function d3_layout_stackY(d) {
+ return d.y;
+ }
+ function d3_layout_stackOut(d, y0, y) {
+ d.y0 = y0;
+ d.y = y;
+ }
+ function d3_layout_stackOrderDefault(data) {
+ return d3.range(data.length);
+ }
+ function d3_layout_stackOffsetZero(data) {
+ var j = -1, m = data[0].length, y0 = [];
+ while (++j < m) y0[j] = 0;
+ return y0;
+ }
+ function d3_layout_stackMaxIndex(array) {
+ var i = 1, j = 0, v = array[0][1], k, n = array.length;
+ for (; i < n; ++i) {
+ if ((k = array[i][1]) > v) {
+ j = i;
+ v = k;
+ }
+ }
+ return j;
+ }
+ function d3_layout_stackReduceSum(d) {
+ return d.reduce(d3_layout_stackSum, 0);
+ }
+ function d3_layout_stackSum(p, d) {
+ return p + d[1];
+ }
+ function d3_layout_histogramBinSturges(range, values) {
+ return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1));
+ }
+ function d3_layout_histogramBinFixed(range, n) {
+ var x = -1, b = +range[0], m = (range[1] - b) / n, f = [];
+ while (++x <= n) f[x] = m * x + b;
+ return f;
+ }
+ function d3_layout_histogramRange(values) {
+ return [ d3.min(values), d3.max(values) ];
+ }
+ function d3_layout_hierarchyRebind(object, hierarchy) {
+ d3.rebind(object, hierarchy, "sort", "children", "value");
+ object.links = d3_layout_hierarchyLinks;
+ object.nodes = function(d) {
+ d3_layout_hierarchyInline = true;
+ return (object.nodes = object)(d);
+ };
+ return object;
+ }
+ function d3_layout_hierarchyChildren(d) {
+ return d.children;
+ }
+ function d3_layout_hierarchyValue(d) {
+ return d.value;
+ }
+ function d3_layout_hierarchySort(a, b) {
+ return b.value - a.value;
+ }
+ function d3_layout_hierarchyLinks(nodes) {
+ return d3.merge(nodes.map(function(parent) {
+ return (parent.children || []).map(function(child) {
+ return {
+ source: parent,
+ target: child
+ };
+ });
+ }));
+ }
+ function d3_layout_packSort(a, b) {
+ return a.value - b.value;
+ }
+ function d3_layout_packInsert(a, b) {
+ var c = a._pack_next;
+ a._pack_next = b;
+ b._pack_prev = a;
+ b._pack_next = c;
+ c._pack_prev = b;
+ }
+ function d3_layout_packSplice(a, b) {
+ a._pack_next = b;
+ b._pack_prev = a;
+ }
+ function d3_layout_packIntersects(a, b) {
+ var dx = b.x - a.x, dy = b.y - a.y, dr = a.r + b.r;
+ return dr * dr - dx * dx - dy * dy > .001;
+ }
+ function d3_layout_packSiblings(node) {
+ function bound(node) {
+ xMin = Math.min(node.x - node.r, xMin);
+ xMax = Math.max(node.x + node.r, xMax);
+ yMin = Math.min(node.y - node.r, yMin);
+ yMax = Math.max(node.y + node.r, yMax);
+ }
+ if (!(nodes = node.children) || !(n = nodes.length)) return;
+ var nodes, xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, a, b, c, i, j, k, n;
+ nodes.forEach(d3_layout_packLink);
+ a = nodes[0];
+ a.x = -a.r;
+ a.y = 0;
+ bound(a);
+ if (n > 1) {
+ b = nodes[1];
+ b.x = b.r;
+ b.y = 0;
+ bound(b);
+ if (n > 2) {
+ c = nodes[2];
+ d3_layout_packPlace(a, b, c);
+ bound(c);
+ d3_layout_packInsert(a, c);
+ a._pack_prev = c;
+ d3_layout_packInsert(c, b);
+ b = a._pack_next;
+ for (i = 3; i < n; i++) {
+ d3_layout_packPlace(a, b, c = nodes[i]);
+ var isect = 0, s1 = 1, s2 = 1;
+ for (j = b._pack_next; j !== b; j = j._pack_next, s1++) {
+ if (d3_layout_packIntersects(j, c)) {
+ isect = 1;
+ break;
+ }
+ }
+ if (isect == 1) {
+ for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) {
+ if (d3_layout_packIntersects(k, c)) {
+ break;
+ }
+ }
+ }
+ if (isect) {
+ if (s1 < s2 || s1 == s2 && b.r < a.r) d3_layout_packSplice(a, b = j); else d3_layout_packSplice(a = k, b);
+ i--;
+ } else {
+ d3_layout_packInsert(a, c);
+ b = c;
+ bound(c);
+ }
+ }
+ }
+ }
+ var cx = (xMin + xMax) / 2, cy = (yMin + yMax) / 2, cr = 0;
+ for (i = 0; i < n; i++) {
+ c = nodes[i];
+ c.x -= cx;
+ c.y -= cy;
+ cr = Math.max(cr, c.r + Math.sqrt(c.x * c.x + c.y * c.y));
+ }
+ node.r = cr;
+ nodes.forEach(d3_layout_packUnlink);
+ }
+ function d3_layout_packLink(node) {
+ node._pack_next = node._pack_prev = node;
+ }
+ function d3_layout_packUnlink(node) {
+ delete node._pack_next;
+ delete node._pack_prev;
+ }
+ function d3_layout_packTransform(node, x, y, k) {
+ var children = node.children;
+ node.x = x += k * node.x;
+ node.y = y += k * node.y;
+ node.r *= k;
+ if (children) {
+ var i = -1, n = children.length;
+ while (++i < n) d3_layout_packTransform(children[i], x, y, k);
+ }
+ }
+ function d3_layout_packPlace(a, b, c) {
+ var db = a.r + c.r, dx = b.x - a.x, dy = b.y - a.y;
+ if (db && (dx || dy)) {
+ var da = b.r + c.r, dc = dx * dx + dy * dy;
+ da *= da;
+ db *= db;
+ var x = .5 + (db - da) / (2 * dc), y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc);
+ c.x = a.x + x * dx + y * dy;
+ c.y = a.y + x * dy - y * dx;
+ } else {
+ c.x = a.x + db;
+ c.y = a.y;
+ }
+ }
+ function d3_layout_clusterY(children) {
+ return 1 + d3.max(children, function(child) {
+ return child.y;
+ });
+ }
+ function d3_layout_clusterX(children) {
+ return children.reduce(function(x, child) {
+ return x + child.x;
+ }, 0) / children.length;
+ }
+ function d3_layout_clusterLeft(node) {
+ var children = node.children;
+ return children && children.length ? d3_layout_clusterLeft(children[0]) : node;
+ }
+ function d3_layout_clusterRight(node) {
+ var children = node.children, n;
+ return children && (n = children.length) ? d3_layout_clusterRight(children[n - 1]) : node;
+ }
+ function d3_layout_treeSeparation(a, b) {
+ return a.parent == b.parent ? 1 : 2;
+ }
+ function d3_layout_treeLeft(node) {
+ var children = node.children;
+ return children && children.length ? children[0] : node._tree.thread;
+ }
+ function d3_layout_treeRight(node) {
+ var children = node.children, n;
+ return children && (n = children.length) ? children[n - 1] : node._tree.thread;
+ }
+ function d3_layout_treeSearch(node, compare) {
+ var children = node.children;
+ if (children && (n = children.length)) {
+ var child, n, i = -1;
+ while (++i < n) {
+ if (compare(child = d3_layout_treeSearch(children[i], compare), node) > 0) {
+ node = child;
+ }
+ }
+ }
+ return node;
+ }
+ function d3_layout_treeRightmost(a, b) {
+ return a.x - b.x;
+ }
+ function d3_layout_treeLeftmost(a, b) {
+ return b.x - a.x;
+ }
+ function d3_layout_treeDeepest(a, b) {
+ return a.depth - b.depth;
+ }
+ function d3_layout_treeVisitAfter(node, callback) {
+ function visit(node, previousSibling) {
+ var children = node.children;
+ if (children && (n = children.length)) {
+ var child, previousChild = null, i = -1, n;
+ while (++i < n) {
+ child = children[i];
+ visit(child, previousChild);
+ previousChild = child;
+ }
+ }
+ callback(node, previousSibling);
+ }
+ visit(node, null);
+ }
+ function d3_layout_treeShift(node) {
+ var shift = 0, change = 0, children = node.children, i = children.length, child;
+ while (--i >= 0) {
+ child = children[i]._tree;
+ child.prelim += shift;
+ child.mod += shift;
+ shift += child.shift + (change += child.change);
+ }
+ }
+ function d3_layout_treeMove(ancestor, node, shift) {
+ ancestor = ancestor._tree;
+ node = node._tree;
+ var change = shift / (node.number - ancestor.number);
+ ancestor.change += change;
+ node.change -= change;
+ node.shift += shift;
+ node.prelim += shift;
+ node.mod += shift;
+ }
+ function d3_layout_treeAncestor(vim, node, ancestor) {
+ return vim._tree.ancestor.parent == node.parent ? vim._tree.ancestor : ancestor;
+ }
+ function d3_layout_treemapPadNull(node) {
+ return {
+ x: node.x,
+ y: node.y,
+ dx: node.dx,
+ dy: node.dy
+ };
+ }
+ function d3_layout_treemapPad(node, padding) {
+ var x = node.x + padding[3], y = node.y + padding[0], dx = node.dx - padding[1] - padding[3], dy = node.dy - padding[0] - padding[2];
+ if (dx < 0) {
+ x += dx / 2;
+ dx = 0;
+ }
+ if (dy < 0) {
+ y += dy / 2;
+ dy = 0;
+ }
+ return {
+ x: x,
+ y: y,
+ dx: dx,
+ dy: dy
+ };
+ }
+ function d3_dsv(delimiter, mimeType) {
+ function dsv(url, callback) {
+ d3.text(url, mimeType, function(text) {
+ callback(text && dsv.parse(text));
+ });
+ }
+ function formatRow(row) {
+ return row.map(formatValue).join(delimiter);
+ }
+ function formatValue(text) {
+ return reFormat.test(text) ? '"' + text.replace(/\"/g, '""') + '"' : text;
+ }
+ var reParse = new RegExp("\r\n|[" + delimiter + "\r\n]", "g"), reFormat = new RegExp('["' + delimiter + "\n]"), delimiterCode = delimiter.charCodeAt(0);
+ dsv.parse = function(text) {
+ var header;
+ return dsv.parseRows(text, function(row, i) {
+ if (i) {
+ var o = {}, j = -1, m = header.length;
+ while (++j < m) o[header[j]] = row[j];
+ return o;
+ } else {
+ header = row;
+ return null;
+ }
+ });
+ };
+ dsv.parseRows = function(text, f) {
+ function token() {
+ if (reParse.lastIndex >= text.length) return EOF;
+ if (eol) {
+ eol = false;
+ return EOL;
+ }
+ var j = reParse.lastIndex;
+ if (text.charCodeAt(j) === 34) {
+ var i = j;
+ while (i++ < text.length) {
+ if (text.charCodeAt(i) === 34) {
+ if (text.charCodeAt(i + 1) !== 34) break;
+ i++;
+ }
+ }
+ reParse.lastIndex = i + 2;
+ var c = text.charCodeAt(i + 1);
+ if (c === 13) {
+ eol = true;
+ if (text.charCodeAt(i + 2) === 10) reParse.lastIndex++;
+ } else if (c === 10) {
+ eol = true;
+ }
+ return text.substring(j + 1, i).replace(/""/g, '"');
+ }
+ var m = reParse.exec(text);
+ if (m) {
+ eol = m[0].charCodeAt(0) !== delimiterCode;
+ return text.substring(j, m.index);
+ }
+ reParse.lastIndex = text.length;
+ return text.substring(j);
+ }
+ var EOL = {}, EOF = {}, rows = [], n = 0, t, eol;
+ reParse.lastIndex = 0;
+ while ((t = token()) !== EOF) {
+ var a = [];
+ while (t !== EOL && t !== EOF) {
+ a.push(t);
+ t = token();
+ }
+ if (f && !(a = f(a, n++))) continue;
+ rows.push(a);
+ }
+ return rows;
+ };
+ dsv.format = function(rows) {
+ return rows.map(formatRow).join("\n");
+ };
+ return dsv;
+ }
+ function d3_geo_type(types, defaultValue) {
+ return function(object) {
+ return object && types.hasOwnProperty(object.type) ? types[object.type](object) : defaultValue;
+ };
+ }
+ function d3_path_circle(radius) {
+ return "m0," + radius + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + "a" + radius + "," + radius + " 0 1,1 0," + +2 * radius + "z";
+ }
+ function d3_geo_bounds(o, f) {
+ if (d3_geo_boundsTypes.hasOwnProperty(o.type)) d3_geo_boundsTypes[o.type](o, f);
+ }
+ function d3_geo_boundsFeature(o, f) {
+ d3_geo_bounds(o.geometry, f);
+ }
+ function d3_geo_boundsFeatureCollection(o, f) {
+ for (var a = o.features, i = 0, n = a.length; i < n; i++) {
+ d3_geo_bounds(a[i].geometry, f);
+ }
+ }
+ function d3_geo_boundsGeometryCollection(o, f) {
+ for (var a = o.geometries, i = 0, n = a.length; i < n; i++) {
+ d3_geo_bounds(a[i], f);
+ }
+ }
+ function d3_geo_boundsLineString(o, f) {
+ for (var a = o.coordinates, i = 0, n = a.length; i < n; i++) {
+ f.apply(null, a[i]);
+ }
+ }
+ function d3_geo_boundsMultiLineString(o, f) {
+ for (var a = o.coordinates, i = 0, n = a.length; i < n; i++) {
+ for (var b = a[i], j = 0, m = b.length; j < m; j++) {
+ f.apply(null, b[j]);
+ }
+ }
+ }
+ function d3_geo_boundsMultiPolygon(o, f) {
+ for (var a = o.coordinates, i = 0, n = a.length; i < n; i++) {
+ for (var b = a[i][0], j = 0, m = b.length; j < m; j++) {
+ f.apply(null, b[j]);
+ }
+ }
+ }
+ function d3_geo_boundsPoint(o, f) {
+ f.apply(null, o.coordinates);
+ }
+ function d3_geo_boundsPolygon(o, f) {
+ for (var a = o.coordinates[0], i = 0, n = a.length; i < n; i++) {
+ f.apply(null, a[i]);
+ }
+ }
+ function d3_geo_greatArcSource(d) {
+ return d.source;
+ }
+ function d3_geo_greatArcTarget(d) {
+ return d.target;
+ }
+ function d3_geo_greatArcInterpolator() {
+ function interpolate(t) {
+ var B = Math.sin(t *= d) * k, A = Math.sin(d - t) * k, x = A * kx0 + B * kx1, y = A * ky0 + B * ky1, z = A * sy0 + B * sy1;
+ return [ Math.atan2(y, x) / d3_geo_radians, Math.atan2(z, Math.sqrt(x * x + y * y)) / d3_geo_radians ];
+ }
+ var x0, y0, cy0, sy0, kx0, ky0, x1, y1, cy1, sy1, kx1, ky1, d, k;
+ interpolate.distance = function() {
+ if (d == null) k = 1 / Math.sin(d = Math.acos(Math.max(-1, Math.min(1, sy0 * sy1 + cy0 * cy1 * Math.cos(x1 - x0)))));
+ return d;
+ };
+ interpolate.source = function(_) {
+ var cx0 = Math.cos(x0 = _[0] * d3_geo_radians), sx0 = Math.sin(x0);
+ cy0 = Math.cos(y0 = _[1] * d3_geo_radians);
+ sy0 = Math.sin(y0);
+ kx0 = cy0 * cx0;
+ ky0 = cy0 * sx0;
+ d = null;
+ return interpolate;
+ };
+ interpolate.target = function(_) {
+ var cx1 = Math.cos(x1 = _[0] * d3_geo_radians), sx1 = Math.sin(x1);
+ cy1 = Math.cos(y1 = _[1] * d3_geo_radians);
+ sy1 = Math.sin(y1);
+ kx1 = cy1 * cx1;
+ ky1 = cy1 * sx1;
+ d = null;
+ return interpolate;
+ };
+ return interpolate;
+ }
+ function d3_geo_greatArcInterpolate(a, b) {
+ var i = d3_geo_greatArcInterpolator().source(a).target(b);
+ i.distance();
+ return i;
+ }
+ function d3_geom_contourStart(grid) {
+ var x = 0, y = 0;
+ while (true) {
+ if (grid(x, y)) {
+ return [ x, y ];
+ }
+ if (x === 0) {
+ x = y + 1;
+ y = 0;
+ } else {
+ x = x - 1;
+ y = y + 1;
+ }
+ }
+ }
+ function d3_geom_hullCCW(i1, i2, i3, v) {
+ var t, a, b, c, d, e, f;
+ t = v[i1];
+ a = t[0];
+ b = t[1];
+ t = v[i2];
+ c = t[0];
+ d = t[1];
+ t = v[i3];
+ e = t[0];
+ f = t[1];
+ return (f - b) * (c - a) - (d - b) * (e - a) > 0;
+ }
+ function d3_geom_polygonInside(p, a, b) {
+ return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]);
+ }
+ function d3_geom_polygonIntersect(c, d, a, b) {
+ var x1 = c[0], x2 = d[0], x3 = a[0], x4 = b[0], y1 = c[1], y2 = d[1], y3 = a[1], y4 = b[1], x13 = x1 - x3, x21 = x2 - x1, x43 = x4 - x3, y13 = y1 - y3, y21 = y2 - y1, y43 = y4 - y3, ua = (x43 * y13 - y43 * x13) / (y43 * x21 - x43 * y21);
+ return [ x1 + ua * x21, y1 + ua * y21 ];
+ }
+ function d3_voronoi_tessellate(vertices, callback) {
+ var Sites = {
+ list: vertices.map(function(v, i) {
+ return {
+ index: i,
+ x: v[0],
+ y: v[1]
+ };
+ }).sort(function(a, b) {
+ return a.y < b.y ? -1 : a.y > b.y ? 1 : a.x < b.x ? -1 : a.x > b.x ? 1 : 0;
+ }),
+ bottomSite: null
+ };
+ var EdgeList = {
+ list: [],
+ leftEnd: null,
+ rightEnd: null,
+ init: function() {
+ EdgeList.leftEnd = EdgeList.createHalfEdge(null, "l");
+ EdgeList.rightEnd = EdgeList.createHalfEdge(null, "l");
+ EdgeList.leftEnd.r = EdgeList.rightEnd;
+ EdgeList.rightEnd.l = EdgeList.leftEnd;
+ EdgeList.list.unshift(EdgeList.leftEnd, EdgeList.rightEnd);
+ },
+ createHalfEdge: function(edge, side) {
+ return {
+ edge: edge,
+ side: side,
+ vertex: null,
+ l: null,
+ r: null
+ };
+ },
+ insert: function(lb, he) {
+ he.l = lb;
+ he.r = lb.r;
+ lb.r.l = he;
+ lb.r = he;
+ },
+ leftBound: function(p) {
+ var he = EdgeList.leftEnd;
+ do {
+ he = he.r;
+ } while (he != EdgeList.rightEnd && Geom.rightOf(he, p));
+ he = he.l;
+ return he;
+ },
+ del: function(he) {
+ he.l.r = he.r;
+ he.r.l = he.l;
+ he.edge = null;
+ },
+ right: function(he) {
+ return he.r;
+ },
+ left: function(he) {
+ return he.l;
+ },
+ leftRegion: function(he) {
+ return he.edge == null ? Sites.bottomSite : he.edge.region[he.side];
+ },
+ rightRegion: function(he) {
+ return he.edge == null ? Sites.bottomSite : he.edge.region[d3_voronoi_opposite[he.side]];
+ }
+ };
+ var Geom = {
+ bisect: function(s1, s2) {
+ var newEdge = {
+ region: {
+ l: s1,
+ r: s2
+ },
+ ep: {
+ l: null,
+ r: null
+ }
+ };
+ var dx = s2.x - s1.x, dy = s2.y - s1.y, adx = dx > 0 ? dx : -dx, ady = dy > 0 ? dy : -dy;
+ newEdge.c = s1.x * dx + s1.y * dy + (dx * dx + dy * dy) * .5;
+ if (adx > ady) {
+ newEdge.a = 1;
+ newEdge.b = dy / dx;
+ newEdge.c /= dx;
+ } else {
+ newEdge.b = 1;
+ newEdge.a = dx / dy;
+ newEdge.c /= dy;
+ }
+ return newEdge;
+ },
+ intersect: function(el1, el2) {
+ var e1 = el1.edge, e2 = el2.edge;
+ if (!e1 || !e2 || e1.region.r == e2.region.r) {
+ return null;
+ }
+ var d = e1.a * e2.b - e1.b * e2.a;
+ if (Math.abs(d) < 1e-10) {
+ return null;
+ }
+ var xint = (e1.c * e2.b - e2.c * e1.b) / d, yint = (e2.c * e1.a - e1.c * e2.a) / d, e1r = e1.region.r, e2r = e2.region.r, el, e;
+ if (e1r.y < e2r.y || e1r.y == e2r.y && e1r.x < e2r.x) {
+ el = el1;
+ e = e1;
+ } else {
+ el = el2;
+ e = e2;
+ }
+ var rightOfSite = xint >= e.region.r.x;
+ if (rightOfSite && el.side === "l" || !rightOfSite && el.side === "r") {
+ return null;
+ }
+ return {
+ x: xint,
+ y: yint
+ };
+ },
+ rightOf: function(he, p) {
+ var e = he.edge, topsite = e.region.r, rightOfSite = p.x > topsite.x;
+ if (rightOfSite && he.side === "l") {
+ return 1;
+ }
+ if (!rightOfSite && he.side === "r") {
+ return 0;
+ }
+ if (e.a === 1) {
+ var dyp = p.y - topsite.y, dxp = p.x - topsite.x, fast = 0, above = 0;
+ if (!rightOfSite && e.b < 0 || rightOfSite && e.b >= 0) {
+ above = fast = dyp >= e.b * dxp;
+ } else {
+ above = p.x + p.y * e.b > e.c;
+ if (e.b < 0) {
+ above = !above;
+ }
+ if (!above) {
+ fast = 1;
+ }
+ }
+ if (!fast) {
+ var dxs = topsite.x - e.region.l.x;
+ above = e.b * (dxp * dxp - dyp * dyp) < dxs * dyp * (1 + 2 * dxp / dxs + e.b * e.b);
+ if (e.b < 0) {
+ above = !above;
+ }
+ }
+ } else {
+ var yl = e.c - e.a * p.x, t1 = p.y - yl, t2 = p.x - topsite.x, t3 = yl - topsite.y;
+ above = t1 * t1 > t2 * t2 + t3 * t3;
+ }
+ return he.side === "l" ? above : !above;
+ },
+ endPoint: function(edge, side, site) {
+ edge.ep[side] = site;
+ if (!edge.ep[d3_voronoi_opposite[side]]) return;
+ callback(edge);
+ },
+ distance: function(s, t) {
+ var dx = s.x - t.x, dy = s.y - t.y;
+ return Math.sqrt(dx * dx + dy * dy);
+ }
+ };
+ var EventQueue = {
+ list: [],
+ insert: function(he, site, offset) {
+ he.vertex = site;
+ he.ystar = site.y + offset;
+ for (var i = 0, list = EventQueue.list, l = list.length; i < l; i++) {
+ var next = list[i];
+ if (he.ystar > next.ystar || he.ystar == next.ystar && site.x > next.vertex.x) {
+ continue;
+ } else {
+ break;
+ }
+ }
+ list.splice(i, 0, he);
+ },
+ del: function(he) {
+ for (var i = 0, ls = EventQueue.list, l = ls.length; i < l && ls[i] != he; ++i) {}
+ ls.splice(i, 1);
+ },
+ empty: function() {
+ return EventQueue.list.length === 0;
+ },
+ nextEvent: function(he) {
+ for (var i = 0, ls = EventQueue.list, l = ls.length; i < l; ++i) {
+ if (ls[i] == he) return ls[i + 1];
+ }
+ return null;
+ },
+ min: function() {
+ var elem = EventQueue.list[0];
+ return {
+ x: elem.vertex.x,
+ y: elem.ystar
+ };
+ },
+ extractMin: function() {
+ return EventQueue.list.shift();
+ }
+ };
+ EdgeList.init();
+ Sites.bottomSite = Sites.list.shift();
+ var newSite = Sites.list.shift(), newIntStar;
+ var lbnd, rbnd, llbnd, rrbnd, bisector;
+ var bot, top, temp, p, v;
+ var e, pm;
+ while (true) {
+ if (!EventQueue.empty()) {
+ newIntStar = EventQueue.min();
+ }
+ if (newSite && (EventQueue.empty() || newSite.y < newIntStar.y || newSite.y == newIntStar.y && newSite.x < newIntStar.x)) {
+ lbnd = EdgeList.leftBound(newSite);
+ rbnd = EdgeList.right(lbnd);
+ bot = EdgeList.rightRegion(lbnd);
+ e = Geom.bisect(bot, newSite);
+ bisector = EdgeList.createHalfEdge(e, "l");
+ EdgeList.insert(lbnd, bisector);
+ p = Geom.intersect(lbnd, bisector);
+ if (p) {
+ EventQueue.del(lbnd);
+ EventQueue.insert(lbnd, p, Geom.distance(p, newSite));
+ }
+ lbnd = bisector;
+ bisector = EdgeList.createHalfEdge(e, "r");
+ EdgeList.insert(lbnd, bisector);
+ p = Geom.intersect(bisector, rbnd);
+ if (p) {
+ EventQueue.insert(bisector, p, Geom.distance(p, newSite));
+ }
+ newSite = Sites.list.shift();
+ } else if (!EventQueue.empty()) {
+ lbnd = EventQueue.extractMin();
+ llbnd = EdgeList.left(lbnd);
+ rbnd = EdgeList.right(lbnd);
+ rrbnd = EdgeList.right(rbnd);
+ bot = EdgeList.leftRegion(lbnd);
+ top = EdgeList.rightRegion(rbnd);
+ v = lbnd.vertex;
+ Geom.endPoint(lbnd.edge, lbnd.side, v);
+ Geom.endPoint(rbnd.edge, rbnd.side, v);
+ EdgeList.del(lbnd);
+ EventQueue.del(rbnd);
+ EdgeList.del(rbnd);
+ pm = "l";
+ if (bot.y > top.y) {
+ temp = bot;
+ bot = top;
+ top = temp;
+ pm = "r";
+ }
+ e = Geom.bisect(bot, top);
+ bisector = EdgeList.createHalfEdge(e, pm);
+ EdgeList.insert(llbnd, bisector);
+ Geom.endPoint(e, d3_voronoi_opposite[pm], v);
+ p = Geom.intersect(llbnd, bisector);
+ if (p) {
+ EventQueue.del(llbnd);
+ EventQueue.insert(llbnd, p, Geom.distance(p, bot));
+ }
+ p = Geom.intersect(bisector, rrbnd);
+ if (p) {
+ EventQueue.insert(bisector, p, Geom.distance(p, bot));
+ }
+ } else {
+ break;
+ }
+ }
+ for (lbnd = EdgeList.right(EdgeList.leftEnd); lbnd != EdgeList.rightEnd; lbnd = EdgeList.right(lbnd)) {
+ callback(lbnd.edge);
+ }
+ }
+ function d3_geom_quadtreeNode() {
+ return {
+ leaf: true,
+ nodes: [],
+ point: null
+ };
+ }
+ function d3_geom_quadtreeVisit(f, node, x1, y1, x2, y2) {
+ if (!f(node, x1, y1, x2, y2)) {
+ var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, children = node.nodes;
+ if (children[0]) d3_geom_quadtreeVisit(f, children[0], x1, y1, sx, sy);
+ if (children[1]) d3_geom_quadtreeVisit(f, children[1], sx, y1, x2, sy);
+ if (children[2]) d3_geom_quadtreeVisit(f, children[2], x1, sy, sx, y2);
+ if (children[3]) d3_geom_quadtreeVisit(f, children[3], sx, sy, x2, y2);
+ }
+ }
+ function d3_geom_quadtreePoint(p) {
+ return {
+ x: p[0],
+ y: p[1]
+ };
+ }
+ function d3_time_utc() {
+ this._ = new Date(arguments.length > 1 ? Date.UTC.apply(this, arguments) : arguments[0]);
+ }
+ function d3_time_formatAbbreviate(name) {
+ return name.substring(0, 3);
+ }
+ function d3_time_parse(date, template, string, j) {
+ var c, p, i = 0, n = template.length, m = string.length;
+ while (i < n) {
+ if (j >= m) return -1;
+ c = template.charCodeAt(i++);
+ if (c == 37) {
+ p = d3_time_parsers[template.charAt(i++)];
+ if (!p || (j = p(date, string, j)) < 0) return -1;
+ } else if (c != string.charCodeAt(j++)) {
+ return -1;
+ }
+ }
+ return j;
+ }
+ function d3_time_formatRe(names) {
+ return new RegExp("^(?:" + names.map(d3.requote).join("|") + ")", "i");
+ }
+ function d3_time_formatLookup(names) {
+ var map = new d3_Map, i = -1, n = names.length;
+ while (++i < n) map.set(names[i].toLowerCase(), i);
+ return map;
+ }
+ function d3_time_parseWeekdayAbbrev(date, string, i) {
+ d3_time_dayAbbrevRe.lastIndex = 0;
+ var n = d3_time_dayAbbrevRe.exec(string.substring(i));
+ return n ? i += n[0].length : -1;
+ }
+ function d3_time_parseWeekday(date, string, i) {
+ d3_time_dayRe.lastIndex = 0;
+ var n = d3_time_dayRe.exec(string.substring(i));
+ return n ? i += n[0].length : -1;
+ }
+ function d3_time_parseMonthAbbrev(date, string, i) {
+ d3_time_monthAbbrevRe.lastIndex = 0;
+ var n = d3_time_monthAbbrevRe.exec(string.substring(i));
+ return n ? (date.m = d3_time_monthAbbrevLookup.get(n[0].toLowerCase()), i += n[0].length) : -1;
+ }
+ function d3_time_parseMonth(date, string, i) {
+ d3_time_monthRe.lastIndex = 0;
+ var n = d3_time_monthRe.exec(string.substring(i));
+ return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i += n[0].length) : -1;
+ }
+ function d3_time_parseLocaleFull(date, string, i) {
+ return d3_time_parse(date, d3_time_formats.c.toString(), string, i);
+ }
+ function d3_time_parseLocaleDate(date, string, i) {
+ return d3_time_parse(date, d3_time_formats.x.toString(), string, i);
+ }
+ function d3_time_parseLocaleTime(date, string, i) {
+ return d3_time_parse(date, d3_time_formats.X.toString(), string, i);
+ }
+ function d3_time_parseFullYear(date, string, i) {
+ d3_time_numberRe.lastIndex = 0;
+ var n = d3_time_numberRe.exec(string.substring(i, i + 4));
+ return n ? (date.y = +n[0], i += n[0].length) : -1;
+ }
+ function d3_time_parseYear(date, string, i) {
+ d3_time_numberRe.lastIndex = 0;
+ var n = d3_time_numberRe.exec(string.substring(i, i + 2));
+ return n ? (date.y = d3_time_expandYear(+n[0]), i += n[0].length) : -1;
+ }
+ function d3_time_expandYear(d) {
+ return d + (d > 68 ? 1900 : 2e3);
+ }
+ function d3_time_parseMonthNumber(date, string, i) {
+ d3_time_numberRe.lastIndex = 0;
+ var n = d3_time_numberRe.exec(string.substring(i, i + 2));
+ return n ? (date.m = n[0] - 1, i += n[0].length) : -1;
+ }
+ function d3_time_parseDay(date, string, i) {
+ d3_time_numberRe.lastIndex = 0;
+ var n = d3_time_numberRe.exec(string.substring(i, i + 2));
+ return n ? (date.d = +n[0], i += n[0].length) : -1;
+ }
+ function d3_time_parseHour24(date, string, i) {
+ d3_time_numberRe.lastIndex = 0;
+ var n = d3_time_numberRe.exec(string.substring(i, i + 2));
+ return n ? (date.H = +n[0], i += n[0].length) : -1;
+ }
+ function d3_time_parseMinutes(date, string, i) {
+ d3_time_numberRe.lastIndex = 0;
+ var n = d3_time_numberRe.exec(string.substring(i, i + 2));
+ return n ? (date.M = +n[0], i += n[0].length) : -1;
+ }
+ function d3_time_parseSeconds(date, string, i) {
+ d3_time_numberRe.lastIndex = 0;
+ var n = d3_time_numberRe.exec(string.substring(i, i + 2));
+ return n ? (date.S = +n[0], i += n[0].length) : -1;
+ }
+ function d3_time_parseMilliseconds(date, string, i) {
+ d3_time_numberRe.lastIndex = 0;
+ var n = d3_time_numberRe.exec(string.substring(i, i + 3));
+ return n ? (date.L = +n[0], i += n[0].length) : -1;
+ }
+ function d3_time_parseAmPm(date, string, i) {
+ var n = d3_time_amPmLookup.get(string.substring(i, i += 2).toLowerCase());
+ return n == null ? -1 : (date.p = n, i);
+ }
+ function d3_time_zone(d) {
+ var z = d.getTimezoneOffset(), zs = z > 0 ? "-" : "+", zh = ~~(Math.abs(z) / 60), zm = Math.abs(z) % 60;
+ return zs + d3_time_zfill2(zh) + d3_time_zfill2(zm);
+ }
+ function d3_time_formatIsoNative(date) {
+ return date.toISOString();
+ }
+ function d3_time_interval(local, step, number) {
+ function round(date) {
+ var d0 = local(date), d1 = offset(d0, 1);
+ return date - d0 < d1 - date ? d0 : d1;
+ }
+ function ceil(date) {
+ step(date = local(new d3_time(date - 1)), 1);
+ return date;
+ }
+ function offset(date, k) {
+ step(date = new d3_time(+date), k);
+ return date;
+ }
+ function range(t0, t1, dt) {
+ var time = ceil(t0), times = [];
+ if (dt > 1) {
+ while (time < t1) {
+ if (!(number(time) % dt)) times.push(new Date(+time));
+ step(time, 1);
+ }
+ } else {
+ while (time < t1) times.push(new Date(+time)), step(time, 1);
+ }
+ return times;
+ }
+ function range_utc(t0, t1, dt) {
+ try {
+ d3_time = d3_time_utc;
+ var utc = new d3_time_utc;
+ utc._ = t0;
+ return range(utc, t1, dt);
+ } finally {
+ d3_time = Date;
+ }
+ }
+ local.floor = local;
+ local.round = round;
+ local.ceil = ceil;
+ local.offset = offset;
+ local.range = range;
+ var utc = local.utc = d3_time_interval_utc(local);
+ utc.floor = utc;
+ utc.round = d3_time_interval_utc(round);
+ utc.ceil = d3_time_interval_utc(ceil);
+ utc.offset = d3_time_interval_utc(offset);
+ utc.range = range_utc;
+ return local;
+ }
+ function d3_time_interval_utc(method) {
+ return function(date, k) {
+ try {
+ d3_time = d3_time_utc;
+ var utc = new d3_time_utc;
+ utc._ = date;
+ return method(utc, k)._;
+ } finally {
+ d3_time = Date;
+ }
+ };
+ }
+ function d3_time_scale(linear, methods, format) {
+ function scale(x) {
+ return linear(x);
+ }
+ scale.invert = function(x) {
+ return d3_time_scaleDate(linear.invert(x));
+ };
+ scale.domain = function(x) {
+ if (!arguments.length) return linear.domain().map(d3_time_scaleDate);
+ linear.domain(x);
+ return scale;
+ };
+ scale.nice = function(m) {
+ return scale.domain(d3_scale_nice(scale.domain(), function() {
+ return m;
+ }));
+ };
+ scale.ticks = function(m, k) {
+ var extent = d3_time_scaleExtent(scale.domain());
+ if (typeof m !== "function") {
+ var span = extent[1] - extent[0], target = span / m, i = d3.bisect(d3_time_scaleSteps, target);
+ if (i == d3_time_scaleSteps.length) return methods.year(extent, m);
+ if (!i) return linear.ticks(m).map(d3_time_scaleDate);
+ if (Math.log(target / d3_time_scaleSteps[i - 1]) < Math.log(d3_time_scaleSteps[i] / target)) --i;
+ m = methods[i];
+ k = m[1];
+ m = m[0].range;
+ }
+ return m(extent[0], new Date(+extent[1] + 1), k);
+ };
+ scale.tickFormat = function() {
+ return format;
+ };
+ scale.copy = function() {
+ return d3_time_scale(linear.copy(), methods, format);
+ };
+ return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp");
+ }
+ function d3_time_scaleExtent(domain) {
+ var start = domain[0], stop = domain[domain.length - 1];
+ return start < stop ? [ start, stop ] : [ stop, start ];
+ }
+ function d3_time_scaleDate(t) {
+ return new Date(t);
+ }
+ function d3_time_scaleFormat(formats) {
+ return function(date) {
+ var i = formats.length - 1, f = formats[i];
+ while (!f[1](date)) f = formats[--i];
+ return f[0](date);
+ };
+ }
+ function d3_time_scaleSetYear(y) {
+ var d = new Date(y, 0, 1);
+ d.setFullYear(y);
+ return d;
+ }
+ function d3_time_scaleGetYear(d) {
+ var y = d.getFullYear(), d0 = d3_time_scaleSetYear(y), d1 = d3_time_scaleSetYear(y + 1);
+ return y + (d - d0) / (d1 - d0);
+ }
+ function d3_time_scaleUTCSetYear(y) {
+ var d = new Date(Date.UTC(y, 0, 1));
+ d.setUTCFullYear(y);
+ return d;
+ }
+ function d3_time_scaleUTCGetYear(d) {
+ var y = d.getUTCFullYear(), d0 = d3_time_scaleUTCSetYear(y), d1 = d3_time_scaleUTCSetYear(y + 1);
+ return y + (d - d0) / (d1 - d0);
+ }
+ if (!Date.now) Date.now = function() {
+ return +(new Date);
+ };
+ try {
+ document.createElement("div").style.setProperty("opacity", 0, "");
+ } catch (error) {
+ var d3_style_prototype = CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty;
+ d3_style_prototype.setProperty = function(name, value, priority) {
+ d3_style_setProperty.call(this, name, value + "", priority);
+ };
+ }
+ d3 = {
+ version: "2.10.2"
+ };
+ var d3_array = d3_arraySlice;
+ try {
+ d3_array(document.documentElement.childNodes)[0].nodeType;
+ } catch (e) {
+ d3_array = d3_arrayCopy;
+ }
+ var d3_arraySubclass = [].__proto__ ? function(array, prototype) {
+ array.__proto__ = prototype;
+ } : function(array, prototype) {
+ for (var property in prototype) array[property] = prototype[property];
+ };
+ d3.map = function(object) {
+ var map = new d3_Map;
+ for (var key in object) map.set(key, object[key]);
+ return map;
+ };
+ d3_class(d3_Map, {
+ has: function(key) {
+ return d3_map_prefix + key in this;
+ },
+ get: function(key) {
+ return this[d3_map_prefix + key];
+ },
+ set: function(key, value) {
+ return this[d3_map_prefix + key] = value;
+ },
+ remove: function(key) {
+ key = d3_map_prefix + key;
+ return key in this && delete this[key];
+ },
+ keys: function() {
+ var keys = [];
+ this.forEach(function(key) {
+ keys.push(key);
+ });
+ return keys;
+ },
+ values: function() {
+ var values = [];
+ this.forEach(function(key, value) {
+ values.push(value);
+ });
+ return values;
+ },
+ entries: function() {
+ var entries = [];
+ this.forEach(function(key, value) {
+ entries.push({
+ key: key,
+ value: value
+ });
+ });
+ return entries;
+ },
+ forEach: function(f) {
+ for (var key in this) {
+ if (key.charCodeAt(0) === d3_map_prefixCode) {
+ f.call(this, key.substring(1), this[key]);
+ }
+ }
+ }
+ });
+ var d3_map_prefix = "\0", d3_map_prefixCode = d3_map_prefix.charCodeAt(0);
+ d3.functor = d3_functor;
+ d3.rebind = function(target, source) {
+ var i = 1, n = arguments.length, method;
+ while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]);
+ return target;
+ };
+ d3.ascending = function(a, b) {
+ return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
+ };
+ d3.descending = function(a, b) {
+ return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
+ };
+ d3.mean = function(array, f) {
+ var n = array.length, a, m = 0, i = -1, j = 0;
+ if (arguments.length === 1) {
+ while (++i < n) if (d3_number(a = array[i])) m += (a - m) / ++j;
+ } else {
+ while (++i < n) if (d3_number(a = f.call(array, array[i], i))) m += (a - m) / ++j;
+ }
+ return j ? m : undefined;
+ };
+ d3.median = function(array, f) {
+ if (arguments.length > 1) array = array.map(f);
+ array = array.filter(d3_number);
+ return array.length ? d3.quantile(array.sort(d3.ascending), .5) : undefined;
+ };
+ d3.min = function(array, f) {
+ var i = -1, n = array.length, a, b;
+ if (arguments.length === 1) {
+ while (++i < n && ((a = array[i]) == null || a != a)) a = undefined;
+ while (++i < n) if ((b = array[i]) != null && a > b) a = b;
+ } else {
+ while (++i < n && ((a = f.call(array, array[i], i)) == null || a != a)) a = undefined;
+ while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b;
+ }
+ return a;
+ };
+ d3.max = function(array, f) {
+ var i = -1, n = array.length, a, b;
+ if (arguments.length === 1) {
+ while (++i < n && ((a = array[i]) == null || a != a)) a = undefined;
+ while (++i < n) if ((b = array[i]) != null && b > a) a = b;
+ } else {
+ while (++i < n && ((a = f.call(array, array[i], i)) == null || a != a)) a = undefined;
+ while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b;
+ }
+ return a;
+ };
+ d3.extent = function(array, f) {
+ var i = -1, n = array.length, a, b, c;
+ if (arguments.length === 1) {
+ while (++i < n && ((a = c = array[i]) == null || a != a)) a = c = undefined;
+ while (++i < n) if ((b = array[i]) != null) {
+ if (a > b) a = b;
+ if (c < b) c = b;
+ }
+ } else {
+ while (++i < n && ((a = c = f.call(array, array[i], i)) == null || a != a)) a = undefined;
+ while (++i < n) if ((b = f.call(array, array[i], i)) != null) {
+ if (a > b) a = b;
+ if (c < b) c = b;
+ }
+ }
+ return [ a, c ];
+ };
+ d3.random = {
+ normal: function(µ, σ) {
+ var n = a
<TRUNCATED>
[2/8] AMBARI-5928. Create and populate Metrics section of a slider
app. (onechiporenko)
Posted by on...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/rickshaw.js
----------------------------------------------------------------------
diff --git a/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/rickshaw.js b/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/rickshaw.js
new file mode 100644
index 0000000..6beb828
--- /dev/null
+++ b/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/rickshaw.js
@@ -0,0 +1,2659 @@
+var Rickshaw = {
+
+ namespace: function(namespace, obj) {
+
+ var parts = namespace.split('.');
+
+ var parent = Rickshaw;
+
+ for(var i = 1, length = parts.length; i < length; i++) {
+ currentPart = parts[i];
+ parent[currentPart] = parent[currentPart] || {};
+ parent = parent[currentPart];
+ }
+ return parent;
+ },
+
+ keys: function(obj) {
+ var keys = [];
+ for (var key in obj) keys.push(key);
+ return keys;
+ },
+
+ extend: function(destination, source) {
+
+ for (var property in source) {
+ destination[property] = source[property];
+ }
+ return destination;
+ }
+};
+
+if (typeof module !== 'undefined' && module.exports) {
+ var d3 = require('d3');
+ module.exports = Rickshaw;
+}
+
+/* Adapted from https://github.com/Jakobo/PTClass */
+
+/*
+Copyright (c) 2005-2010 Sam Stephenson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+/* Based on Alex Arnell's inheritance implementation. */
+/** section: Language
+ * class Class
+ *
+ * Manages Prototype's class-based OOP system.
+ *
+ * Refer to Prototype's web site for a [tutorial on classes and
+ * inheritance](http://prototypejs.org/learn/class-inheritance).
+**/
+(function(globalContext) {
+/* ------------------------------------ */
+/* Import from object.js */
+/* ------------------------------------ */
+var _toString = Object.prototype.toString,
+ NULL_TYPE = 'Null',
+ UNDEFINED_TYPE = 'Undefined',
+ BOOLEAN_TYPE = 'Boolean',
+ NUMBER_TYPE = 'Number',
+ STRING_TYPE = 'String',
+ OBJECT_TYPE = 'Object',
+ FUNCTION_CLASS = '[object Function]';
+function isFunction(object) {
+ return _toString.call(object) === FUNCTION_CLASS;
+}
+function extend(destination, source) {
+ for (var property in source) if (source.hasOwnProperty(property)) // modify protect primitive slaughter
+ destination[property] = source[property];
+ return destination;
+}
+function keys(object) {
+ if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); }
+ var results = [];
+ for (var property in object) {
+ if (object.hasOwnProperty(property)) {
+ results.push(property);
+ }
+ }
+ return results;
+}
+function Type(o) {
+ switch(o) {
+ case null: return NULL_TYPE;
+ case (void 0): return UNDEFINED_TYPE;
+ }
+ var type = typeof o;
+ switch(type) {
+ case 'boolean': return BOOLEAN_TYPE;
+ case 'number': return NUMBER_TYPE;
+ case 'string': return STRING_TYPE;
+ }
+ return OBJECT_TYPE;
+}
+function isUndefined(object) {
+ return typeof object === "undefined";
+}
+/* ------------------------------------ */
+/* Import from Function.js */
+/* ------------------------------------ */
+var slice = Array.prototype.slice;
+function argumentNames(fn) {
+ var names = fn.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
+ .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
+ .replace(/\s+/g, '').split(',');
+ return names.length == 1 && !names[0] ? [] : names;
+}
+function wrap(fn, wrapper) {
+ var __method = fn;
+ return function() {
+ var a = update([bind(__method, this)], arguments);
+ return wrapper.apply(this, a);
+ }
+}
+function update(array, args) {
+ var arrayLength = array.length, length = args.length;
+ while (length--) array[arrayLength + length] = args[length];
+ return array;
+}
+function merge(array, args) {
+ array = slice.call(array, 0);
+ return update(array, args);
+}
+function bind(fn, context) {
+ if (arguments.length < 2 && isUndefined(arguments[0])) return this;
+ var __method = fn, args = slice.call(arguments, 2);
+ return function() {
+ var a = merge(args, arguments);
+ return __method.apply(context, a);
+ }
+}
+
+/* ------------------------------------ */
+/* Import from Prototype.js */
+/* ------------------------------------ */
+var emptyFunction = function(){};
+
+var Class = (function() {
+
+ // Some versions of JScript fail to enumerate over properties, names of which
+ // correspond to non-enumerable properties in the prototype chain
+ var IS_DONTENUM_BUGGY = (function(){
+ for (var p in { toString: 1 }) {
+ // check actual property name, so that it works with augmented Object.prototype
+ if (p === 'toString') return false;
+ }
+ return true;
+ })();
+
+ function subclass() {};
+ function create() {
+ var parent = null, properties = [].slice.apply(arguments);
+ if (isFunction(properties[0]))
+ parent = properties.shift();
+
+ function klass() {
+ this.initialize.apply(this, arguments);
+ }
+
+ extend(klass, Class.Methods);
+ klass.superclass = parent;
+ klass.subclasses = [];
+
+ if (parent) {
+ subclass.prototype = parent.prototype;
+ klass.prototype = new subclass;
+ try { parent.subclasses.push(klass) } catch(e) {}
+ }
+
+ for (var i = 0, length = properties.length; i < length; i++)
+ klass.addMethods(properties[i]);
+
+ if (!klass.prototype.initialize)
+ klass.prototype.initialize = emptyFunction;
+
+ klass.prototype.constructor = klass;
+ return klass;
+ }
+
+ function addMethods(source) {
+ var ancestor = this.superclass && this.superclass.prototype,
+ properties = keys(source);
+
+ // IE6 doesn't enumerate `toString` and `valueOf` (among other built-in `Object.prototype`) properties,
+ // Force copy if they're not Object.prototype ones.
+ // Do not copy other Object.prototype.* for performance reasons
+ if (IS_DONTENUM_BUGGY) {
+ if (source.toString != Object.prototype.toString)
+ properties.push("toString");
+ if (source.valueOf != Object.prototype.valueOf)
+ properties.push("valueOf");
+ }
+
+ for (var i = 0, length = properties.length; i < length; i++) {
+ var property = properties[i], value = source[property];
+ if (ancestor && isFunction(value) &&
+ argumentNames(value)[0] == "$super") {
+ var method = value;
+ value = wrap((function(m) {
+ return function() { return ancestor[m].apply(this, arguments); };
+ })(property), method);
+
+ value.valueOf = bind(method.valueOf, method);
+ value.toString = bind(method.toString, method);
+ }
+ this.prototype[property] = value;
+ }
+
+ return this;
+ }
+
+ return {
+ create: create,
+ Methods: {
+ addMethods: addMethods
+ }
+ };
+})();
+
+if (globalContext.exports) {
+ globalContext.exports.Class = Class;
+}
+else {
+ globalContext.Class = Class;
+}
+})(Rickshaw);
+Rickshaw.namespace('Rickshaw.Compat.ClassList');
+
+Rickshaw.Compat.ClassList = function() {
+
+ /* adapted from http://purl.eligrey.com/github/classList.js/blob/master/classList.js */
+
+ if (typeof document !== "undefined" && !("classList" in document.createElement("a"))) {
+
+ (function (view) {
+
+ "use strict";
+
+ var
+ classListProp = "classList"
+ , protoProp = "prototype"
+ , elemCtrProto = (view.HTMLElement || view.Element)[protoProp]
+ , objCtr = Object
+ , strTrim = String[protoProp].trim || function () {
+ return this.replace(/^\s+|\s+$/g, "");
+ }
+ , arrIndexOf = Array[protoProp].indexOf || function (item) {
+ var
+ i = 0
+ , len = this.length
+ ;
+ for (; i < len; i++) {
+ if (i in this && this[i] === item) {
+ return i;
+ }
+ }
+ return -1;
+ }
+ // Vendors: please allow content code to instantiate DOMExceptions
+ , DOMEx = function (type, message) {
+ this.name = type;
+ this.code = DOMException[type];
+ this.message = message;
+ }
+ , checkTokenAndGetIndex = function (classList, token) {
+ if (token === "") {
+ throw new DOMEx(
+ "SYNTAX_ERR"
+ , "An invalid or illegal string was specified"
+ );
+ }
+ if (/\s/.test(token)) {
+ throw new DOMEx(
+ "INVALID_CHARACTER_ERR"
+ , "String contains an invalid character"
+ );
+ }
+ return arrIndexOf.call(classList, token);
+ }
+ , ClassList = function (elem) {
+ var
+ trimmedClasses = strTrim.call(elem.className)
+ , classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
+ , i = 0
+ , len = classes.length
+ ;
+ for (; i < len; i++) {
+ this.push(classes[i]);
+ }
+ this._updateClassName = function () {
+ elem.className = this.toString();
+ };
+ }
+ , classListProto = ClassList[protoProp] = []
+ , classListGetter = function () {
+ return new ClassList(this);
+ }
+ ;
+ // Most DOMException implementations don't allow calling DOMException's toString()
+ // on non-DOMExceptions. Error's toString() is sufficient here.
+ DOMEx[protoProp] = Error[protoProp];
+ classListProto.item = function (i) {
+ return this[i] || null;
+ };
+ classListProto.contains = function (token) {
+ token += "";
+ return checkTokenAndGetIndex(this, token) !== -1;
+ };
+ classListProto.add = function (token) {
+ token += "";
+ if (checkTokenAndGetIndex(this, token) === -1) {
+ this.push(token);
+ this._updateClassName();
+ }
+ };
+ classListProto.remove = function (token) {
+ token += "";
+ var index = checkTokenAndGetIndex(this, token);
+ if (index !== -1) {
+ this.splice(index, 1);
+ this._updateClassName();
+ }
+ };
+ classListProto.toggle = function (token) {
+ token += "";
+ if (checkTokenAndGetIndex(this, token) === -1) {
+ this.add(token);
+ } else {
+ this.remove(token);
+ }
+ };
+ classListProto.toString = function () {
+ return this.join(" ");
+ };
+
+ if (objCtr.defineProperty) {
+ var classListPropDesc = {
+ get: classListGetter
+ , enumerable: true
+ , configurable: true
+ };
+ try {
+ objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
+ } catch (ex) { // IE 8 doesn't support enumerable:true
+ if (ex.number === -0x7FF5EC54) {
+ classListPropDesc.enumerable = false;
+ objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
+ }
+ }
+ } else if (objCtr[protoProp].__defineGetter__) {
+ elemCtrProto.__defineGetter__(classListProp, classListGetter);
+ }
+
+ }(window));
+
+ }
+};
+
+if ( (typeof RICKSHAW_NO_COMPAT !== "undefined" && !RICKSHAW_NO_COMPAT) || typeof RICKSHAW_NO_COMPAT === "undefined") {
+ new Rickshaw.Compat.ClassList();
+}
+Rickshaw.namespace('Rickshaw.Graph');
+
+Rickshaw.Graph = function(args) {
+
+ this.element = args.element;
+ this.series = args.series;
+
+ this.defaults = {
+ interpolation: 'cardinal',
+ offset: 'zero',
+ min: undefined,
+ max: undefined
+ };
+
+ Rickshaw.keys(this.defaults).forEach( function(k) {
+ this[k] = args[k] || this.defaults[k];
+ }, this );
+
+ this.window = {};
+
+ this.updateCallbacks = [];
+
+ var self = this;
+
+ this.initialize = function(args) {
+
+ this.validateSeries(args.series);
+
+ this.series.active = function() { return self.series.filter( function(s) { return !s.disabled } ) };
+
+ this.setSize({ width: args.width, height: args.height });
+
+ this.element.classList.add('rickshaw_graph');
+ this.vis = d3.select(this.element)
+ .append("svg:svg")
+ .attr('width', this.width)
+ .attr('height', this.height);
+
+ var renderers = [
+ Rickshaw.Graph.Renderer.Stack,
+ Rickshaw.Graph.Renderer.Line,
+ Rickshaw.Graph.Renderer.Bar,
+ Rickshaw.Graph.Renderer.Area,
+ Rickshaw.Graph.Renderer.ScatterPlot
+ ];
+
+ renderers.forEach( function(r) {
+ if (!r) return;
+ self.registerRenderer(new r( { graph: self } ));
+ } );
+
+ this.setRenderer(args.renderer || 'stack', args);
+ this.discoverRange();
+ };
+
+ this.validateSeries = function(series) {
+
+ if (!(series instanceof Array) && !(series instanceof Rickshaw.Series)) {
+ var seriesSignature = Object.prototype.toString.apply(series);
+ throw "series is not an array: " + seriesSignature;
+ }
+
+ var pointsCount;
+
+ series.forEach( function(s) {
+
+ if (!(s instanceof Object)) {
+ throw "series element is not an object: " + s;
+ }
+ if (!(s.data)) {
+ throw "series has no data: " + JSON.stringify(s);
+ }
+ if (!(s.data instanceof Array)) {
+ throw "series data is not an array: " + JSON.stringify(s.data);
+ }
+
+ pointsCount = pointsCount || s.data.length;
+
+ if (pointsCount && s.data.length != pointsCount) {
+ throw "series cannot have differing numbers of points: " +
+ pointsCount + " vs " + s.data.length + "; see Rickshaw.Series.zeroFill()";
+ }
+
+ var dataTypeX = typeof s.data[0].x;
+ var dataTypeY = typeof s.data[0].y;
+
+ if (dataTypeX != 'number' || dataTypeY != 'number') {
+ throw "x and y properties of points should be numbers instead of " +
+ dataTypeX + " and " + dataTypeY;
+ }
+ } );
+ };
+
+ this.dataDomain = function() {
+
+ // take from the first series
+ var data = this.series[0].data;
+
+ return [ data[0].x, data.slice(-1).shift().x ];
+
+ };
+
+ this.discoverRange = function() {
+
+ var domain = this.renderer.domain();
+
+ this.x = d3.scale.linear().domain(domain.x).range([0, this.width]);
+
+ this.y = d3.scale.linear().domain(domain.y).range([this.height, 0]);
+
+ this.y.magnitude = d3.scale.linear()
+ .domain([domain.y[0] - domain.y[0], domain.y[1] - domain.y[0]])
+ .range([0, this.height]);
+ };
+
+ this.render = function() {
+
+ var stackedData = this.stackData();
+ this.discoverRange();
+
+ this.renderer.render();
+
+ this.updateCallbacks.forEach( function(callback) {
+ callback();
+ } );
+ };
+
+ this.update = this.render;
+
+ this.stackData = function() {
+
+ var data = this.series.active()
+ .map( function(d) { return d.data } )
+ .map( function(d) { return d.filter( function(d) { return this._slice(d) }, this ) }, this);
+
+ this.stackData.hooks.data.forEach( function(entry) {
+ data = entry.f.apply(self, [data]);
+ } );
+
+ var layout = d3.layout.stack();
+ layout.offset( self.offset );
+
+ var stackedData = layout(data);
+
+ this.stackData.hooks.after.forEach( function(entry) {
+ stackedData = entry.f.apply(self, [data]);
+ } );
+
+ var i = 0;
+ this.series.forEach( function(series) {
+ if (series.disabled) return;
+ series.stack = stackedData[i++];
+ } );
+
+ this.stackedData = stackedData;
+ return stackedData;
+ };
+
+ this.stackData.hooks = { data: [], after: [] };
+
+ this._slice = function(d) {
+
+ if (this.window.xMin || this.window.xMax) {
+
+ var isInRange = true;
+
+ if (this.window.xMin && d.x < this.window.xMin) isInRange = false;
+ if (this.window.xMax && d.x > this.window.xMax) isInRange = false;
+
+ return isInRange;
+ }
+
+ return true;
+ };
+
+ this.onUpdate = function(callback) {
+ this.updateCallbacks.push(callback);
+ };
+
+ this.registerRenderer = function(renderer) {
+ this._renderers = this._renderers || {};
+ this._renderers[renderer.name] = renderer;
+ };
+
+ this.configure = function(args) {
+
+ if (args.width || args.height) {
+ this.setSize(args);
+ }
+
+ Rickshaw.keys(this.defaults).forEach( function(k) {
+ this[k] = k in args ? args[k]
+ : k in this ? this[k]
+ : this.defaults[k];
+ }, this );
+
+ this.setRenderer(args.renderer || this.renderer.name, args);
+ };
+
+ this.setRenderer = function(name, args) {
+
+ if (!this._renderers[name]) {
+ throw "couldn't find renderer " + name;
+ }
+ this.renderer = this._renderers[name];
+
+ if (typeof args == 'object') {
+ this.renderer.configure(args);
+ }
+ };
+
+ this.setSize = function(args) {
+
+ args = args || {};
+
+ if (typeof window !== undefined) {
+ var style = window.getComputedStyle(this.element, null);
+ var elementWidth = parseInt(style.getPropertyValue('width'));
+ var elementHeight = parseInt(style.getPropertyValue('height'));
+ }
+
+ this.width = args.width || elementWidth || 400;
+ this.height = args.height || elementHeight || 250;
+
+ this.vis && this.vis
+ .attr('width', this.width)
+ .attr('height', this.height);
+ }
+
+ this.initialize(args);
+};
+Rickshaw.namespace('Rickshaw.Fixtures.Color');
+
+Rickshaw.Fixtures.Color = function() {
+
+ this.schemes = {};
+
+ this.schemes.spectrum14 = [
+ '#ecb796',
+ '#dc8f70',
+ '#b2a470',
+ '#92875a',
+ '#716c49',
+ '#d2ed82',
+ '#bbe468',
+ '#a1d05d',
+ '#e7cbe6',
+ '#d8aad6',
+ '#a888c2',
+ '#9dc2d3',
+ '#649eb9',
+ '#387aa3'
+ ].reverse();
+
+ this.schemes.spectrum2000 = [
+ '#57306f',
+ '#514c76',
+ '#646583',
+ '#738394',
+ '#6b9c7d',
+ '#84b665',
+ '#a7ca50',
+ '#bfe746',
+ '#e2f528',
+ '#fff726',
+ '#ecdd00',
+ '#d4b11d',
+ '#de8800',
+ '#de4800',
+ '#c91515',
+ '#9a0000',
+ '#7b0429',
+ '#580839',
+ '#31082b'
+ ];
+
+ this.schemes.spectrum2001 = [
+ '#2f243f',
+ '#3c2c55',
+ '#4a3768',
+ '#565270',
+ '#6b6b7c',
+ '#72957f',
+ '#86ad6e',
+ '#a1bc5e',
+ '#b8d954',
+ '#d3e04e',
+ '#ccad2a',
+ '#cc8412',
+ '#c1521d',
+ '#ad3821',
+ '#8a1010',
+ '#681717',
+ '#531e1e',
+ '#3d1818',
+ '#320a1b'
+ ];
+
+ this.schemes.classic9 = [
+ '#423d4f',
+ '#4a6860',
+ '#848f39',
+ '#a2b73c',
+ '#ddcb53',
+ '#c5a32f',
+ '#7d5836',
+ '#963b20',
+ '#7c2626',
+ '#491d37',
+ '#2f254a'
+ ].reverse();
+
+ this.schemes.httpStatus = {
+ 503: '#ea5029',
+ 502: '#d23f14',
+ 500: '#bf3613',
+ 410: '#efacea',
+ 409: '#e291dc',
+ 403: '#f457e8',
+ 408: '#e121d2',
+ 401: '#b92dae',
+ 405: '#f47ceb',
+ 404: '#a82a9f',
+ 400: '#b263c6',
+ 301: '#6fa024',
+ 302: '#87c32b',
+ 307: '#a0d84c',
+ 304: '#28b55c',
+ 200: '#1a4f74',
+ 206: '#27839f',
+ 201: '#52adc9',
+ 202: '#7c979f',
+ 203: '#a5b8bd',
+ 204: '#c1cdd1'
+ };
+
+ this.schemes.colorwheel = [
+ '#b5b6a9',
+ '#858772',
+ '#785f43',
+ '#96557e',
+ '#4682b4',
+ '#65b9ac',
+ '#73c03a',
+ '#cb513a'
+ ].reverse();
+
+ this.schemes.cool = [
+ '#5e9d2f',
+ '#73c03a',
+ '#4682b4',
+ '#7bc3b8',
+ '#a9884e',
+ '#c1b266',
+ '#a47493',
+ '#c09fb5'
+ ];
+
+ this.schemes.munin = [
+ '#00cc00',
+ '#0066b3',
+ '#ff8000',
+ '#ffcc00',
+ '#330099',
+ '#990099',
+ '#ccff00',
+ '#ff0000',
+ '#808080',
+ '#008f00',
+ '#00487d',
+ '#b35a00',
+ '#b38f00',
+ '#6b006b',
+ '#8fb300',
+ '#b30000',
+ '#bebebe',
+ '#80ff80',
+ '#80c9ff',
+ '#ffc080',
+ '#ffe680',
+ '#aa80ff',
+ '#ee00cc',
+ '#ff8080',
+ '#666600',
+ '#ffbfff',
+ '#00ffcc',
+ '#cc6699',
+ '#999900'
+ ];
+};
+Rickshaw.namespace('Rickshaw.Fixtures.RandomData');
+
+Rickshaw.Fixtures.RandomData = function(timeInterval) {
+
+ var addData;
+ timeInterval = timeInterval || 1;
+
+ var lastRandomValue = 200;
+
+ var timeBase = Math.floor(new Date().getTime() / 1000);
+
+ this.addData = function(data) {
+
+ var randomValue = Math.random() * 100 + 15 + lastRandomValue;
+ var index = data[0].length;
+
+ var counter = 1;
+
+ data.forEach( function(series) {
+ var randomVariance = Math.random() * 20;
+ var v = randomValue / 25 + counter++
+ + (Math.cos((index * counter * 11) / 960) + 2) * 15
+ + (Math.cos(index / 7) + 2) * 7
+ + (Math.cos(index / 17) + 2) * 1;
+
+ series.push( { x: (index * timeInterval) + timeBase, y: v + randomVariance } );
+ } );
+
+ lastRandomValue = randomValue * .85;
+ }
+};
+
+Rickshaw.namespace('Rickshaw.Fixtures.Time');
+
+Rickshaw.Fixtures.Time = function() {
+
+ var tzOffset = new Date().getTimezoneOffset() * 60;
+
+ var self = this;
+
+ this.months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
+
+ this.units = [
+ {
+ name: 'decade',
+ seconds: 86400 * 365.25 * 10,
+ formatter: function(d) { return (parseInt(d.getUTCFullYear() / 10) * 10) }
+ }, {
+ name: '5 year',
+ seconds: 86400 * 365.25 * 5,
+ formatter: function(d) { return (parseInt(d.getUTCFullYear() / 5) * 5) }
+ }, {
+ name: 'year',
+ seconds: 86400 * 365.25,
+ formatter: function(d) { return d.getUTCFullYear() }
+ }, {
+ name: '6 month',
+ seconds: 86400 * 30.5 * 6,
+ formatter: function(d) { return self.months[d.getUTCMonth()] }
+ }, {
+ name: 'month',
+ seconds: 86400 * 30.5,
+ formatter: function(d) { return self.months[d.getUTCMonth()] }
+ }, {
+ name: 'week',
+ seconds: 86400 * 7,
+ formatter: function(d) { return self.formatDate(d) }
+ }, {
+ name: '3 day',
+ seconds: 86400 * 3,
+ formatter: function(d) { return self.formatDate(d) }
+ }, {
+ name: 'day',
+ seconds: 86400,
+ formatter: function(d) { return d.getUTCDate() }
+ }, {
+ name: '6 hour',
+ seconds: 3600 * 6,
+ formatter: function(d) { return self.formatTime(d) }
+ }, {
+ name: 'hour',
+ seconds: 3600,
+ formatter: function(d) { return self.formatTime(d) }
+ }, {
+ name: '15 minute',
+ seconds: 60 * 15,
+ formatter: function(d) { return self.formatTime(d) }
+ }, {
+ name: '5 minute',
+ seconds: 60 * 5,
+ formatter: function(d) { return self.formatTime(d) }
+ }, {
+ name: 'minute',
+ seconds: 60,
+ formatter: function(d) { return d.getUTCMinutes() }
+ }, {
+ name: '15 second',
+ seconds: 15,
+ formatter: function(d) { return d.getUTCSeconds() + 's' }
+ }, {
+ name: '5 second',
+ seconds: 5,
+ formatter: function(d) { return d.getUTCSeconds() + 's' }
+ }, {
+ name: 'second',
+ seconds: 1,
+ formatter: function(d) { return d.getUTCSeconds() + 's' }
+ }
+ ];
+
+ this.unit = function(unitName) {
+ return this.units.filter( function(unit) { return unitName == unit.name } ).shift();
+ };
+
+ this.formatDate = function(d) {
+ return d.toUTCString().match(/, (\w+ \w+ \w+)/)[1];
+ };
+
+ this.formatTime = function(d) {
+ return d.toUTCString().match(/(\d+:\d+):/)[1];
+ };
+
+ this.ceil = function(time, unit) {
+
+ if (unit.name == 'month') {
+
+ var nearFuture = new Date((time + unit.seconds - 1) * 1000);
+
+ var rounded = new Date(0);
+ rounded.setUTCFullYear(nearFuture.getUTCFullYear());
+ rounded.setUTCMonth(nearFuture.getUTCMonth());
+ rounded.setUTCDate(1);
+ rounded.setUTCHours(0);
+ rounded.setUTCMinutes(0);
+ rounded.setUTCSeconds(0);
+ rounded.setUTCMilliseconds(0);
+
+ return rounded.getTime() / 1000;
+ }
+
+ if (unit.name == 'year') {
+
+ var nearFuture = new Date((time + unit.seconds - 1) * 1000);
+
+ var rounded = new Date(0);
+ rounded.setUTCFullYear(nearFuture.getUTCFullYear());
+ rounded.setUTCMonth(0);
+ rounded.setUTCDate(1);
+ rounded.setUTCHours(0);
+ rounded.setUTCMinutes(0);
+ rounded.setUTCSeconds(0);
+ rounded.setUTCMilliseconds(0);
+
+ return rounded.getTime() / 1000;
+ }
+
+ return Math.ceil(time / unit.seconds) * unit.seconds;
+ };
+};
+Rickshaw.namespace('Rickshaw.Fixtures.Number');
+
+Rickshaw.Fixtures.Number.formatKMBT = function(y) {
+ if (y >= 1000000000000) { return y / 1000000000000 + "T" }
+ else if (y >= 1000000000) { return y / 1000000000 + "B" }
+ else if (y >= 1000000) { return y / 1000000 + "M" }
+ else if (y >= 1000) { return y / 1000 + "K" }
+ else if (y < 1 && y > 0) { return y.toFixed(2) }
+ else if (y == 0) { return '' }
+ else { return y }
+};
+
+Rickshaw.Fixtures.Number.formatBase1024KMGTP = function(y) {
+ if (y >= 1125899906842624) { return y / 1125899906842624 + "P" }
+ else if (y >= 1099511627776){ return y / 1099511627776 + "T" }
+ else if (y >= 1073741824) { return y / 1073741824 + "G" }
+ else if (y >= 1048576) { return y / 1048576 + "M" }
+ else if (y >= 1024) { return y / 1024 + "K" }
+ else if (y < 1 && y > 0) { return y.toFixed(2) }
+ else if (y == 0) { return '' }
+ else { return y }
+};
+Rickshaw.namespace("Rickshaw.Color.Palette");
+
+Rickshaw.Color.Palette = function(args) {
+
+ var color = new Rickshaw.Fixtures.Color();
+
+ args = args || {};
+ this.schemes = {};
+
+ this.scheme = color.schemes[args.scheme] || args.scheme || color.schemes.colorwheel;
+ this.runningIndex = 0;
+ this.generatorIndex = 0;
+
+ if (args.interpolatedStopCount) {
+ var schemeCount = this.scheme.length - 1;
+ var i, j, scheme = [];
+ for (i = 0; i < schemeCount; i++) {
+ scheme.push(this.scheme[i]);
+ var generator = d3.interpolateHsl(this.scheme[i], this.scheme[i + 1]);
+ for (j = 1; j < args.interpolatedStopCount; j++) {
+ scheme.push(generator((1 / args.interpolatedStopCount) * j));
+ }
+ }
+ scheme.push(this.scheme[this.scheme.length - 1]);
+ this.scheme = scheme;
+ }
+ this.rotateCount = this.scheme.length;
+
+ this.color = function(key) {
+ return this.scheme[key] || this.scheme[this.runningIndex++] || this.interpolateColor() || '#808080';
+ };
+
+ this.interpolateColor = function() {
+ if (!Array.isArray(this.scheme)) return;
+ var color;
+ if (this.generatorIndex == this.rotateCount * 2 - 1) {
+ color = d3.interpolateHsl(this.scheme[this.generatorIndex], this.scheme[0])(0.5);
+ this.generatorIndex = 0;
+ this.rotateCount *= 2;
+ } else {
+ color = d3.interpolateHsl(this.scheme[this.generatorIndex], this.scheme[this.generatorIndex + 1])(0.5);
+ this.generatorIndex++;
+ }
+ this.scheme.push(color);
+ return color;
+ };
+
+};
+Rickshaw.namespace('Rickshaw.Graph.Ajax');
+
+Rickshaw.Graph.Ajax = Rickshaw.Class.create( {
+
+ initialize: function(args) {
+
+ this.dataURL = args.dataURL;
+
+ this.onData = args.onData || function(d) { return d };
+ this.onComplete = args.onComplete || function() {};
+ this.onError = args.onError || function() {};
+
+ this.args = args; // pass through to Rickshaw.Graph
+
+ this.request();
+ },
+
+ request: function() {
+
+ $.ajax( {
+ url: this.dataURL,
+ dataType: 'json',
+ success: this.success.bind(this),
+ error: this.error.bind(this)
+ } );
+ },
+
+ error: function() {
+
+ console.log("error loading dataURL: " + this.dataURL);
+ this.onError(this);
+ },
+
+ success: function(data, status) {
+
+ data = this.onData(data);
+ this.args.series = this._splice({ data: data, series: this.args.series });
+
+ this.graph = new Rickshaw.Graph(this.args);
+ this.graph.render();
+
+ this.onComplete(this);
+ },
+
+ _splice: function(args) {
+
+ var data = args.data;
+ var series = args.series;
+
+ if (!args.series) return data;
+
+ series.forEach( function(s) {
+
+ var seriesKey = s.key || s.name;
+ if (!seriesKey) throw "series needs a key or a name";
+
+ data.forEach( function(d) {
+
+ var dataKey = d.key || d.name;
+ if (!dataKey) throw "data needs a key or a name";
+
+ if (seriesKey == dataKey) {
+ var properties = ['color', 'name', 'data'];
+ properties.forEach( function(p) {
+ s[p] = s[p] || d[p];
+ } );
+ }
+ } );
+ } );
+
+ return series;
+ }
+} );
+
+Rickshaw.namespace('Rickshaw.Graph.Annotate');
+
+Rickshaw.Graph.Annotate = function(args) {
+
+ var graph = this.graph = args.graph;
+ this.elements = { timeline: args.element };
+
+ var self = this;
+
+ this.data = {};
+
+ this.elements.timeline.classList.add('rickshaw_annotation_timeline');
+
+ this.add = function(time, content, end_time) {
+ self.data[time] = self.data[time] || {'boxes': []};
+ self.data[time].boxes.push({content: content, end: end_time});
+ };
+
+ this.update = function() {
+
+ Rickshaw.keys(self.data).forEach( function(time) {
+
+ var annotation = self.data[time];
+ var left = self.graph.x(time);
+
+ if (left < 0 || left > self.graph.x.range()[1]) {
+ if (annotation.element) {
+ annotation.line.classList.add('offscreen');
+ annotation.element.style.display = 'none';
+ }
+
+ annotation.boxes.forEach( function(box) {
+ if ( box.rangeElement ) box.rangeElement.classList.add('offscreen');
+ });
+
+ return;
+ }
+
+ if (!annotation.element) {
+ var element = annotation.element = document.createElement('div');
+ element.classList.add('annotation');
+ this.elements.timeline.appendChild(element);
+ element.addEventListener('click', function(e) {
+ element.classList.toggle('active');
+ annotation.line.classList.toggle('active');
+ annotation.boxes.forEach( function(box) {
+ if ( box.rangeElement ) box.rangeElement.classList.toggle('active');
+ });
+ }, false);
+
+ }
+
+ annotation.element.style.left = left + 'px';
+ annotation.element.style.display = 'block';
+
+ annotation.boxes.forEach( function(box) {
+
+
+ var element = box.element;
+
+ if (!element) {
+ element = box.element = document.createElement('div');
+ element.classList.add('content');
+ element.innerHTML = box.content;
+ annotation.element.appendChild(element);
+
+ annotation.line = document.createElement('div');
+ annotation.line.classList.add('annotation_line');
+ self.graph.element.appendChild(annotation.line);
+
+ if ( box.end ) {
+ box.rangeElement = document.createElement('div');
+ box.rangeElement.classList.add('annotation_range');
+ self.graph.element.appendChild(box.rangeElement);
+ }
+
+ }
+
+ if ( box.end ) {
+
+ var annotationRangeStart = left;
+ var annotationRangeEnd = Math.min( self.graph.x(box.end), self.graph.x.range()[1] );
+
+ // annotation makes more sense at end
+ if ( annotationRangeStart > annotationRangeEnd ) {
+ annotationRangeEnd = left;
+ annotationRangeStart = Math.max( self.graph.x(box.end), self.graph.x.range()[0] );
+ }
+
+ var annotationRangeWidth = annotationRangeEnd - annotationRangeStart;
+
+ box.rangeElement.style.left = annotationRangeStart + 'px';
+ box.rangeElement.style.width = annotationRangeWidth + 'px'
+
+ box.rangeElement.classList.remove('offscreen');
+ }
+
+ annotation.line.classList.remove('offscreen');
+ annotation.line.style.left = left + 'px';
+ } );
+ }, this );
+ };
+
+ this.graph.onUpdate( function() { self.update() } );
+};
+Rickshaw.namespace('Rickshaw.Graph.Axis.Time');
+
+Rickshaw.Graph.Axis.Time = function(args) {
+
+ var self = this;
+
+ this.graph = args.graph;
+ this.elements = [];
+ this.ticksTreatment = args.ticksTreatment || 'plain';
+ this.fixedTimeUnit = args.timeUnit;
+
+ var time = new Rickshaw.Fixtures.Time();
+
+ this.appropriateTimeUnit = function() {
+
+ var unit;
+ var units = time.units;
+
+ var domain = this.graph.x.domain();
+ var rangeSeconds = domain[1] - domain[0];
+
+ units.forEach( function(u) {
+ if (Math.floor(rangeSeconds / u.seconds) >= 2) {
+ unit = unit || u;
+ }
+ } );
+
+ return (unit || time.units[time.units.length - 1]);
+ };
+
+ this.tickOffsets = function() {
+
+ var domain = this.graph.x.domain();
+
+ var unit = this.fixedTimeUnit || this.appropriateTimeUnit();
+ var count = Math.ceil((domain[1] - domain[0]) / unit.seconds);
+
+ var runningTick = domain[0];
+
+ var offsets = [];
+
+ for (var i = 0; i < count; i++) {
+
+ tickValue = time.ceil(runningTick, unit);
+ runningTick = tickValue + unit.seconds / 2;
+
+ offsets.push( { value: tickValue, unit: unit } );
+ }
+
+ return offsets;
+ };
+
+ this.render = function() {
+
+ this.elements.forEach( function(e) {
+ e.parentNode.removeChild(e);
+ } );
+
+ this.elements = [];
+
+ var offsets = this.tickOffsets();
+
+ offsets.forEach( function(o) {
+
+ if (self.graph.x(o.value) > self.graph.x.range()[1]) return;
+
+ var element = document.createElement('div');
+ element.style.left = self.graph.x(o.value) + 'px';
+ element.classList.add('x_tick');
+ element.classList.add(self.ticksTreatment);
+
+ var title = document.createElement('div');
+ title.classList.add('title');
+ title.innerHTML = o.unit.formatter(new Date(o.value * 1000));
+ element.appendChild(title);
+
+ self.graph.element.appendChild(element);
+ self.elements.push(element);
+
+ } );
+ };
+
+ this.graph.onUpdate( function() { self.render() } );
+};
+
+Rickshaw.namespace('Rickshaw.Graph.Axis.Y');
+
+Rickshaw.Graph.Axis.Y = function(args) {
+
+ var self = this;
+ var berthRate = 0.10;
+
+ this.initialize = function(args) {
+
+ this.graph = args.graph;
+ this.orientation = args.orientation || 'right';
+
+ var pixelsPerTick = args.pixelsPerTick || 75;
+ this.ticks = args.ticks || Math.floor(this.graph.height / pixelsPerTick);
+ this.tickSize = args.tickSize || 4;
+ this.ticksTreatment = args.ticksTreatment || 'plain';
+
+ if (args.element) {
+
+ this.element = args.element;
+ this.vis = d3.select(args.element)
+ .append("svg:svg")
+ .attr('class', 'rickshaw_graph y_axis');
+
+ this.element = this.vis[0][0];
+ this.element.style.position = 'relative';
+
+ this.setSize({ width: args.width, height: args.height });
+
+ } else {
+ this.vis = this.graph.vis;
+ }
+
+ this.graph.onUpdate( function() { self.render() } );
+ };
+
+ this.setSize = function(args) {
+
+ args = args || {};
+
+ if (!this.element) return;
+
+ if (typeof window !== 'undefined') {
+
+ var style = window.getComputedStyle(this.element.parentNode, null);
+ var elementWidth = parseInt(style.getPropertyValue('width'));
+
+ if (!args.auto) {
+ var elementHeight = parseInt(style.getPropertyValue('height'));
+ }
+ }
+
+ this.width = args.width || elementWidth || this.graph.width * berthRate;
+ this.height = args.height || elementHeight || this.graph.height;
+
+ this.vis
+ .attr('width', this.width)
+ .attr('height', this.height * (1 + berthRate));
+
+ var berth = this.height * berthRate;
+ this.element.style.top = -1 * berth + 'px';
+ };
+
+ this.render = function() {
+
+ if (this.graph.height !== this._renderHeight) this.setSize({ auto: true });
+
+ var axis = d3.svg.axis().scale(this.graph.y).orient(this.orientation);
+ axis.tickFormat( args.tickFormat || function(y) { return y } );
+
+ if (this.orientation == 'left') {
+ var berth = this.height * berthRate;
+ var transform = 'translate(' + this.width + ', ' + berth + ')';
+ }
+
+ if (this.element) {
+ this.vis.selectAll('*').remove();
+ }
+
+ this.vis
+ .append("svg:g")
+ .attr("class", ["y_ticks", this.ticksTreatment].join(" "))
+ .attr("transform", transform)
+ .call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(this.tickSize))
+
+ var gridSize = (this.orientation == 'right' ? 1 : -1) * this.graph.width;
+
+ this.graph.vis
+ .append("svg:g")
+ .attr("class", "y_grid")
+ .call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(gridSize));
+
+ this._renderHeight = this.graph.height;
+ };
+
+ this.initialize(args);
+};
+
+Rickshaw.namespace('Rickshaw.Graph.Behavior.Series.Highlight');
+
+Rickshaw.Graph.Behavior.Series.Highlight = function(args) {
+
+ this.graph = args.graph;
+ this.legend = args.legend;
+
+ var self = this;
+
+ var colorSafe = {};
+
+ this.addHighlightEvents = function (l) {
+ l.element.addEventListener( 'mouseover', function(e) {
+
+ self.legend.lines.forEach( function(line) {
+ if (l === line) return;
+ colorSafe[line.series.name] = colorSafe[line.series.name] || line.series.color;
+ line.series.color = d3.interpolateRgb(line.series.color, d3.rgb('#d8d8d8'))(0.8).toString();
+ } );
+
+ self.graph.update();
+
+ }, false );
+
+ l.element.addEventListener( 'mouseout', function(e) {
+
+ self.legend.lines.forEach( function(line) {
+ if (colorSafe[line.series.name]) {
+ line.series.color = colorSafe[line.series.name];
+ }
+ } );
+
+ self.graph.update();
+
+ }, false );
+ };
+
+ if (this.legend) {
+ this.legend.lines.forEach( function(l) {
+ self.addHighlightEvents(l);
+ } );
+ }
+
+};
+Rickshaw.namespace('Rickshaw.Graph.Behavior.Series.Order');
+
+Rickshaw.Graph.Behavior.Series.Order = function(args) {
+
+ this.graph = args.graph;
+ this.legend = args.legend;
+
+ var self = this;
+
+ $(function() {
+ $(self.legend.list).sortable( {
+ containment: 'parent',
+ tolerance: 'pointer',
+ update: function( event, ui ) {
+ var series = [];
+ $(self.legend.list).find('li').each( function(index, item) {
+ if (!item.series) return;
+ series.push(item.series);
+ } );
+
+ for (var i = self.graph.series.length - 1; i >= 0; i--) {
+ self.graph.series[i] = series.shift();
+ }
+
+ self.graph.update();
+ }
+ } );
+ $(self.legend.list).disableSelection();
+ });
+
+ //hack to make jquery-ui sortable behave
+ this.graph.onUpdate( function() {
+ // commenting out since this breaks rendering in IE9
+ //var h = window.getComputedStyle(self.legend.element).height;
+ //self.legend.element.style.height = h;
+ } );
+};
+Rickshaw.namespace('Rickshaw.Graph.Behavior.Series.Toggle');
+
+Rickshaw.Graph.Behavior.Series.Toggle = function(args) {
+
+ this.graph = args.graph;
+ this.legend = args.legend;
+
+ var self = this;
+
+ this.addAnchor = function(line) {
+ var anchor = document.createElement('a');
+ anchor.innerHTML = '✔';
+ anchor.classList.add('action');
+ line.element.insertBefore(anchor, line.element.firstChild);
+
+ anchor.onclick = function(e) {
+ if (line.series.disabled) {
+ line.series.enable();
+ line.element.classList.remove('disabled');
+ } else {
+ line.series.disable();
+ line.element.classList.add('disabled');
+ }
+ }
+
+ var label = line.element.getElementsByTagName('span')[0];
+ label.onclick = function(e){
+
+ var disableAllOtherLines = line.series.disabled;
+ if ( ! disableAllOtherLines ) {
+ for ( var i = 0; i < self.legend.lines.length; i++ ) {
+ var l = self.legend.lines[i];
+ if ( line.series === l.series ) {
+ // noop
+ } else if ( l.series.disabled ) {
+ // noop
+ } else {
+ disableAllOtherLines = true;
+ break;
+ }
+ }
+ }
+
+ // show all or none
+ if ( disableAllOtherLines ) {
+
+ // these must happen first or else we try ( and probably fail ) to make a no line graph
+ line.series.enable();
+ line.element.classList.remove('disabled');
+
+ self.legend.lines.forEach(function(l){
+ if ( line.series === l.series ) {
+ // noop
+ } else {
+ l.series.disable();
+ l.element.classList.add('disabled');
+ }
+ });
+
+ } else {
+
+ self.legend.lines.forEach(function(l){
+ l.series.enable();
+ l.element.classList.remove('disabled');
+ });
+
+ }
+
+ };
+
+ };
+
+ if (this.legend) {
+
+ $(this.legend.list).sortable( {
+ start: function(event, ui) {
+ ui.item.bind('no.onclick',
+ function(event) {
+ event.preventDefault();
+ }
+ );
+ },
+ stop: function(event, ui) {
+ setTimeout(function(){
+ ui.item.unbind('no.onclick');
+ }, 250);
+ }
+ })
+
+ this.legend.lines.forEach( function(l) {
+ self.addAnchor(l);
+ } );
+ }
+
+ this._addBehavior = function() {
+
+ this.graph.series.forEach( function(s) {
+
+ s.disable = function() {
+
+ if (self.graph.series.length <= 1) {
+ throw('only one series left');
+ }
+
+ s.disabled = true;
+ self.graph.update();
+ };
+
+ s.enable = function() {
+ s.disabled = false;
+ self.graph.update();
+ };
+ } );
+ };
+ this._addBehavior();
+
+ this.updateBehaviour = function () { this._addBehavior() };
+
+};
+Rickshaw.namespace('Rickshaw.Graph.HoverDetail');
+
+Rickshaw.Graph.HoverDetail = Rickshaw.Class.create({
+
+ initialize: function(args) {
+
+ var graph = this.graph = args.graph;
+
+ this.xFormatter = args.xFormatter || function(x) {
+ return new Date( x * 1000 ).toUTCString();
+ };
+
+ this.yFormatter = args.yFormatter || function(y) {
+ return y.toFixed(2);
+ };
+
+ var element = this.element = document.createElement('div');
+ element.className = 'detail';
+
+ this.visible = true;
+ graph.element.appendChild(element);
+
+ this.lastEvent = null;
+ this._addListeners();
+
+ this.onShow = args.onShow;
+ this.onHide = args.onHide;
+ this.onRender = args.onRender;
+
+ this.formatter = args.formatter || this.formatter;
+ },
+
+ formatter: function(series, x, y, formattedX, formattedY, d) {
+ return series.name + ': ' + formattedY;
+ },
+
+ update: function(e) {
+
+ e = e || this.lastEvent;
+ if (!e) return;
+ this.lastEvent = e;
+
+ if (!e.target.nodeName.match(/^(path|svg|rect)$/)) return;
+
+ var graph = this.graph;
+
+ var eventX = e.offsetX || e.layerX;
+ var eventY = e.offsetY || e.layerY;
+
+ var domainX = graph.x.invert(eventX);
+ var stackedData = graph.stackedData;
+
+ var topSeriesData = stackedData.slice(-1).shift();
+
+ var domainIndexScale = d3.scale.linear()
+ .domain([topSeriesData[0].x, topSeriesData.slice(-1).shift().x])
+ .range([0, topSeriesData.length]);
+
+ var approximateIndex = Math.floor(domainIndexScale(domainX));
+ var dataIndex = Math.min(approximateIndex || 0, stackedData[0].length - 1);
+
+ for (var i = approximateIndex; i < stackedData[0].length - 1;) {
+
+ if (!stackedData[0][i] || !stackedData[0][i + 1]) {
+ break;
+ }
+
+ if (stackedData[0][i].x <= domainX && stackedData[0][i + 1].x > domainX) {
+ dataIndex = i;
+ break;
+ }
+ if (stackedData[0][i + 1] <= domainX) { i++ } else { i-- }
+ }
+
+ var domainX = stackedData[0][dataIndex].x;
+ var formattedXValue = this.xFormatter(domainX);
+ var graphX = graph.x(domainX);
+ var order = 0;
+
+ var detail = graph.series.active()
+ .map( function(s) { return { order: order++, series: s, name: s.name, value: s.stack[dataIndex] } } );
+
+ var activeItem;
+
+ var sortFn = function(a, b) {
+ return (a.value.y0 + a.value.y) - (b.value.y0 + b.value.y);
+ };
+
+ var domainMouseY = graph.y.magnitude.invert(graph.element.offsetHeight - eventY);
+
+ detail.sort(sortFn).forEach( function(d) {
+
+ d.formattedYValue = (this.yFormatter.constructor == Array) ?
+ this.yFormatter[detail.indexOf(d)](d.value.y) :
+ this.yFormatter(d.value.y);
+
+ d.graphX = graphX;
+ d.graphY = graph.y(d.value.y0 + d.value.y);
+
+ if (domainMouseY > d.value.y0 && domainMouseY < d.value.y0 + d.value.y && !activeItem) {
+ activeItem = d;
+ d.active = true;
+ }
+
+ }, this );
+
+ this.element.innerHTML = '';
+ this.element.style.left = graph.x(domainX) + 'px';
+
+ if (this.visible) {
+ this.render( {
+ detail: detail,
+ domainX: domainX,
+ formattedXValue: formattedXValue,
+ mouseX: eventX,
+ mouseY: eventY
+ } );
+ }
+ },
+
+ hide: function() {
+ this.visible = false;
+ this.element.classList.add('inactive');
+
+ if (typeof this.onHide == 'function') {
+ this.onHide();
+ }
+ },
+
+ show: function() {
+ this.visible = true;
+ this.element.classList.remove('inactive');
+
+ if (typeof this.onShow == 'function') {
+ this.onShow();
+ }
+ },
+
+ render: function(args) {
+
+ var detail = args.detail;
+ var domainX = args.domainX;
+
+ var mouseX = args.mouseX;
+ var mouseY = args.mouseY;
+
+ var formattedXValue = args.formattedXValue;
+
+ var xLabel = document.createElement('div');
+ xLabel.className = 'x_label';
+ xLabel.innerHTML = formattedXValue;
+ this.element.appendChild(xLabel);
+
+ detail.forEach( function(d) {
+
+ var item = document.createElement('div');
+ item.className = 'item';
+ item.innerHTML = this.formatter(d.series, domainX, d.value.y, formattedXValue, d.formattedYValue, d);
+ item.style.top = this.graph.y(d.value.y0 + d.value.y) + 'px';
+
+ this.element.appendChild(item);
+
+ var dot = document.createElement('div');
+ dot.className = 'dot';
+ dot.style.top = item.style.top;
+ dot.style.borderColor = d.series.color;
+
+ this.element.appendChild(dot);
+
+ if (d.active) {
+ item.className = 'item active';
+ dot.className = 'dot active';
+ }
+
+ }, this );
+
+ this.show();
+
+ if (typeof this.onRender == 'function') {
+ this.onRender(args);
+ }
+ },
+
+ _addListeners: function() {
+
+ this.graph.element.addEventListener(
+ 'mousemove',
+ function(e) {
+ this.visible = true;
+ this.update(e)
+ }.bind(this),
+ false
+ );
+
+ this.graph.onUpdate( function() { this.update() }.bind(this) );
+
+ this.graph.element.addEventListener(
+ 'mouseout',
+ function(e) {
+ if (e.relatedTarget && !(e.relatedTarget.compareDocumentPosition(this.graph.element) & Node.DOCUMENT_POSITION_CONTAINS)) {
+ this.hide();
+ }
+ }.bind(this),
+ false
+ );
+ }
+});
+
+Rickshaw.namespace('Rickshaw.Graph.JSONP');
+
+Rickshaw.Graph.JSONP = Rickshaw.Class.create( Rickshaw.Graph.Ajax, {
+
+ request: function() {
+
+ $.ajax( {
+ url: this.dataURL,
+ dataType: 'jsonp',
+ success: this.success.bind(this),
+ error: this.error.bind(this)
+ } );
+ }
+} );
+Rickshaw.namespace('Rickshaw.Graph.Legend');
+
+Rickshaw.Graph.Legend = function(args) {
+
+ var element = this.element = args.element;
+ var graph = this.graph = args.graph;
+
+ var self = this;
+
+ element.classList.add('rickshaw_legend');
+
+ var list = this.list = document.createElement('ul');
+ element.appendChild(list);
+
+ var series = graph.series
+ .map( function(s) { return s } )
+ .reverse();
+
+ this.lines = [];
+
+ this.addLine = function (series) {
+ var line = document.createElement('li');
+ line.className = 'line';
+
+ var swatch = document.createElement('div');
+ swatch.className = 'swatch';
+ swatch.style.backgroundColor = series.color;
+
+ line.appendChild(swatch);
+
+ var label = document.createElement('span');
+ label.className = 'label';
+ label.innerHTML = series.name;
+
+ line.appendChild(label);
+ list.appendChild(line);
+
+ line.series = series;
+
+ if (series.noLegend) {
+ line.style.display = 'none';
+ }
+
+ var _line = { element: line, series: series };
+ if (self.shelving) {
+ self.shelving.addAnchor(_line);
+ self.shelving.updateBehaviour();
+ }
+ if (self.highlighter) {
+ self.highlighter.addHighlightEvents(_line);
+ }
+ self.lines.push(_line);
+ };
+
+ series.forEach( function(s) {
+ self.addLine(s);
+ } );
+
+ graph.onUpdate( function() {} );
+};
+Rickshaw.namespace('Rickshaw.Graph.RangeSlider');
+
+Rickshaw.Graph.RangeSlider = function(args) {
+
+ var element = this.element = args.element;
+ var graph = this.graph = args.graph;
+
+ $( function() {
+ $(element).slider( {
+
+ range: true,
+ min: graph.dataDomain()[0],
+ max: graph.dataDomain()[1],
+ values: [
+ graph.dataDomain()[0],
+ graph.dataDomain()[1]
+ ],
+ slide: function( event, ui ) {
+
+ graph.window.xMin = ui.values[0];
+ graph.window.xMax = ui.values[1];
+ graph.update();
+
+ // if we're at an extreme, stick there
+ if (graph.dataDomain()[0] == ui.values[0]) {
+ graph.window.xMin = undefined;
+ }
+ if (graph.dataDomain()[1] == ui.values[1]) {
+ graph.window.xMax = undefined;
+ }
+ }
+ } );
+ } );
+
+ element[0].style.width = graph.width + 'px';
+
+ graph.onUpdate( function() {
+
+ var values = $(element).slider('option', 'values');
+
+ $(element).slider('option', 'min', graph.dataDomain()[0]);
+ $(element).slider('option', 'max', graph.dataDomain()[1]);
+
+ if (graph.window.xMin == undefined) {
+ values[0] = graph.dataDomain()[0];
+ }
+ if (graph.window.xMax == undefined) {
+ values[1] = graph.dataDomain()[1];
+ }
+
+ $(element).slider('option', 'values', values);
+
+ } );
+};
+
+Rickshaw.namespace("Rickshaw.Graph.Renderer");
+
+Rickshaw.Graph.Renderer = Rickshaw.Class.create( {
+
+ initialize: function(args) {
+ this.graph = args.graph;
+ this.tension = args.tension || this.tension;
+ this.graph.unstacker = this.graph.unstacker || new Rickshaw.Graph.Unstacker( { graph: this.graph } );
+ this.configure(args);
+ },
+
+ seriesPathFactory: function() {
+ //implement in subclass
+ },
+
+ seriesStrokeFactory: function() {
+ // implement in subclass
+ },
+
+ defaults: function() {
+ return {
+ tension: 0.8,
+ strokeWidth: 2,
+ unstack: true,
+ padding: { top: 0.01, right: 0, bottom: 0.01, left: 0 },
+ stroke: false,
+ fill: false
+ };
+ },
+
+ domain: function() {
+
+ var values = [];
+ var stackedData = this.graph.stackedData || this.graph.stackData();
+
+ var topSeriesData = this.unstack ? stackedData : [ stackedData.slice(-1).shift() ];
+
+ topSeriesData.forEach( function(series) {
+ series.forEach( function(d) {
+ values.push( d.y + d.y0 );
+ } );
+ } );
+
+ var xMin = stackedData[0][0].x;
+ var xMax = stackedData[0][ stackedData[0].length - 1 ].x;
+
+ xMin -= (xMax - xMin) * this.padding.left;
+ xMax += (xMax - xMin) * this.padding.right;
+
+ var yMin = this.graph.min === 'auto' ? d3.min( values ) : this.graph.min || 0;
+ var yMax = this.graph.max || d3.max( values );
+
+ if (this.graph.min === 'auto' || yMin < 0) {
+ yMin -= (yMax - yMin) * this.padding.bottom;
+ }
+
+ if (this.graph.max === undefined) {
+ yMax += (yMax - yMin) * this.padding.top;
+ }
+
+ return { x: [xMin, xMax], y: [yMin, yMax] };
+ },
+
+ render: function() {
+
+ var graph = this.graph;
+
+ graph.vis.selectAll('*').remove();
+
+ var nodes = graph.vis.selectAll("path")
+ .data(this.graph.stackedData)
+ .enter().append("svg:path")
+ .attr("d", this.seriesPathFactory());
+
+ var i = 0;
+ graph.series.forEach( function(series) {
+ if (series.disabled) return;
+ series.path = nodes[0][i++];
+ this._styleSeries(series);
+ }, this );
+ },
+
+ _styleSeries: function(series) {
+
+ var fill = this.fill ? series.color : 'none';
+ var stroke = this.stroke ? series.color : 'none';
+
+ series.path.setAttribute('fill', fill);
+ series.path.setAttribute('stroke', stroke);
+ series.path.setAttribute('stroke-width', this.strokeWidth);
+ series.path.setAttribute('class', series.className);
+ },
+
+ configure: function(args) {
+
+ args = args || {};
+
+ Rickshaw.keys(this.defaults()).forEach( function(key) {
+
+ if (!args.hasOwnProperty(key)) {
+ this[key] = this[key] || this.graph[key] || this.defaults()[key];
+ return;
+ }
+
+ if (typeof this.defaults()[key] == 'object') {
+
+ Rickshaw.keys(this.defaults()[key]).forEach( function(k) {
+
+ this[key][k] =
+ args[key][k] !== undefined ? args[key][k] :
+ this[key][k] !== undefined ? this[key][k] :
+ this.defaults()[key][k];
+ }, this );
+
+ } else {
+ this[key] =
+ args[key] !== undefined ? args[key] :
+ this[key] !== undefined ? this[key] :
+ this.graph[key] !== undefined ? this.graph[key] :
+ this.defaults()[key];
+ }
+
+ }, this );
+ },
+
+ setStrokeWidth: function(strokeWidth) {
+ if (strokeWidth !== undefined) {
+ this.strokeWidth = strokeWidth;
+ }
+ },
+
+ setTension: function(tension) {
+ if (tension !== undefined) {
+ this.tension = tension;
+ }
+ }
+} );
+
+Rickshaw.namespace('Rickshaw.Graph.Renderer.Line');
+
+Rickshaw.Graph.Renderer.Line = Rickshaw.Class.create( Rickshaw.Graph.Renderer, {
+
+ name: 'line',
+
+ defaults: function($super) {
+
+ return Rickshaw.extend( $super(), {
+ unstack: true,
+ fill: false,
+ stroke: true
+ } );
+ },
+
+ seriesPathFactory: function() {
+
+ var graph = this.graph;
+
+ return d3.svg.line()
+ .x( function(d) { return graph.x(d.x) } )
+ .y( function(d) { return graph.y(d.y) } )
+ .interpolate(this.graph.interpolation).tension(this.tension);
+ }
+} );
+
+Rickshaw.namespace('Rickshaw.Graph.Renderer.Stack');
+
+Rickshaw.Graph.Renderer.Stack = Rickshaw.Class.create( Rickshaw.Graph.Renderer, {
+
+ name: 'stack',
+
+ defaults: function($super) {
+
+ return Rickshaw.extend( $super(), {
+ fill: true,
+ stroke: false,
+ unstack: false
+ } );
+ },
+
+ seriesPathFactory: function() {
+
+ var graph = this.graph;
+
+ return d3.svg.area()
+ .x( function(d) { return graph.x(d.x) } )
+ .y0( function(d) { return graph.y(d.y0) } )
+ .y1( function(d) { return graph.y(d.y + d.y0) } )
+ .interpolate(this.graph.interpolation).tension(this.tension);
+ }
+} );
+
+Rickshaw.namespace('Rickshaw.Graph.Renderer.Bar');
+
+Rickshaw.Graph.Renderer.Bar = Rickshaw.Class.create( Rickshaw.Graph.Renderer, {
+
+ name: 'bar',
+
+ defaults: function($super) {
+
+ var defaults = Rickshaw.extend( $super(), {
+ gapSize: 0.05,
+ unstack: false
+ } );
+
+ delete defaults.tension;
+ return defaults;
+ },
+
+ initialize: function($super, args) {
+ args = args || {};
+ this.gapSize = args.gapSize || this.gapSize;
+ $super(args);
+ },
+
+ domain: function($super) {
+
+ var domain = $super();
+
+ var frequentInterval = this._frequentInterval();
+ domain.x[1] += parseInt(frequentInterval.magnitude);
+
+ return domain;
+ },
+
+ barWidth: function() {
+
+ var stackedData = this.graph.stackedData || this.graph.stackData();
+ var data = stackedData.slice(-1).shift();
+
+ var frequentInterval = this._frequentInterval();
+ var barWidth = this.graph.x(data[0].x + frequentInterval.magnitude * (1 - this.gapSize));
+
+ return barWidth;
+ },
+
+ render: function() {
+
+ var graph = this.graph;
+
+ graph.vis.selectAll('*').remove();
+
+ var barWidth = this.barWidth();
+ var barXOffset = 0;
+
+ var activeSeriesCount = graph.series.filter( function(s) { return !s.disabled; } ).length;
+ var seriesBarWidth = this.unstack ? barWidth / activeSeriesCount : barWidth;
+
+ var transform = function(d) {
+ // add a matrix transform for negative values
+ var matrix = [ 1, 0, 0, (d.y < 0 ? -1 : 1), 0, (d.y < 0 ? graph.y.magnitude(Math.abs(d.y)) * 2 : 0) ];
+ return "matrix(" + matrix.join(',') + ")";
+ };
+
+ graph.series.forEach( function(series) {
+
+ if (series.disabled) return;
+
+ var nodes = graph.vis.selectAll("path")
+ .data(series.stack)
+ .enter().append("svg:rect")
+ .attr("x", function(d) { return graph.x(d.x) + barXOffset })
+ .attr("y", function(d) { return (graph.y(d.y0 + Math.abs(d.y))) * (d.y < 0 ? -1 : 1 ) })
+ .attr("width", seriesBarWidth)
+ .attr("height", function(d) { return graph.y.magnitude(Math.abs(d.y)) })
+ .attr("transform", transform);
+
+ Array.prototype.forEach.call(nodes[0], function(n) {
+ n.setAttribute('fill', series.color);
+ } );
+
+ if (this.unstack) barXOffset += seriesBarWidth;
+
+ }, this );
+ },
+
+ _frequentInterval: function() {
+
+ var stackedData = this.graph.stackedData || this.graph.stackData();
+ var data = stackedData.slice(-1).shift();
+
+ var intervalCounts = {};
+
+ for (var i = 0; i < data.length - 1; i++) {
+ var interval = data[i + 1].x - data[i].x;
+ intervalCounts[interval] = intervalCounts[interval] || 0;
+ intervalCounts[interval]++;
+ }
+
+ var frequentInterval = { count: 0 };
+
+ Rickshaw.keys(intervalCounts).forEach( function(i) {
+ if (frequentInterval.count < intervalCounts[i]) {
+
+ frequentInterval = {
+ count: intervalCounts[i],
+ magnitude: i
+ };
+ }
+ } );
+
+ this._frequentInterval = function() { return frequentInterval };
+
+ return frequentInterval;
+ }
+} );
+
+Rickshaw.namespace('Rickshaw.Graph.Renderer.Area');
+
+Rickshaw.Graph.Renderer.Area = Rickshaw.Class.create( Rickshaw.Graph.Renderer, {
+
+ name: 'area',
+
+ defaults: function($super) {
+
+ return Rickshaw.extend( $super(), {
+ unstack: false,
+ fill: false,
+ stroke: false
+ } );
+ },
+
+ seriesPathFactory: function() {
+
+ var graph = this.graph;
+
+ return d3.svg.area()
+ .x( function(d) { return graph.x(d.x) } )
+ .y0( function(d) { return graph.y(d.y0) } )
+ .y1( function(d) { return graph.y(d.y + d.y0) } )
+ .interpolate(graph.interpolation).tension(this.tension);
+ },
+
+ seriesStrokeFactory: function() {
+
+ var graph = this.graph;
+
+ return d3.svg.line()
+ .x( function(d) { return graph.x(d.x) } )
+ .y( function(d) { return graph.y(d.y + d.y0) } )
+ .interpolate(graph.interpolation).tension(this.tension);
+ },
+
+ render: function() {
+
+ var graph = this.graph;
+
+ graph.vis.selectAll('*').remove();
+
+ var nodes = graph.vis.selectAll("path")
+ .data(this.graph.stackedData)
+ .enter().insert("svg:g", 'g');
+
+ nodes.append("svg:path")
+ .attr("d", this.seriesPathFactory())
+ .attr("class", 'area');
+
+ if (this.stroke) {
+ nodes.append("svg:path")
+ .attr("d", this.seriesStrokeFactory())
+ .attr("class", 'line');
+ }
+
+ var i = 0;
+ graph.series.forEach( function(series) {
+ if (series.disabled) return;
+ series.path = nodes[0][i++];
+ this._styleSeries(series);
+ }, this );
+ },
+
+ _styleSeries: function(series) {
+
+ if (!series.path) return;
+
+ d3.select(series.path).select('.area')
+ .attr('fill', series.color);
+
+ if (this.stroke) {
+ d3.select(series.path).select('.line')
+ .attr('fill', 'none')
+ .attr('stroke', series.stroke || d3.interpolateRgb(series.color, 'black')(0.125))
+ .attr('stroke-width', this.strokeWidth);
+ }
+
+ if (series.className) {
+ series.path.setAttribute('class', series.className);
+ }
+ }
+} );
+
+Rickshaw.namespace('Rickshaw.Graph.Renderer.ScatterPlot');
+
+Rickshaw.Graph.Renderer.ScatterPlot = Rickshaw.Class.create( Rickshaw.Graph.Renderer, {
+
+ name: 'scatterplot',
+
+ defaults: function($super) {
+
+ return Rickshaw.extend( $super(), {
+ unstack: true,
+ fill: true,
+ stroke: false,
+ padding:{ top: 0.01, right: 0.01, bottom: 0.01, left: 0.01 },
+ dotSize: 4
+ } );
+ },
+
+ initialize: function($super, args) {
+ $super(args);
+ },
+
+ render: function() {
+
+ var graph = this.graph;
+
+ graph.vis.selectAll('*').remove();
+
+ graph.series.forEach( function(series) {
+
+ if (series.disabled) return;
+
+ var nodes = graph.vis.selectAll("path")
+ .data(series.stack)
+ .enter().append("svg:circle")
+ .attr("cx", function(d) { return graph.x(d.x) })
+ .attr("cy", function(d) { return graph.y(d.y) })
+ .attr("r", function(d) { return ("r" in d) ? d.r : graph.renderer.dotSize});
+
+ Array.prototype.forEach.call(nodes[0], function(n) {
+ n.setAttribute('fill', series.color);
+ } );
+
+ }, this );
+ }
+} );
+Rickshaw.namespace('Rickshaw.Graph.Smoother');
+
+Rickshaw.Graph.Smoother = function(args) {
+
+ this.graph = args.graph;
+ this.element = args.element;
+
+ var self = this;
+
+ this.aggregationScale = 1;
+
+ if (this.element) {
+
+ $( function() {
+ $(self.element).slider( {
+ min: 1,
+ max: 100,
+ slide: function( event, ui ) {
+ self.setScale(ui.value);
+ self.graph.update();
+ }
+ } );
+ } );
+ }
+
+ self.graph.stackData.hooks.data.push( {
+ name: 'smoother',
+ orderPosition: 50,
+ f: function(data) {
+
+ var aggregatedData = [];
+
+ data.forEach( function(seriesData) {
+
+ var aggregatedSeriesData = [];
+
+ while (seriesData.length) {
+
+ var avgX = 0, avgY = 0;
+ var slice = seriesData.splice(0, self.aggregationScale);
+
+ slice.forEach( function(d) {
+ avgX += d.x / slice.length;
+ avgY += d.y / slice.length;
+ } );
+
+ aggregatedSeriesData.push( { x: avgX, y: avgY } );
+ }
+
+ aggregatedData.push(aggregatedSeriesData);
+ } );
+
+ return aggregatedData;
+ }
+ } );
+
+ this.setScale = function(scale) {
+
+ if (scale < 1) {
+ throw "scale out of range: " + scale;
+ }
+
+ this.aggregationScale = scale;
+ this.graph.update();
+ }
+};
+
+Rickshaw.namespace('Rickshaw.Graph.Unstacker');
+
+Rickshaw.Graph.Unstacker = function(args) {
+
+ this.graph = args.graph;
+ var self = this;
+
+ this.graph.stackData.hooks.after.push( {
+ name: 'unstacker',
+ f: function(data) {
+
+ if (!self.graph.renderer.unstack) return data;
+
+ data.forEach( function(seriesData) {
+ seriesData.forEach( function(d) {
+ d.y0 = 0;
+ } );
+ } );
+
+ return data;
+ }
+ } );
+};
+
+Rickshaw.namespace('Rickshaw.Series');
+
+Rickshaw.Series = Rickshaw.Class.create( Array, {
+
+ initialize: function (data, palette, options) {
+
+ options = options || {}
+
+ this.palette = new Rickshaw.Color.Palette(palette);
+
+ this.timeBase = typeof(options.timeBase) === 'undefined' ?
+ Math.floor(new Date().getTime() / 1000) :
+ options.timeBase;
+
+ var timeInterval = typeof(options.timeInterval) == 'undefined' ?
+ 1000 :
+ options.timeInterval;
+
+ this.setTimeInterval(timeInterval);
+
+ if (data && (typeof(data) == "object") && (data instanceof Array)) {
+ data.forEach( function(item) { this.addItem(item) }, this );
+ }
+ },
+
+ addItem: function(item) {
+
+ if (typeof(item.name) === 'undefined') {
+ throw('addItem() needs a name');
+ }
+
+ item.color = (item.color || this.palette.color(item.name));
+ item.data = (item.data || []);
+
+ // backfill, if necessary
+ if ((item.data.length == 0) && this.length && (this.getIndex() > 0)) {
+ this[0].data.forEach( function(plot) {
+ item.data.push({ x: plot.x, y: 0 });
+ } );
+ } else if (item.data.length == 0) {
+ item.data.push({ x: this.timeBase - (this.timeInterval || 0), y: 0 });
+ }
+
+ this.push(item);
+
+ if (this.legend) {
+ this.legend.addLine(this.itemByName(item.name));
+ }
+ },
+
+ addData: function(data) {
+
+ var index = this.getIndex();
+
+ Rickshaw.keys(data).forEach( function(name) {
+ if (! this.itemByName(name)) {
+ this.addItem({ name: name });
+ }
+ }, this );
+
+ this.forEach( function(item) {
+ item.data.push({
+ x: (index * this.timeInterval || 1) + this.timeBase,
+ y: (data[item.name] || 0)
+ });
+ }, this );
+ },
+
+ getIndex: function () {
+ return (this[0] && this[0].data && this[0].data.length) ? this[0].data.length : 0;
+ },
+
+ itemByName: function(name) {
+
+ for (var i = 0; i < this.length; i++) {
+ if (this[i].name == name)
+ return this[i];
+ }
+ },
+
+ setTimeInterval: function(iv) {
+ this.timeInterval = iv / 1000;
+ },
+
+ setTimeBase: function (t) {
+ this.timeBase = t;
+ },
+
+ dump: function() {
+
+ var data = {
+ timeBase: this.timeBase,
+ timeInterval: this.timeInterval,
+ items: []
+ };
+
+ this.forEach( function(item) {
+
+ var newItem = {
+ color: item.color,
+ name: item.name,
+ data: []
+ };
+
+ item.data.forEach( function(plot) {
+ newItem.data.push({ x: plot.x, y: plot.y });
+ } );
+
+ data.items.push(newItem);
+ } );
+
+ return data;
+ },
+
+ load: function(data) {
+
+ if (data.timeInterval) {
+ this.timeInterval = data.timeInterval;
+ }
+
+ if (data.timeBase) {
+ this.timeBase = data.timeBase;
+ }
+
+ if (data.items) {
+ data.items.forEach( function(item) {
+ this.push(item);
+ if (this.legend) {
+ this.legend.addLine(this.itemByName(item.name));
+ }
+
+ }, this );
+ }
+ }
+} );
+
+Rickshaw.Series.zeroFill = function(series) {
+
+ var x;
+ var i = 0;
+
+ var data = series.map( function(s) { return s.data } );
+
+ while ( i < Math.max.apply(null, data.map( function(d) { return d.length } )) ) {
+
+ x = Math.min.apply( null,
+ data
+ .filter(function(d) { return d[i] })
+ .map(function(d) { return d[i].x })
+ );
+
+ data.forEach( function(d) {
+ if (!d[i] || d[i].x != x) {
+ d.splice(i, 0, { x: x, y: 0 });
+ }
+ } );
+
+ i++;
+ }
+};
+Rickshaw.namespace('Rickshaw.Series.FixedDuration');
+
+Rickshaw.Series.FixedDuration = Rickshaw.Class.create(Rickshaw.Series, {
+
+ initialize: function (data, palette, options) {
+
+ var options = options || {}
+
+ if (typeof(options.timeInterval) === 'undefined') {
+ throw new Error('FixedDuration series requires timeInterval');
+ }
+
+ if (typeof(options.maxDataPoints) === 'undefined') {
+ throw new Error('FixedDuration series requires maxDataPoints');
+ }
+
+ this.palette = new Rickshaw.Color.Palette(palette);
+ this.timeBase = typeof(options.timeBase) === 'undefined' ? Math.floor(new Date().getTime() / 1000) : options.timeBase;
+ this.setTimeInterval(options.timeInterval);
+
+ if (this[0] && this[0].data && this[0].data.length) {
+ this.currentSize = this[0].data.length;
+ this.currentIndex = this[0].data.length;
+ } else {
+ this.currentSize = 0;
+ this.currentIndex = 0;
+ }
+
+ this.maxDataPoints = options.maxDataPoints;
+
+
+ if (data && (typeof(data) == "object") && (data instanceof Array)) {
+ data.forEach( function (item) { this.addItem(item) }, this );
+ this.currentSize += 1;
+ this.currentIndex += 1;
+ }
+
+ // reset timeBase for zero-filled values if needed
+ this.timeBase -= (this.maxDataPoints - this.currentSize) * this.timeInterval;
+
+ // zero-fill up to maxDataPoints size if we don't have that much data yet
+ if ((typeof(this.maxDataPoints) !== 'undefined') && (this.currentSize < this.maxDataPoints)) {
+ for (var i = this.maxDataPoints - this.currentSize - 1; i > 0; i--) {
+ this.currentSize += 1;
+ this.currentIndex += 1;
+ this.forEach( function (item) {
+ item.data.unshift({ x: ((i-1) * this.timeInterval || 1) + this.timeBase, y: 0, i: i });
+ }, this );
+ }
+ }
+ },
+
+ addData: function($super, data) {
+
+ $super(data)
+
+ this.currentSize += 1;
+ this.currentIndex += 1;
+
+ if (this.maxDataPoints !== undefined) {
+ while (this.currentSize > this.maxDataPoints) {
+ this.dropData();
+ }
+ }
+ },
+
+ dropData: function() {
+
+ this.forEach(function(item) {
+ item.data.splice(0, 1);
+ } );
+
+ this.currentSize -= 1;
+ },
+
+ getIndex: function () {
+ return this.currentIndex;
+ }
+} );
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/styles/cubism.css
----------------------------------------------------------------------
diff --git a/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/styles/cubism.css b/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/styles/cubism.css
new file mode 100644
index 0000000..b572148
--- /dev/null
+++ b/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/styles/cubism.css
@@ -0,0 +1,82 @@
+/*
+ * D3 visualization components
+ * Styles for Dag viewer and Sankey diagram
+ */
+.wfdag {
+ width: 100%;
+}
+
+#dag_viewer .axis path,
+#dag_viewer .axis line {
+ fill: none;
+ stroke: #000;
+ shape-rendering: crispEdges;
+}
+
+#dag_viewer line.link,
+#dag_viewer path.link {
+ fill: none;
+ stroke: #666;
+ stroke-width: 2.5px;
+}
+
+#dag_viewer line.link.finished,
+#dag_viewer path.link.finished {
+ stroke: #444;
+}
+
+#dag_viewer marker#finished {
+ fill: #444;
+}
+
+#dag_viewer marker#circle {
+ fill: #666;
+ stroke: none;
+}
+
+#dag_viewer line.source.mark,
+#dag_viewer line.target.mark {
+ stroke: #666;
+ stroke-width: 2.5px;
+}
+
+#dag_viewer rect {
+ fill: #ccc;
+ stroke: #333;
+ stroke-width: 1px;
+}
+
+#dag_viewer rect.finished {
+ fill: green;
+ fill-opacity: 0.8;
+}
+
+#dag_viewer text.joblabel {
+ pointer-events: none;
+ text-anchor: middle;
+}
+
+#dag_viewer text.axislabel {
+ pointer-events: none;
+ text-anchor: middle;
+}
+
+#dag_viewer text.shadow {
+ stroke: #fff;
+ stroke-width: 3px;
+ stroke-opacity: .8;
+}
+
+.map, .shuffle, .reduce {
+ fill-opacity: 0.8;
+ stroke-width: 2px;
+}
+
+.allmap, .allshuffle, .allreduce {
+ fill: none;
+ stroke-width: 2px;
+}
+
+.y.axis {
+ font-size: 10px;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/styles/rickshaw.css
----------------------------------------------------------------------
diff --git a/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/styles/rickshaw.css b/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/styles/rickshaw.css
new file mode 100644
index 0000000..9102bd4
--- /dev/null
+++ b/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/styles/rickshaw.css
@@ -0,0 +1,307 @@
+.rickshaw_graph .detail {
+ pointer-events: none;
+ position: absolute;
+ top: 0;
+ z-index: 2;
+ background: rgba(0, 0, 0, 0.1);
+ bottom: 0;
+ width: 1px;
+ transition: opacity 0.25s linear;
+ -moz-transition: opacity 0.25s linear;
+ -o-transition: opacity 0.25s linear;
+ -webkit-transition: opacity 0.25s linear;
+}
+.rickshaw_graph .detail.inactive {
+ opacity: 0;
+}
+.rickshaw_graph .detail .item.active {
+ opacity: 1;
+}
+.rickshaw_graph .detail .x_label {
+ font-family: Arial, sans-serif;
+ border-radius: 3px;
+ padding: 6px;
+ opacity: 0.5;
+ border: 1px solid #e0e0e0;
+ font-size: 12px;
+ position: absolute;
+ background: white;
+ white-space: nowrap;
+}
+.rickshaw_graph .detail .item {
+ position: absolute;
+ z-index: 2;
+ border-radius: 3px;
+ padding: 0.25em;
+ font-size: 12px;
+ font-family: Arial, sans-serif;
+ opacity: 0;
+ background: rgba(0, 0, 0, 0.4);
+ color: white;
+ border: 1px solid rgba(0, 0, 0, 0.4);
+ margin-left: 1em;
+ margin-top: -1em;
+ white-space: nowrap;
+}
+.rickshaw_graph .detail .item.active {
+ opacity: 1;
+ background: rgba(0, 0, 0, 0.8);
+}
+.rickshaw_graph .detail .item:before {
+ content: "\25c2";
+ position: absolute;
+ left: -0.5em;
+ color: rgba(0, 0, 0, 0.7);
+ width: 0;
+}
+.rickshaw_graph .detail .dot {
+ width: 4px;
+ height: 4px;
+ margin-left: -4px;
+ margin-top: -3px;
+ border-radius: 5px;
+ position: absolute;
+ box-shadow: 0 0 2px rgba(0, 0, 0, 0.6);
+ background: white;
+ border-width: 2px;
+ border-style: solid;
+ display: none;
+ background-clip: padding-box;
+}
+.rickshaw_graph .detail .dot.active {
+ display: block;
+}
+/* graph */
+
+.rickshaw_graph {
+ position: relative;
+}
+.rickshaw_graph svg {
+ display: block;
+ overflow: hidden;
+}
+
+/* ticks */
+
+.rickshaw_graph .x_tick {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ width: 0px;
+ border-left: 1px dotted rgba(0, 0, 0, 0.2);
+ pointer-events: none;
+}
+.rickshaw_graph .x_tick .title {
+ position: absolute;
+ font-size: 12px;
+ font-family: Arial, sans-serif;
+ opacity: 0.5;
+ white-space: nowrap;
+ margin-left: 3px;
+ bottom: 1px;
+}
+
+/* annotations */
+
+.rickshaw_annotation_timeline {
+ height: 1px;
+ border-top: 1px solid #e0e0e0;
+ margin-top: 10px;
+ position: relative;
+}
+.rickshaw_annotation_timeline .annotation {
+ position: absolute;
+ height: 6px;
+ width: 6px;
+ margin-left: -2px;
+ top: -3px;
+ border-radius: 5px;
+ background-color: rgba(0, 0, 0, 0.25);
+}
+.rickshaw_graph .annotation_line {
+ position: absolute;
+ top: 0;
+ bottom: -6px;
+ width: 0px;
+ border-left: 2px solid rgba(0, 0, 0, 0.3);
+ display: none;
+}
+.rickshaw_graph .annotation_line.active {
+ display: block;
+}
+
+.rickshaw_graph .annotation_range {
+ background: rgba(0, 0, 0, 0.1);
+ display: none;
+ position: absolute;
+ top: 0;
+ bottom: -6px;
+ z-index: -10;
+}
+.rickshaw_graph .annotation_range.active {
+ display: block;
+}
+.rickshaw_graph .annotation_range.active.offscreen {
+ display: none;
+}
+
+.rickshaw_annotation_timeline .annotation .content {
+ background: white;
+ color: black;
+ opacity: 0.9;
+ padding: 5px 5px;
+ box-shadow: 0 0 2px rgba(0, 0, 0, 0.8);
+ border-radius: 3px;
+ position: relative;
+ z-index: 20;
+ font-size: 12px;
+ padding: 6px 8px 8px;
+ top: 18px;
+ left: -11px;
+ width: 160px;
+ display: none;
+ cursor: pointer;
+}
+.rickshaw_annotation_timeline .annotation .content:before {
+ content: "\25b2";
+ position: absolute;
+ top: -11px;
+ color: white;
+ text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.8);
+}
+.rickshaw_annotation_timeline .annotation.active,
+.rickshaw_annotation_timeline .annotation:hover {
+ background-color: rgba(0, 0, 0, 0.8);
+ cursor: none;
+}
+.rickshaw_annotation_timeline .annotation .content:hover {
+ z-index: 50;
+}
+.rickshaw_annotation_timeline .annotation.active .content {
+ display: block;
+}
+.rickshaw_annotation_timeline .annotation:hover .content {
+ display: block;
+ z-index: 50;
+}
+.rickshaw_graph .y_axis {
+ fill: none;
+}
+.rickshaw_graph .y_ticks .tick {
+ stroke: rgba(0, 0, 0, 0.16);
+ stroke-width: 2px;
+ shape-rendering: crisp-edges;
+ pointer-events: none;
+}
+.rickshaw_graph .y_grid .tick {
+ z-index: -1;
+ stroke: rgba(0, 0, 0, 0.20);
+ stroke-width: 1px;
+ stroke-dasharray: 1 1;
+}
+.rickshaw_graph .y_grid path {
+ fill: none;
+ stroke: none;
+}
+.rickshaw_graph .y_ticks path {
+ fill: none;
+ stroke: #808080;
+}
+.rickshaw_graph .y_ticks text {
+ opacity: 0.5;
+ font-size: 12px;
+ pointer-events: none;
+}
+.rickshaw_graph .x_tick.glow .title,
+.rickshaw_graph .y_ticks.glow text {
+ fill: black;
+ color: black;
+ text-shadow:
+ -1px 1px 0 rgba(255, 255, 255, 0.1),
+ 1px -1px 0 rgba(255, 255, 255, 0.1),
+ 1px 1px 0 rgba(255, 255, 255, 0.1),
+ 0px 1px 0 rgba(255, 255, 255, 0.1),
+ 0px -1px 0 rgba(255, 255, 255, 0.1),
+ 1px 0px 0 rgba(255, 255, 255, 0.1),
+ -1px 0px 0 rgba(255, 255, 255, 0.1),
+ -1px -1px 0 rgba(255, 255, 255, 0.1);
+}
+.rickshaw_graph .x_tick.inverse .title,
+.rickshaw_graph .y_ticks.inverse text {
+ fill: white;
+ color: white;
+ text-shadow:
+ -1px 1px 0 rgba(0, 0, 0, 0.8),
+ 1px -1px 0 rgba(0, 0, 0, 0.8),
+ 1px 1px 0 rgba(0, 0, 0, 0.8),
+ 0px 1px 0 rgba(0, 0, 0, 0.8),
+ 0px -1px 0 rgba(0, 0, 0, 0.8),
+ 1px 0px 0 rgba(0, 0, 0, 0.8),
+ -1px 0px 0 rgba(0, 0, 0, 0.8),
+ -1px -1px 0 rgba(0, 0, 0, 0.8);
+}
+.rickshaw_legend {
+ font-family: Arial;
+ font-size: 12px;
+ color: white;
+ background: #404040;
+ display: inline-block;
+ padding: 12px 5px;
+ border-radius: 2px;
+ position: relative;
+}
+.rickshaw_legend:hover {
+ z-index: 10;
+}
+.rickshaw_legend .swatch {
+ width: 10px;
+ height: 10px;
+ border: 1px solid rgba(0, 0, 0, 0.2);
+}
+.rickshaw_legend .line {
+ clear: both;
+ line-height: 140%;
+ padding-right: 15px;
+}
+.rickshaw_legend .line .swatch {
+ display: inline-block;
+ margin-right: 3px;
+ border-radius: 2px;
+}
+.rickshaw_legend .label {
+ white-space: nowrap;
+ display: inline;
+}
+.rickshaw_legend .action:hover {
+ opacity: 0.6;
+}
+.rickshaw_legend .action {
+ margin-right: 0.2em;
+ font-size: 10px;
+ opacity: 0.2;
+ cursor: pointer;
+ font-size: 14px;
+}
+.rickshaw_legend .line.disabled {
+ opacity: 0.4;
+}
+.rickshaw_legend ul {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+ margin: 2px;
+ cursor: pointer;
+}
+.rickshaw_legend li {
+ padding: 0 0 0 2px;
+ min-width: 80px;
+ white-space: nowrap;
+}
+.rickshaw_legend li:hover {
+ background: rgba(255, 255, 255, 0.08);
+ border-radius: 3px;
+}
+.rickshaw_legend li:active {
+ background: rgba(255, 255, 255, 0.2);
+ border-radius: 3px;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/contrib/views/slider/src/main/resources/ui/app/assets/data/apps/apps.json
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/assets/data/apps/apps.json b/contrib/views/slider/src/main/resources/ui/app/assets/data/apps/apps.json
index 7a00c14..fccb7a5 100644
--- a/contrib/views/slider/src/main/resources/ui/app/assets/data/apps/apps.json
+++ b/contrib/views/slider/src/main/resources/ui/app/assets/data/apps/apps.json
@@ -59,6 +59,16 @@
"version" : "1.0.0",
"view_name" : "SLIDER",
"yarnId" : "application_1401266754647_0003",
+ "metrics" : {
+ "metric1" : "",
+ "metric2" : "",
+ "metric3" : "",
+ "metric4" : "",
+ "metric5" : "",
+ "metric6" : "",
+ "metric7" : "",
+ "metric8" : ""
+ },
"components" : {
"HBASE_MASTER" : {
"componentName" : "HBASE_MASTER",
@@ -228,7 +238,18 @@
"yarn.timeline-service.webapp.https.address" : "c6401.ambari.apache.org:8190"
}
},
- "jmx" : { },
+ "jmx" : {
+ "ClusterId" : "67ee848a-8576-45d3-9b18-cdda4eb6c025",
+ "DeadRegionServers" : "1",
+ "IsActiveMaster" : "true",
+ "MasterActiveTime" : "1401332251511",
+ "MasterStartTime" : "1401332248911",
+ "RegionServers" : "1",
+ "ServerName" : "c6401.ambari.apache.org,60000,1401332245896",
+ "ZookeeperQuorum" : "c6401.ambari.apache.org:2181",
+ "cluster_requests" : "14496",
+ "metricAverageLoad" : "2.0"
+ },
"urls" : {
"JMX" : "http://c6401.ambari.apache.org:39505/jmx",
"Metrics" : "http://c6401.ambari.apache.org/cgi-bin/rrd.py?c=Application1",
@@ -236,4 +257,4 @@
}
}
]
-}
\ No newline at end of file
+}
[8/8] git commit: AMBARI-5928. Create and populate Metrics section of
a slider app. (onechiporenko)
Posted by on...@apache.org.
AMBARI-5928. Create and populate Metrics section of a slider app. (onechiporenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/79f3a1a3
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/79f3a1a3
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/79f3a1a3
Branch: refs/heads/branch-1.6.0.slider
Commit: 79f3a1a3d1c4908923899e1aadc949d20d86abe7
Parents: 71aa923
Author: Oleg Nechiporenko <on...@apache.org>
Authored: Thu May 29 20:44:53 2014 +0300
Committer: Oleg Nechiporenko <on...@apache.org>
Committed: Thu May 29 20:44:53 2014 +0300
----------------------------------------------------------------------
.../ui/app/assets/data/metrics/metric.json | 2818 +++++++
.../ui/app/assets/data/metrics/metric2.json | 3838 ++++++++++
.../ui/app/assets/data/metrics/metric3.json | 1856 +++++
.../ui/app/assets/data/metrics/metric4.json | 968 +++
.../slider_app/summary_controller.js | 23 +
.../resources/ui/app/helpers/string_utils.js | 163 +
.../resources/ui/app/templates/common/chart.hbs | 26 +
.../resources/ui/app/views/common/chart_view.js | 915 +++
.../views/slider_app/metrics/metric2_view.js | 63 +
.../views/slider_app/metrics/metric3_view.js | 61 +
.../views/slider_app/metrics/metric4_view.js | 54 +
.../app/views/slider_app/metrics/metric_view.js | 70 +
.../ui/app/views/slider_app/summary_view.js | 27 +
.../ui/vendor/scripts/common/cubism.v1.js | 1085 +++
.../resources/ui/vendor/scripts/common/d3.v2.js | 7033 ++++++++++++++++++
.../ui/vendor/scripts/common/jquery.ui.core.js | 334 +
.../ui/vendor/scripts/common/jquery.ui.mouse.js | 175 +
.../vendor/scripts/common/jquery.ui.sortable.js | 1088 +++
.../vendor/scripts/common/jquery.ui.widget.js | 276 +
.../ui/vendor/scripts/common/rickshaw.js | 2659 +++++++
.../main/resources/ui/vendor/styles/cubism.css | 82 +
.../resources/ui/vendor/styles/rickshaw.css | 307 +
.../resources/ui/app/assets/data/apps/apps.json | 25 +-
.../ui/app/assets/data/apptypes/all_fields.json | 296 +-
.../ui/app/controllers/slider_app_controller.js | 1 -
.../src/main/resources/ui/app/helpers/ajax.js | 21 +
.../src/main/resources/ui/app/helpers/helper.js | 41 +
.../ui/app/mappers/slider_apps_mapper.js | 13 +-
.../main/resources/ui/app/models/slider_app.js | 18 +-
.../src/main/resources/ui/app/routes/main.js | 6 +-
.../resources/ui/app/styles/application.less | 92 +-
.../ui/app/templates/slider_app/configs.hbs | 8 +-
.../ui/app/templates/slider_app/summary.hbs | 25 +-
.../slider/src/main/resources/ui/config.js | 12 +
.../slider/src/main/resources/ui/package.json | 1 -
35 files changed, 24436 insertions(+), 44 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/ambari-web/contrib/views/slider/src/main/resources/ui/app/assets/data/metrics/metric.json
----------------------------------------------------------------------
diff --git a/ambari-web/contrib/views/slider/src/main/resources/ui/app/assets/data/metrics/metric.json b/ambari-web/contrib/views/slider/src/main/resources/ui/app/assets/data/metrics/metric.json
new file mode 100644
index 0000000..38fc817
--- /dev/null
+++ b/ambari-web/contrib/views/slider/src/main/resources/ui/app/assets/data/metrics/metric.json
@@ -0,0 +1,2818 @@
+{
+ "metrics" : {
+ "dfs" : {
+ "FSNamesystem" : {
+ "CapacityRemainingGB" : [
+ [
+ 5.0,
+ 1401351555
+ ],
+ [
+ 5.0,
+ 1401351570
+ ],
+ [
+ 5.0,
+ 1401351585
+ ],
+ [
+ 5.0,
+ 1401351600
+ ],
+ [
+ 5.0,
+ 1401351615
+ ],
+ [
+ 5.0,
+ 1401351630
+ ],
+ [
+ 5.0,
+ 1401351645
+ ],
+ [
+ 5.0,
+ 1401351660
+ ],
+ [
+ 5.0,
+ 1401351675
+ ],
+ [
+ 5.0,
+ 1401351690
+ ],
+ [
+ 5.0,
+ 1401351705
+ ],
+ [
+ 5.0,
+ 1401351720
+ ],
+ [
+ 5.0,
+ 1401351735
+ ],
+ [
+ 5.0,
+ 1401351750
+ ],
+ [
+ 5.0,
+ 1401351765
+ ],
+ [
+ 5.0,
+ 1401351780
+ ],
+ [
+ 5.0,
+ 1401351795
+ ],
+ [
+ 5.0,
+ 1401351810
+ ],
+ [
+ 5.0,
+ 1401351825
+ ],
+ [
+ 5.0,
+ 1401351840
+ ],
+ [
+ 5.0,
+ 1401351855
+ ],
+ [
+ 5.0,
+ 1401351870
+ ],
+ [
+ 5.0,
+ 1401351885
+ ],
+ [
+ 5.0,
+ 1401351900
+ ],
+ [
+ 5.0,
+ 1401351915
+ ],
+ [
+ 5.0,
+ 1401351930
+ ],
+ [
+ 5.0,
+ 1401351945
+ ],
+ [
+ 5.0,
+ 1401351960
+ ],
+ [
+ 5.0,
+ 1401351975
+ ],
+ [
+ 5.0,
+ 1401351990
+ ],
+ [
+ 5.0,
+ 1401352005
+ ],
+ [
+ 5.0,
+ 1401352020
+ ],
+ [
+ 5.0,
+ 1401352035
+ ],
+ [
+ 5.0,
+ 1401352050
+ ],
+ [
+ 5.0,
+ 1401352065
+ ],
+ [
+ 5.0,
+ 1401352080
+ ],
+ [
+ 5.0,
+ 1401352095
+ ],
+ [
+ 5.0,
+ 1401352110
+ ],
+ [
+ 5.0,
+ 1401352125
+ ],
+ [
+ 5.0,
+ 1401352140
+ ],
+ [
+ 5.0,
+ 1401352155
+ ],
+ [
+ 5.0,
+ 1401352170
+ ],
+ [
+ 5.0,
+ 1401352185
+ ],
+ [
+ 5.0,
+ 1401352200
+ ],
+ [
+ 5.0,
+ 1401352215
+ ],
+ [
+ 5.0,
+ 1401352230
+ ],
+ [
+ 5.0,
+ 1401352245
+ ],
+ [
+ 5.0,
+ 1401352260
+ ],
+ [
+ 5.0,
+ 1401352275
+ ],
+ [
+ 5.0,
+ 1401352290
+ ],
+ [
+ 5.0,
+ 1401352305
+ ],
+ [
+ 5.0,
+ 1401352320
+ ],
+ [
+ 5.0,
+ 1401352335
+ ],
+ [
+ 5.0,
+ 1401352350
+ ],
+ [
+ 5.0,
+ 1401352365
+ ],
+ [
+ 5.0,
+ 1401352380
+ ],
+ [
+ 5.0,
+ 1401352395
+ ],
+ [
+ 5.0,
+ 1401352410
+ ],
+ [
+ 5.0,
+ 1401352425
+ ],
+ [
+ 5.0,
+ 1401352440
+ ],
+ [
+ 5.0,
+ 1401352455
+ ],
+ [
+ 5.0,
+ 1401352470
+ ],
+ [
+ 5.0,
+ 1401352485
+ ],
+ [
+ 5.0,
+ 1401352500
+ ],
+ [
+ 5.0,
+ 1401352515
+ ],
+ [
+ 5.0,
+ 1401352530
+ ],
+ [
+ 5.0,
+ 1401352545
+ ],
+ [
+ 5.0,
+ 1401352560
+ ],
+ [
+ 5.0,
+ 1401352575
+ ],
+ [
+ 5.0,
+ 1401352590
+ ],
+ [
+ 5.0,
+ 1401352605
+ ],
+ [
+ 5.0,
+ 1401352620
+ ],
+ [
+ 5.0,
+ 1401352635
+ ],
+ [
+ 5.0,
+ 1401352650
+ ],
+ [
+ 5.0,
+ 1401352665
+ ],
+ [
+ 5.0,
+ 1401352680
+ ],
+ [
+ 5.0,
+ 1401352695
+ ],
+ [
+ 5.0,
+ 1401352710
+ ],
+ [
+ 5.0,
+ 1401352725
+ ],
+ [
+ 5.0,
+ 1401352740
+ ],
+ [
+ 5.0,
+ 1401352755
+ ],
+ [
+ 5.0,
+ 1401352770
+ ],
+ [
+ 5.0,
+ 1401352785
+ ],
+ [
+ 5.0,
+ 1401352800
+ ],
+ [
+ 5.0,
+ 1401352815
+ ],
+ [
+ 5.0,
+ 1401352830
+ ],
+ [
+ 5.0,
+ 1401352845
+ ],
+ [
+ 5.0,
+ 1401352860
+ ],
+ [
+ 5.0,
+ 1401352875
+ ],
+ [
+ 5.0,
+ 1401352890
+ ],
+ [
+ 5.0,
+ 1401352905
+ ],
+ [
+ 5.0,
+ 1401352920
+ ],
+ [
+ 5.0,
+ 1401352935
+ ],
+ [
+ 5.0,
+ 1401352950
+ ],
+ [
+ 5.0,
+ 1401352965
+ ],
+ [
+ 5.0,
+ 1401352980
+ ],
+ [
+ 5.0,
+ 1401352995
+ ],
+ [
+ 5.0,
+ 1401353010
+ ],
+ [
+ 5.0,
+ 1401353025
+ ],
+ [
+ 5.0,
+ 1401353040
+ ],
+ [
+ 5.0,
+ 1401353055
+ ],
+ [
+ 5.0,
+ 1401353070
+ ],
+ [
+ 5.0,
+ 1401353085
+ ],
+ [
+ 5.0,
+ 1401353100
+ ],
+ [
+ 5.0,
+ 1401353115
+ ],
+ [
+ 5.0,
+ 1401353130
+ ],
+ [
+ 5.0,
+ 1401353145
+ ],
+ [
+ 5.0,
+ 1401353160
+ ],
+ [
+ 5.0,
+ 1401353175
+ ],
+ [
+ 5.0,
+ 1401353190
+ ],
+ [
+ 5.0,
+ 1401353205
+ ],
+ [
+ 5.0,
+ 1401353220
+ ],
+ [
+ 5.0,
+ 1401353235
+ ],
+ [
+ 5.0,
+ 1401353250
+ ],
+ [
+ 5.0,
+ 1401353265
+ ],
+ [
+ 5.0,
+ 1401353280
+ ],
+ [
+ 5.0,
+ 1401353295
+ ],
+ [
+ 5.0,
+ 1401353310
+ ],
+ [
+ 5.0,
+ 1401353325
+ ],
+ [
+ 5.0,
+ 1401353340
+ ],
+ [
+ 5.0,
+ 1401353355
+ ],
+ [
+ 5.0,
+ 1401353370
+ ],
+ [
+ 5.0,
+ 1401353385
+ ],
+ [
+ 5.0,
+ 1401353400
+ ],
+ [
+ 5.0,
+ 1401353415
+ ],
+ [
+ 5.0,
+ 1401353430
+ ],
+ [
+ 5.0,
+ 1401353445
+ ],
+ [
+ 5.0,
+ 1401353460
+ ],
+ [
+ 5.0,
+ 1401353475
+ ],
+ [
+ 5.0,
+ 1401353490
+ ],
+ [
+ 5.0,
+ 1401353505
+ ],
+ [
+ 5.0,
+ 1401353520
+ ],
+ [
+ 5.0,
+ 1401353535
+ ],
+ [
+ 5.0,
+ 1401353550
+ ],
+ [
+ 5.0,
+ 1401353565
+ ],
+ [
+ 5.0,
+ 1401353580
+ ],
+ [
+ 5.0,
+ 1401353595
+ ],
+ [
+ 5.0,
+ 1401353610
+ ],
+ [
+ 5.0,
+ 1401353625
+ ],
+ [
+ 5.0,
+ 1401353640
+ ],
+ [
+ 5.0,
+ 1401353655
+ ],
+ [
+ 5.0,
+ 1401353670
+ ],
+ [
+ 5.0,
+ 1401353685
+ ],
+ [
+ 5.0,
+ 1401353700
+ ],
+ [
+ 5.0,
+ 1401353715
+ ],
+ [
+ 5.0,
+ 1401353730
+ ],
+ [
+ 5.0,
+ 1401353745
+ ],
+ [
+ 5.0,
+ 1401353760
+ ],
+ [
+ 5.0,
+ 1401353775
+ ],
+ [
+ 5.0,
+ 1401353790
+ ],
+ [
+ 5.0,
+ 1401353805
+ ],
+ [
+ 5.0,
+ 1401353820
+ ],
+ [
+ 5.0,
+ 1401353835
+ ],
+ [
+ 5.0,
+ 1401353850
+ ],
+ [
+ 5.0,
+ 1401353865
+ ],
+ [
+ 5.0,
+ 1401353880
+ ],
+ [
+ 5.0,
+ 1401353895
+ ],
+ [
+ 5.0,
+ 1401353910
+ ],
+ [
+ 5.0,
+ 1401353925
+ ],
+ [
+ 5.0,
+ 1401353940
+ ],
+ [
+ 5.0,
+ 1401353955
+ ],
+ [
+ 5.0,
+ 1401353970
+ ],
+ [
+ 5.0,
+ 1401353985
+ ],
+ [
+ 5.0,
+ 1401354000
+ ],
+ [
+ 5.0,
+ 1401354015
+ ],
+ [
+ 5.0,
+ 1401354030
+ ],
+ [
+ 5.0,
+ 1401354045
+ ],
+ [
+ 5.0,
+ 1401354060
+ ],
+ [
+ 5.0,
+ 1401354075
+ ],
+ [
+ 5.0,
+ 1401354090
+ ],
+ [
+ 5.0,
+ 1401354105
+ ],
+ [
+ 5.0,
+ 1401354120
+ ],
+ [
+ 5.0,
+ 1401354135
+ ],
+ [
+ 5.0,
+ 1401354150
+ ],
+ [
+ 5.0,
+ 1401354165
+ ],
+ [
+ 5.0,
+ 1401354180
+ ],
+ [
+ 5.0,
+ 1401354195
+ ],
+ [
+ 5.0,
+ 1401354210
+ ],
+ [
+ 5.0,
+ 1401354225
+ ],
+ [
+ 5.0,
+ 1401354240
+ ],
+ [
+ 5.0,
+ 1401354255
+ ],
+ [
+ 5.0,
+ 1401354270
+ ],
+ [
+ 5.0,
+ 1401354285
+ ],
+ [
+ 5.0,
+ 1401354300
+ ],
+ [
+ 5.0,
+ 1401354315
+ ],
+ [
+ 5.0,
+ 1401354330
+ ],
+ [
+ 5.0,
+ 1401354345
+ ],
+ [
+ 5.0,
+ 1401354360
+ ],
+ [
+ 5.0,
+ 1401354375
+ ],
+ [
+ 5.0,
+ 1401354390
+ ],
+ [
+ 5.0,
+ 1401354405
+ ],
+ [
+ 5.0,
+ 1401354420
+ ],
+ [
+ 5.0,
+ 1401354435
+ ],
+ [
+ 5.0,
+ 1401354450
+ ],
+ [
+ 5.0,
+ 1401354465
+ ],
+ [
+ 5.0,
+ 1401354480
+ ],
+ [
+ 5.0,
+ 1401354495
+ ],
+ [
+ 5.0,
+ 1401354510
+ ],
+ [
+ 5.0,
+ 1401354525
+ ],
+ [
+ 5.0,
+ 1401354540
+ ],
+ [
+ 5.0,
+ 1401354555
+ ],
+ [
+ 5.0,
+ 1401354570
+ ],
+ [
+ 5.0,
+ 1401354585
+ ],
+ [
+ 5.0,
+ 1401354600
+ ],
+ [
+ 5.0,
+ 1401354615
+ ],
+ [
+ 5.0,
+ 1401354630
+ ],
+ [
+ 5.0,
+ 1401354645
+ ],
+ [
+ 5.0,
+ 1401354660
+ ],
+ [
+ 5.0,
+ 1401354675
+ ],
+ [
+ 5.0,
+ 1401354690
+ ],
+ [
+ 5.0,
+ 1401354705
+ ],
+ [
+ 5.0,
+ 1401354720
+ ],
+ [
+ 5.0,
+ 1401354735
+ ],
+ [
+ 5.0,
+ 1401354750
+ ],
+ [
+ 5.0,
+ 1401354765
+ ],
+ [
+ 5.0,
+ 1401354780
+ ],
+ [
+ 5.0,
+ 1401354795
+ ],
+ [
+ 5.0,
+ 1401354810
+ ],
+ [
+ 5.0,
+ 1401354825
+ ],
+ [
+ 5.0,
+ 1401354840
+ ],
+ [
+ 5.0,
+ 1401354855
+ ],
+ [
+ 5.0,
+ 1401354870
+ ],
+ [
+ 5.0,
+ 1401354885
+ ],
+ [
+ 5.0,
+ 1401354900
+ ],
+ [
+ 5.0,
+ 1401354915
+ ],
+ [
+ 5.0,
+ 1401354930
+ ],
+ [
+ 5.0,
+ 1401354945
+ ],
+ [
+ 5.0,
+ 1401354960
+ ],
+ [
+ 5.0,
+ 1401354975
+ ],
+ [
+ 5.0,
+ 1401354990
+ ],
+ [
+ 5.0,
+ 1401355005
+ ],
+ [
+ 5.0,
+ 1401355020
+ ],
+ [
+ 5.0,
+ 1401355035
+ ],
+ [
+ 5.0,
+ 1401355050
+ ],
+ [
+ 5.0,
+ 1401355065
+ ]
+ ],
+ "CapacityTotalGB" : [
+ [
+ 9.0,
+ 1401351555
+ ],
+ [
+ 9.0,
+ 1401351570
+ ],
+ [
+ 9.0,
+ 1401351585
+ ],
+ [
+ 9.0,
+ 1401351600
+ ],
+ [
+ 9.0,
+ 1401351615
+ ],
+ [
+ 9.0,
+ 1401351630
+ ],
+ [
+ 9.0,
+ 1401351645
+ ],
+ [
+ 9.0,
+ 1401351660
+ ],
+ [
+ 9.0,
+ 1401351675
+ ],
+ [
+ 9.0,
+ 1401351690
+ ],
+ [
+ 9.0,
+ 1401351705
+ ],
+ [
+ 9.0,
+ 1401351720
+ ],
+ [
+ 9.0,
+ 1401351735
+ ],
+ [
+ 9.0,
+ 1401351750
+ ],
+ [
+ 9.0,
+ 1401351765
+ ],
+ [
+ 9.0,
+ 1401351780
+ ],
+ [
+ 9.0,
+ 1401351795
+ ],
+ [
+ 9.0,
+ 1401351810
+ ],
+ [
+ 9.0,
+ 1401351825
+ ],
+ [
+ 9.0,
+ 1401351840
+ ],
+ [
+ 9.0,
+ 1401351855
+ ],
+ [
+ 9.0,
+ 1401351870
+ ],
+ [
+ 9.0,
+ 1401351885
+ ],
+ [
+ 9.0,
+ 1401351900
+ ],
+ [
+ 9.0,
+ 1401351915
+ ],
+ [
+ 9.0,
+ 1401351930
+ ],
+ [
+ 9.0,
+ 1401351945
+ ],
+ [
+ 9.0,
+ 1401351960
+ ],
+ [
+ 9.0,
+ 1401351975
+ ],
+ [
+ 9.0,
+ 1401351990
+ ],
+ [
+ 9.0,
+ 1401352005
+ ],
+ [
+ 9.0,
+ 1401352020
+ ],
+ [
+ 9.0,
+ 1401352035
+ ],
+ [
+ 9.0,
+ 1401352050
+ ],
+ [
+ 9.0,
+ 1401352065
+ ],
+ [
+ 9.0,
+ 1401352080
+ ],
+ [
+ 9.0,
+ 1401352095
+ ],
+ [
+ 9.0,
+ 1401352110
+ ],
+ [
+ 9.0,
+ 1401352125
+ ],
+ [
+ 9.0,
+ 1401352140
+ ],
+ [
+ 9.0,
+ 1401352155
+ ],
+ [
+ 9.0,
+ 1401352170
+ ],
+ [
+ 9.0,
+ 1401352185
+ ],
+ [
+ 9.0,
+ 1401352200
+ ],
+ [
+ 9.0,
+ 1401352215
+ ],
+ [
+ 9.0,
+ 1401352230
+ ],
+ [
+ 9.0,
+ 1401352245
+ ],
+ [
+ 9.0,
+ 1401352260
+ ],
+ [
+ 9.0,
+ 1401352275
+ ],
+ [
+ 9.0,
+ 1401352290
+ ],
+ [
+ 9.0,
+ 1401352305
+ ],
+ [
+ 9.0,
+ 1401352320
+ ],
+ [
+ 9.0,
+ 1401352335
+ ],
+ [
+ 9.0,
+ 1401352350
+ ],
+ [
+ 9.0,
+ 1401352365
+ ],
+ [
+ 9.0,
+ 1401352380
+ ],
+ [
+ 9.0,
+ 1401352395
+ ],
+ [
+ 9.0,
+ 1401352410
+ ],
+ [
+ 9.0,
+ 1401352425
+ ],
+ [
+ 9.0,
+ 1401352440
+ ],
+ [
+ 9.0,
+ 1401352455
+ ],
+ [
+ 9.0,
+ 1401352470
+ ],
+ [
+ 9.0,
+ 1401352485
+ ],
+ [
+ 9.0,
+ 1401352500
+ ],
+ [
+ 9.0,
+ 1401352515
+ ],
+ [
+ 9.0,
+ 1401352530
+ ],
+ [
+ 9.0,
+ 1401352545
+ ],
+ [
+ 9.0,
+ 1401352560
+ ],
+ [
+ 9.0,
+ 1401352575
+ ],
+ [
+ 9.0,
+ 1401352590
+ ],
+ [
+ 9.0,
+ 1401352605
+ ],
+ [
+ 9.0,
+ 1401352620
+ ],
+ [
+ 9.0,
+ 1401352635
+ ],
+ [
+ 9.0,
+ 1401352650
+ ],
+ [
+ 9.0,
+ 1401352665
+ ],
+ [
+ 9.0,
+ 1401352680
+ ],
+ [
+ 9.0,
+ 1401352695
+ ],
+ [
+ 9.0,
+ 1401352710
+ ],
+ [
+ 9.0,
+ 1401352725
+ ],
+ [
+ 9.0,
+ 1401352740
+ ],
+ [
+ 9.0,
+ 1401352755
+ ],
+ [
+ 9.0,
+ 1401352770
+ ],
+ [
+ 9.0,
+ 1401352785
+ ],
+ [
+ 9.0,
+ 1401352800
+ ],
+ [
+ 9.0,
+ 1401352815
+ ],
+ [
+ 9.0,
+ 1401352830
+ ],
+ [
+ 9.0,
+ 1401352845
+ ],
+ [
+ 9.0,
+ 1401352860
+ ],
+ [
+ 9.0,
+ 1401352875
+ ],
+ [
+ 9.0,
+ 1401352890
+ ],
+ [
+ 9.0,
+ 1401352905
+ ],
+ [
+ 9.0,
+ 1401352920
+ ],
+ [
+ 9.0,
+ 1401352935
+ ],
+ [
+ 9.0,
+ 1401352950
+ ],
+ [
+ 9.0,
+ 1401352965
+ ],
+ [
+ 9.0,
+ 1401352980
+ ],
+ [
+ 9.0,
+ 1401352995
+ ],
+ [
+ 9.0,
+ 1401353010
+ ],
+ [
+ 9.0,
+ 1401353025
+ ],
+ [
+ 9.0,
+ 1401353040
+ ],
+ [
+ 9.0,
+ 1401353055
+ ],
+ [
+ 9.0,
+ 1401353070
+ ],
+ [
+ 9.0,
+ 1401353085
+ ],
+ [
+ 9.0,
+ 1401353100
+ ],
+ [
+ 9.0,
+ 1401353115
+ ],
+ [
+ 9.0,
+ 1401353130
+ ],
+ [
+ 9.0,
+ 1401353145
+ ],
+ [
+ 9.0,
+ 1401353160
+ ],
+ [
+ 9.0,
+ 1401353175
+ ],
+ [
+ 9.0,
+ 1401353190
+ ],
+ [
+ 9.0,
+ 1401353205
+ ],
+ [
+ 9.0,
+ 1401353220
+ ],
+ [
+ 9.0,
+ 1401353235
+ ],
+ [
+ 9.0,
+ 1401353250
+ ],
+ [
+ 9.0,
+ 1401353265
+ ],
+ [
+ 9.0,
+ 1401353280
+ ],
+ [
+ 9.0,
+ 1401353295
+ ],
+ [
+ 9.0,
+ 1401353310
+ ],
+ [
+ 9.0,
+ 1401353325
+ ],
+ [
+ 9.0,
+ 1401353340
+ ],
+ [
+ 9.0,
+ 1401353355
+ ],
+ [
+ 9.0,
+ 1401353370
+ ],
+ [
+ 9.0,
+ 1401353385
+ ],
+ [
+ 9.0,
+ 1401353400
+ ],
+ [
+ 9.0,
+ 1401353415
+ ],
+ [
+ 9.0,
+ 1401353430
+ ],
+ [
+ 9.0,
+ 1401353445
+ ],
+ [
+ 9.0,
+ 1401353460
+ ],
+ [
+ 9.0,
+ 1401353475
+ ],
+ [
+ 9.0,
+ 1401353490
+ ],
+ [
+ 9.0,
+ 1401353505
+ ],
+ [
+ 9.0,
+ 1401353520
+ ],
+ [
+ 9.0,
+ 1401353535
+ ],
+ [
+ 9.0,
+ 1401353550
+ ],
+ [
+ 9.0,
+ 1401353565
+ ],
+ [
+ 9.0,
+ 1401353580
+ ],
+ [
+ 9.0,
+ 1401353595
+ ],
+ [
+ 9.0,
+ 1401353610
+ ],
+ [
+ 9.0,
+ 1401353625
+ ],
+ [
+ 9.0,
+ 1401353640
+ ],
+ [
+ 9.0,
+ 1401353655
+ ],
+ [
+ 9.0,
+ 1401353670
+ ],
+ [
+ 9.0,
+ 1401353685
+ ],
+ [
+ 9.0,
+ 1401353700
+ ],
+ [
+ 9.0,
+ 1401353715
+ ],
+ [
+ 9.0,
+ 1401353730
+ ],
+ [
+ 9.0,
+ 1401353745
+ ],
+ [
+ 9.0,
+ 1401353760
+ ],
+ [
+ 9.0,
+ 1401353775
+ ],
+ [
+ 9.0,
+ 1401353790
+ ],
+ [
+ 9.0,
+ 1401353805
+ ],
+ [
+ 9.0,
+ 1401353820
+ ],
+ [
+ 9.0,
+ 1401353835
+ ],
+ [
+ 9.0,
+ 1401353850
+ ],
+ [
+ 9.0,
+ 1401353865
+ ],
+ [
+ 9.0,
+ 1401353880
+ ],
+ [
+ 9.0,
+ 1401353895
+ ],
+ [
+ 9.0,
+ 1401353910
+ ],
+ [
+ 9.0,
+ 1401353925
+ ],
+ [
+ 9.0,
+ 1401353940
+ ],
+ [
+ 9.0,
+ 1401353955
+ ],
+ [
+ 9.0,
+ 1401353970
+ ],
+ [
+ 9.0,
+ 1401353985
+ ],
+ [
+ 9.0,
+ 1401354000
+ ],
+ [
+ 9.0,
+ 1401354015
+ ],
+ [
+ 9.0,
+ 1401354030
+ ],
+ [
+ 9.0,
+ 1401354045
+ ],
+ [
+ 9.0,
+ 1401354060
+ ],
+ [
+ 9.0,
+ 1401354075
+ ],
+ [
+ 9.0,
+ 1401354090
+ ],
+ [
+ 9.0,
+ 1401354105
+ ],
+ [
+ 9.0,
+ 1401354120
+ ],
+ [
+ 9.0,
+ 1401354135
+ ],
+ [
+ 9.0,
+ 1401354150
+ ],
+ [
+ 9.0,
+ 1401354165
+ ],
+ [
+ 9.0,
+ 1401354180
+ ],
+ [
+ 9.0,
+ 1401354195
+ ],
+ [
+ 9.0,
+ 1401354210
+ ],
+ [
+ 9.0,
+ 1401354225
+ ],
+ [
+ 9.0,
+ 1401354240
+ ],
+ [
+ 9.0,
+ 1401354255
+ ],
+ [
+ 9.0,
+ 1401354270
+ ],
+ [
+ 9.0,
+ 1401354285
+ ],
+ [
+ 9.0,
+ 1401354300
+ ],
+ [
+ 9.0,
+ 1401354315
+ ],
+ [
+ 9.0,
+ 1401354330
+ ],
+ [
+ 9.0,
+ 1401354345
+ ],
+ [
+ 9.0,
+ 1401354360
+ ],
+ [
+ 9.0,
+ 1401354375
+ ],
+ [
+ 9.0,
+ 1401354390
+ ],
+ [
+ 9.0,
+ 1401354405
+ ],
+ [
+ 9.0,
+ 1401354420
+ ],
+ [
+ 9.0,
+ 1401354435
+ ],
+ [
+ 9.0,
+ 1401354450
+ ],
+ [
+ 9.0,
+ 1401354465
+ ],
+ [
+ 9.0,
+ 1401354480
+ ],
+ [
+ 9.0,
+ 1401354495
+ ],
+ [
+ 9.0,
+ 1401354510
+ ],
+ [
+ 9.0,
+ 1401354525
+ ],
+ [
+ 9.0,
+ 1401354540
+ ],
+ [
+ 9.0,
+ 1401354555
+ ],
+ [
+ 9.0,
+ 1401354570
+ ],
+ [
+ 9.0,
+ 1401354585
+ ],
+ [
+ 9.0,
+ 1401354600
+ ],
+ [
+ 9.0,
+ 1401354615
+ ],
+ [
+ 9.0,
+ 1401354630
+ ],
+ [
+ 9.0,
+ 1401354645
+ ],
+ [
+ 9.0,
+ 1401354660
+ ],
+ [
+ 9.0,
+ 1401354675
+ ],
+ [
+ 9.0,
+ 1401354690
+ ],
+ [
+ 9.0,
+ 1401354705
+ ],
+ [
+ 9.0,
+ 1401354720
+ ],
+ [
+ 9.0,
+ 1401354735
+ ],
+ [
+ 9.0,
+ 1401354750
+ ],
+ [
+ 9.0,
+ 1401354765
+ ],
+ [
+ 9.0,
+ 1401354780
+ ],
+ [
+ 9.0,
+ 1401354795
+ ],
+ [
+ 9.0,
+ 1401354810
+ ],
+ [
+ 9.0,
+ 1401354825
+ ],
+ [
+ 9.0,
+ 1401354840
+ ],
+ [
+ 9.0,
+ 1401354855
+ ],
+ [
+ 9.0,
+ 1401354870
+ ],
+ [
+ 9.0,
+ 1401354885
+ ],
+ [
+ 9.0,
+ 1401354900
+ ],
+ [
+ 9.0,
+ 1401354915
+ ],
+ [
+ 9.0,
+ 1401354930
+ ],
+ [
+ 9.0,
+ 1401354945
+ ],
+ [
+ 9.0,
+ 1401354960
+ ],
+ [
+ 9.0,
+ 1401354975
+ ],
+ [
+ 9.0,
+ 1401354990
+ ],
+ [
+ 9.0,
+ 1401355005
+ ]
+ ],
+ "CapacityUsedGB" : [
+ [
+ 0.0,
+ 1401351555
+ ],
+ [
+ 0.0,
+ 1401351570
+ ],
+ [
+ 0.0,
+ 1401351585
+ ],
+ [
+ 0.0,
+ 1401351600
+ ],
+ [
+ 0.0,
+ 1401351615
+ ],
+ [
+ 0.0,
+ 1401351630
+ ],
+ [
+ 0.0,
+ 1401351645
+ ],
+ [
+ 0.0,
+ 1401351660
+ ],
+ [
+ 0.0,
+ 1401351675
+ ],
+ [
+ 0.0,
+ 1401351690
+ ],
+ [
+ 0.0,
+ 1401351705
+ ],
+ [
+ 0.0,
+ 1401351720
+ ],
+ [
+ 0.0,
+ 1401351735
+ ],
+ [
+ 0.0,
+ 1401351750
+ ],
+ [
+ 0.0,
+ 1401351765
+ ],
+ [
+ 0.0,
+ 1401351780
+ ],
+ [
+ 0.0,
+ 1401351795
+ ],
+ [
+ 0.0,
+ 1401351810
+ ],
+ [
+ 0.0,
+ 1401351825
+ ],
+ [
+ 0.0,
+ 1401351840
+ ],
+ [
+ 0.0,
+ 1401351855
+ ],
+ [
+ 0.0,
+ 1401351870
+ ],
+ [
+ 0.0,
+ 1401351885
+ ],
+ [
+ 0.0,
+ 1401351900
+ ],
+ [
+ 0.0,
+ 1401351915
+ ],
+ [
+ 0.0,
+ 1401351930
+ ],
+ [
+ 0.0,
+ 1401351945
+ ],
+ [
+ 0.0,
+ 1401351960
+ ],
+ [
+ 0.0,
+ 1401351975
+ ],
+ [
+ 0.0,
+ 1401351990
+ ],
+ [
+ 0.0,
+ 1401352005
+ ],
+ [
+ 0.0,
+ 1401352020
+ ],
+ [
+ 0.0,
+ 1401352035
+ ],
+ [
+ 0.0,
+ 1401352050
+ ],
+ [
+ 0.0,
+ 1401352065
+ ],
+ [
+ 0.0,
+ 1401352080
+ ],
+ [
+ 0.0,
+ 1401352095
+ ],
+ [
+ 0.0,
+ 1401352110
+ ],
+ [
+ 0.0,
+ 1401352125
+ ],
+ [
+ 0.0,
+ 1401352140
+ ],
+ [
+ 0.0,
+ 1401352155
+ ],
+ [
+ 0.0,
+ 1401352170
+ ],
+ [
+ 0.0,
+ 1401352185
+ ],
+ [
+ 0.0,
+ 1401352200
+ ],
+ [
+ 0.0,
+ 1401352215
+ ],
+ [
+ 0.0,
+ 1401352230
+ ],
+ [
+ 0.0,
+ 1401352245
+ ],
+ [
+ 0.0,
+ 1401352260
+ ],
+ [
+ 0.0,
+ 1401352275
+ ],
+ [
+ 0.0,
+ 1401352290
+ ],
+ [
+ 0.0,
+ 1401352305
+ ],
+ [
+ 0.0,
+ 1401352320
+ ],
+ [
+ 0.0,
+ 1401352335
+ ],
+ [
+ 0.0,
+ 1401352350
+ ],
+ [
+ 0.0,
+ 1401352365
+ ],
+ [
+ 0.0,
+ 1401352380
+ ],
+ [
+ 0.0,
+ 1401352395
+ ],
+ [
+ 0.0,
+ 1401352410
+ ],
+ [
+ 0.0,
+ 1401352425
+ ],
+ [
+ 0.0,
+ 1401352440
+ ],
+ [
+ 0.0,
+ 1401352455
+ ],
+ [
+ 0.0,
+ 1401352470
+ ],
+ [
+ 0.0,
+ 1401352485
+ ],
+ [
+ 0.0,
+ 1401352500
+ ],
+ [
+ 0.0,
+ 1401352515
+ ],
+ [
+ 0.0,
+ 1401352530
+ ],
+ [
+ 0.0,
+ 1401352545
+ ],
+ [
+ 0.0,
+ 1401352560
+ ],
+ [
+ 0.0,
+ 1401352575
+ ],
+ [
+ 0.0,
+ 1401352590
+ ],
+ [
+ 0.0,
+ 1401352605
+ ],
+ [
+ 0.0,
+ 1401352620
+ ],
+ [
+ 0.0,
+ 1401352635
+ ],
+ [
+ 0.0,
+ 1401352650
+ ],
+ [
+ 0.0,
+ 1401352665
+ ],
+ [
+ 0.0,
+ 1401352680
+ ],
+ [
+ 0.0,
+ 1401352695
+ ],
+ [
+ 0.0,
+ 1401352710
+ ],
+ [
+ 0.0,
+ 1401352725
+ ],
+ [
+ 0.0,
+ 1401352740
+ ],
+ [
+ 0.0,
+ 1401352755
+ ],
+ [
+ 0.0,
+ 1401352770
+ ],
+ [
+ 0.0,
+ 1401352785
+ ],
+ [
+ 0.0,
+ 1401352800
+ ],
+ [
+ 0.0,
+ 1401352815
+ ],
+ [
+ 0.0,
+ 1401352830
+ ],
+ [
+ 0.0,
+ 1401352845
+ ],
+ [
+ 0.0,
+ 1401352860
+ ],
+ [
+ 0.0,
+ 1401352875
+ ],
+ [
+ 0.0,
+ 1401352890
+ ],
+ [
+ 0.0,
+ 1401352905
+ ],
+ [
+ 0.0,
+ 1401352920
+ ],
+ [
+ 0.0,
+ 1401352935
+ ],
+ [
+ 0.0,
+ 1401352950
+ ],
+ [
+ 0.0,
+ 1401352965
+ ],
+ [
+ 0.0,
+ 1401352980
+ ],
+ [
+ 0.0,
+ 1401352995
+ ],
+ [
+ 0.0,
+ 1401353010
+ ],
+ [
+ 0.0,
+ 1401353025
+ ],
+ [
+ 0.0,
+ 1401353040
+ ],
+ [
+ 0.0,
+ 1401353055
+ ],
+ [
+ 0.0,
+ 1401353070
+ ],
+ [
+ 0.0,
+ 1401353085
+ ],
+ [
+ 0.0,
+ 1401353100
+ ],
+ [
+ 0.0,
+ 1401353115
+ ],
+ [
+ 0.0,
+ 1401353130
+ ],
+ [
+ 0.0,
+ 1401353145
+ ],
+ [
+ 0.0,
+ 1401353160
+ ],
+ [
+ 0.0,
+ 1401353175
+ ],
+ [
+ 0.0,
+ 1401353190
+ ],
+ [
+ 0.0,
+ 1401353205
+ ],
+ [
+ 0.0,
+ 1401353220
+ ],
+ [
+ 0.0,
+ 1401353235
+ ],
+ [
+ 0.0,
+ 1401353250
+ ],
+ [
+ 0.0,
+ 1401353265
+ ],
+ [
+ 0.0,
+ 1401353280
+ ],
+ [
+ 0.0,
+ 1401353295
+ ],
+ [
+ 0.0,
+ 1401353310
+ ],
+ [
+ 0.0,
+ 1401353325
+ ],
+ [
+ 0.0,
+ 1401353340
+ ],
+ [
+ 0.0,
+ 1401353355
+ ],
+ [
+ 0.0,
+ 1401353370
+ ],
+ [
+ 0.0,
+ 1401353385
+ ],
+ [
+ 0.0,
+ 1401353400
+ ],
+ [
+ 0.0,
+ 1401353415
+ ],
+ [
+ 0.0,
+ 1401353430
+ ],
+ [
+ 0.0,
+ 1401353445
+ ],
+ [
+ 0.0,
+ 1401353460
+ ],
+ [
+ 0.0,
+ 1401353475
+ ],
+ [
+ 0.0,
+ 1401353490
+ ],
+ [
+ 0.0,
+ 1401353505
+ ],
+ [
+ 0.0,
+ 1401353520
+ ],
+ [
+ 0.0,
+ 1401353535
+ ],
+ [
+ 0.0,
+ 1401353550
+ ],
+ [
+ 0.0,
+ 1401353565
+ ],
+ [
+ 0.0,
+ 1401353580
+ ],
+ [
+ 0.0,
+ 1401353595
+ ],
+ [
+ 0.0,
+ 1401353610
+ ],
+ [
+ 0.0,
+ 1401353625
+ ],
+ [
+ 0.0,
+ 1401353640
+ ],
+ [
+ 0.0,
+ 1401353655
+ ],
+ [
+ 0.0,
+ 1401353670
+ ],
+ [
+ 0.0,
+ 1401353685
+ ],
+ [
+ 0.0,
+ 1401353700
+ ],
+ [
+ 0.0,
+ 1401353715
+ ],
+ [
+ 0.0,
+ 1401353730
+ ],
+ [
+ 0.0,
+ 1401353745
+ ],
+ [
+ 0.0,
+ 1401353760
+ ],
+ [
+ 0.0,
+ 1401353775
+ ],
+ [
+ 0.0,
+ 1401353790
+ ],
+ [
+ 0.0,
+ 1401353805
+ ],
+ [
+ 0.0,
+ 1401353820
+ ],
+ [
+ 0.0,
+ 1401353835
+ ],
+ [
+ 0.0,
+ 1401353850
+ ],
+ [
+ 0.0,
+ 1401353865
+ ],
+ [
+ 0.0,
+ 1401353880
+ ],
+ [
+ 0.0,
+ 1401353895
+ ],
+ [
+ 0.0,
+ 1401353910
+ ],
+ [
+ 0.0,
+ 1401353925
+ ],
+ [
+ 0.0,
+ 1401353940
+ ],
+ [
+ 0.0,
+ 1401353955
+ ],
+ [
+ 0.0,
+ 1401353970
+ ],
+ [
+ 0.0,
+ 1401353985
+ ],
+ [
+ 0.0,
+ 1401354000
+ ],
+ [
+ 0.0,
+ 1401354015
+ ],
+ [
+ 0.0,
+ 1401354030
+ ],
+ [
+ 0.0,
+ 1401354045
+ ],
+ [
+ 0.0,
+ 1401354060
+ ],
+ [
+ 0.0,
+ 1401354075
+ ],
+ [
+ 0.0,
+ 1401354090
+ ],
+ [
+ 0.0,
+ 1401354105
+ ],
+ [
+ 0.0,
+ 1401354120
+ ],
+ [
+ 0.0,
+ 1401354135
+ ],
+ [
+ 0.0,
+ 1401354150
+ ],
+ [
+ 0.0,
+ 1401354165
+ ],
+ [
+ 0.0,
+ 1401354180
+ ],
+ [
+ 0.0,
+ 1401354195
+ ],
+ [
+ 0.0,
+ 1401354210
+ ],
+ [
+ 0.0,
+ 1401354225
+ ],
+ [
+ 0.0,
+ 1401354240
+ ],
+ [
+ 0.0,
+ 1401354255
+ ],
+ [
+ 0.0,
+ 1401354270
+ ],
+ [
+ 0.0,
+ 1401354285
+ ],
+ [
+ 0.0,
+ 1401354300
+ ],
+ [
+ 0.0,
+ 1401354315
+ ],
+ [
+ 0.0,
+ 1401354330
+ ],
+ [
+ 0.0,
+ 1401354345
+ ],
+ [
+ 0.0,
+ 1401354360
+ ],
+ [
+ 0.0,
+ 1401354375
+ ],
+ [
+ 0.0,
+ 1401354390
+ ],
+ [
+ 0.0,
+ 1401354405
+ ],
+ [
+ 0.0,
+ 1401354420
+ ],
+ [
+ 0.0,
+ 1401354435
+ ],
+ [
+ 0.0,
+ 1401354450
+ ],
+ [
+ 0.0,
+ 1401354465
+ ],
+ [
+ 0.0,
+ 1401354480
+ ],
+ [
+ 0.0,
+ 1401354495
+ ],
+ [
+ 0.0,
+ 1401354510
+ ],
+ [
+ 0.0,
+ 1401354525
+ ],
+ [
+ 0.0,
+ 1401354540
+ ],
+ [
+ 0.0,
+ 1401354555
+ ],
+ [
+ 0.0,
+ 1401354570
+ ],
+ [
+ 0.0,
+ 1401354585
+ ],
+ [
+ 0.0,
+ 1401354600
+ ],
+ [
+ 0.0,
+ 1401354615
+ ],
+ [
+ 0.0,
+ 1401354630
+ ],
+ [
+ 0.0,
+ 1401354645
+ ],
+ [
+ 0.0,
+ 1401354660
+ ],
+ [
+ 0.0,
+ 1401354675
+ ],
+ [
+ 0.0,
+ 1401354690
+ ],
+ [
+ 0.0,
+ 1401354705
+ ],
+ [
+ 0.0,
+ 1401354720
+ ],
+ [
+ 0.0,
+ 1401354735
+ ],
+ [
+ 0.0,
+ 1401354750
+ ],
+ [
+ 0.0,
+ 1401354765
+ ],
+ [
+ 0.0,
+ 1401354780
+ ],
+ [
+ 0.0,
+ 1401354795
+ ],
+ [
+ 0.0,
+ 1401354810
+ ],
+ [
+ 0.0,
+ 1401354825
+ ],
+ [
+ 0.0,
+ 1401354840
+ ],
+ [
+ 0.0,
+ 1401354855
+ ],
+ [
+ 0.0,
+ 1401354870
+ ],
+ [
+ 0.0,
+ 1401354885
+ ],
+ [
+ 0.0,
+ 1401354900
+ ],
+ [
+ 0.0,
+ 1401354915
+ ],
+ [
+ 0.0,
+ 1401354930
+ ],
+ [
+ 0.0,
+ 1401354945
+ ],
+ [
+ 0.0,
+ 1401354960
+ ],
+ [
+ 0.0,
+ 1401354975
+ ],
+ [
+ 0.0,
+ 1401354990
+ ],
+ [
+ 0.0,
+ 1401355005
+ ],
+ [
+ 0.0,
+ 1401355020
+ ],
+ [
+ 0.0,
+ 1401355035
+ ],
+ [
+ 0.0,
+ 1401355050
+ ],
+ [
+ 0.0,
+ 1401355065
+ ]
+ ]
+ }
+ }
+ }
+}
[5/8] AMBARI-5928. Create and populate Metrics section of a slider
app. (onechiporenko)
Posted by on...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/slider_app/metrics/metric3_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/slider_app/metrics/metric3_view.js b/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/slider_app/metrics/metric3_view.js
new file mode 100644
index 0000000..66e7917
--- /dev/null
+++ b/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/slider_app/metrics/metric3_view.js
@@ -0,0 +1,61 @@
+/**
+ * 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.
+ */
+
+/**
+ * @class
+ *
+ * This is a view for showing cluster CPU metrics
+ *
+ * @extends App.ChartView
+ * @extends Ember.Object
+ * @extends Ember.View
+ */
+App.Metric3View = App.ChartView.extend({
+ id: "service-metrics-hdfs-file-operations",
+ title: 'File Operations',
+ renderer: 'line',
+
+ ajaxIndex: 'metrics3',
+ yAxisFormatter: App.ChartView.CreateRateFormatter('ops', App.ChartView.DefaultFormatter),
+
+ transformToSeries: function (jsonData) {
+ var seriesArray = [];
+ if (jsonData && jsonData.metrics && jsonData.metrics.dfs && jsonData.metrics.dfs.namenode) {
+ for ( var name in jsonData.metrics.dfs.namenode) {
+ var displayName;
+ var seriesData = jsonData.metrics.dfs.namenode[name];
+ switch (name) {
+ case "FileInfoOps":
+ displayName = 'File Info Ops';
+ break;
+ case "DeleteFileOps":
+ displayName = 'Delete File Ops';
+ break;
+ case "CreateFileOps":
+ displayName = 'Create File Ops';
+ break;
+ default:
+ break;
+ }
+ if (seriesData) {
+ seriesArray.push(this.transformData(seriesData, displayName));
+ }
+ }
+ }
+ return seriesArray;
+ }
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/slider_app/metrics/metric4_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/slider_app/metrics/metric4_view.js b/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/slider_app/metrics/metric4_view.js
new file mode 100644
index 0000000..9f9298b
--- /dev/null
+++ b/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/slider_app/metrics/metric4_view.js
@@ -0,0 +1,54 @@
+/**
+ * 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.
+ */
+
+/**
+ * @class
+ *
+ * This is a view for showing cluster CPU metrics
+ *
+ * @extends App.ChartView
+ * @extends Ember.Object
+ * @extends Ember.View
+ */
+App.Metric4View = App.ChartView.extend({
+ id: "service-metrics-hdfs-rpc",
+ title: 'RPC',
+ yAxisFormatter: App.ChartView.TimeElapsedFormatter,
+
+ ajaxIndex: 'metrics4',
+
+ transformToSeries: function (jsonData) {
+ var seriesArray = [];
+ if (jsonData && jsonData.metrics && jsonData.metrics.rpc) {
+ for ( var name in jsonData.metrics.rpc) {
+ var displayName;
+ var seriesData = jsonData.metrics.rpc[name];
+ switch (name) {
+ case "RpcQueueTime_avg_time":
+ displayName = 'RPC Queue Time Avg Time';
+ break;
+ default:
+ break;
+ }
+ if (seriesData) {
+ seriesArray.push(this.transformData(seriesData, displayName));
+ }
+ }
+ }
+ return seriesArray;
+ }
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/slider_app/metrics/metric_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/slider_app/metrics/metric_view.js b/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/slider_app/metrics/metric_view.js
new file mode 100644
index 0000000..61a5739
--- /dev/null
+++ b/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/slider_app/metrics/metric_view.js
@@ -0,0 +1,70 @@
+/**
+ * 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.
+ */
+
+/**
+ * @class
+ *
+ * This is a view for showing cluster CPU metrics
+ *
+ * @extends App.ChartView
+ * @extends Ember.Object
+ * @extends Ember.View
+ */
+App.MetricView = App.ChartView.extend({
+
+ id: "service-metrics-hdfs-space-utilization",
+
+ title: 'Space Utilization',
+
+ yAxisFormatter: App.ChartView.BytesFormatter,
+
+ renderer: 'line',
+
+ ajaxIndex: 'metrics',
+
+ transformToSeries: function (jsonData) {
+ var seriesArray = [];
+ var GB = Math.pow(2, 30);
+ if (jsonData && jsonData.metrics && jsonData.metrics.dfs && jsonData.metrics.dfs.FSNamesystem) {
+ for ( var name in jsonData.metrics.dfs.FSNamesystem) {
+ var displayName;
+ var seriesData = jsonData.metrics.dfs.FSNamesystem[name];
+ switch (name) {
+ case "CapacityRemainingGB":
+ displayName = 'Capacity Remaining GB';
+ break;
+ case "CapacityUsedGB":
+ displayName = 'Capacity Used GB';
+ break;
+ case "CapacityTotalGB":
+ displayName = 'Capacity Total GB';
+ break;
+ default:
+ break;
+ }
+ if (seriesData) {
+ var s = this.transformData(seriesData, displayName);
+ for (var i = 0; i < s.data.length; i++) {
+ s.data[i].y *= GB;
+ }
+ seriesArray.push(s);
+ }
+ }
+ }
+ return seriesArray;
+ }
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/slider_app/summary_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/slider_app/summary_view.js b/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/slider_app/summary_view.js
new file mode 100644
index 0000000..bad2eb9
--- /dev/null
+++ b/ambari-web/contrib/views/slider/src/main/resources/ui/app/views/slider_app/summary_view.js
@@ -0,0 +1,27 @@
+/**
+ * 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.
+ */
+
+App.SliderAppSummaryView = Ember.View.extend({
+
+ classNames: ['app_summary'],
+
+ graphs: [
+ [App.MetricView, App.Metric2View, App.Metric3View, App.Metric4View]
+ ]
+
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/cubism.v1.js
----------------------------------------------------------------------
diff --git a/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/cubism.v1.js b/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/cubism.v1.js
new file mode 100644
index 0000000..be9ff4d
--- /dev/null
+++ b/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/cubism.v1.js
@@ -0,0 +1,1085 @@
+(function (exports) {
+ var cubism = exports.cubism = {version:"1.2.0"};
+ var cubism_id = 0;
+
+ function cubism_identity(d) {
+ return d;
+ }
+
+ cubism.option = function (name, defaultValue) {
+ var values = cubism.options(name);
+ return values.length ? values[0] : defaultValue;
+ };
+
+ cubism.options = function (name, defaultValues) {
+ var options = location.search.substring(1).split("&"),
+ values = [],
+ i = -1,
+ n = options.length,
+ o;
+ while (++i < n) {
+ if ((o = options[i].split("="))[0] == name) {
+ values.push(decodeURIComponent(o[1]));
+ }
+ }
+ return values.length || arguments.length < 2 ? values : defaultValues;
+ };
+ cubism.context = function () {
+ var context = new cubism_context,
+ step = 1e4, // ten seconds, in milliseconds
+ size = 1440, // four hours at ten seconds, in pixels
+ start0, stop0, // the start and stop for the previous change event
+ start1, stop1, // the start and stop for the next prepare event
+ serverDelay = 5e3,
+ clientDelay = 5e3,
+ event = d3.dispatch("prepare", "beforechange", "change", "focus"),
+ scale = context.scale = d3.time.scale().range([0, size]),
+ timeout,
+ focus;
+
+ function update() {
+ var now = Date.now();
+ stop0 = new Date(Math.floor((now - serverDelay - clientDelay) / step) * step);
+ start0 = new Date(stop0 - size * step);
+ stop1 = new Date(Math.floor((now - serverDelay) / step) * step);
+ start1 = new Date(stop1 - size * step);
+ scale.domain([start0, stop0]);
+ return context;
+ }
+
+ context.start = function () {
+ if (timeout) clearTimeout(timeout);
+ var delay = +stop1 + serverDelay - Date.now();
+
+ // If we're too late for the first prepare event, skip it.
+ if (delay < clientDelay) delay += step;
+
+ timeout = setTimeout(function prepare() {
+ stop1 = new Date(Math.floor((Date.now() - serverDelay) / step) * step);
+ start1 = new Date(stop1 - size * step);
+ event.prepare.call(context, start1, stop1);
+
+ setTimeout(function () {
+ scale.domain([start0 = start1, stop0 = stop1]);
+ event.beforechange.call(context, start1, stop1);
+ event.change.call(context, start1, stop1);
+ event.focus.call(context, focus);
+ }, clientDelay);
+
+ timeout = setTimeout(prepare, step);
+ }, delay);
+ return context;
+ };
+
+ context.stop = function () {
+ timeout = clearTimeout(timeout);
+ return context;
+ };
+
+ timeout = setTimeout(context.start, 10);
+
+ // Set or get the step interval in milliseconds.
+ // Defaults to ten seconds.
+ context.step = function (_) {
+ if (!arguments.length) return step;
+ step = +_;
+ return update();
+ };
+
+ // Set or get the context size (the count of metric values).
+ // Defaults to 1440 (four hours at ten seconds).
+ context.size = function (_) {
+ if (!arguments.length) return size;
+ scale.range([0, size = +_]);
+ return update();
+ };
+
+ // The server delay is the amount of time we wait for the server to compute a
+ // metric. This delay may result from clock skew or from delays collecting
+ // metrics from various hosts. Defaults to 4 seconds.
+ context.serverDelay = function (_) {
+ if (!arguments.length) return serverDelay;
+ serverDelay = +_;
+ return update();
+ };
+
+ // The client delay is the amount of additional time we wait to fetch those
+ // metrics from the server. The client and server delay combined represent the
+ // age of the most recent displayed metric. Defaults to 1 second.
+ context.clientDelay = function (_) {
+ if (!arguments.length) return clientDelay;
+ clientDelay = +_;
+ return update();
+ };
+
+ // Sets the focus to the specified index, and dispatches a "focus" event.
+ context.focus = function (i) {
+ event.focus.call(context, focus = i);
+ return context;
+ };
+
+ // Add, remove or get listeners for events.
+ context.on = function (type, listener) {
+ if (arguments.length < 2) return event.on(type);
+
+ event.on(type, listener);
+
+ // Notify the listener of the current start and stop time, as appropriate.
+ // This way, metrics can make requests for data immediately,
+ // and likewise the axis can display itself synchronously.
+ if (listener != null) {
+ if (/^prepare(\.|$)/.test(type)) listener.call(context, start1, stop1);
+ if (/^beforechange(\.|$)/.test(type)) listener.call(context, start0, stop0);
+ if (/^change(\.|$)/.test(type)) listener.call(context, start0, stop0);
+ if (/^focus(\.|$)/.test(type)) listener.call(context, focus);
+ }
+
+ return context;
+ };
+
+ d3.select(window).on("keydown.context-" + ++cubism_id, function () {
+ switch (!d3.event.metaKey && d3.event.keyCode) {
+ case 37: // left
+ if (focus == null) focus = size - 1;
+ if (focus > 0) context.focus(--focus);
+ break;
+ case 39: // right
+ if (focus == null) focus = size - 2;
+ if (focus < size - 1) context.focus(++focus);
+ break;
+ default:
+ return;
+ }
+ d3.event.preventDefault();
+ });
+
+ return update();
+ };
+
+ function cubism_context() {
+ }
+
+ var cubism_contextPrototype = cubism.context.prototype = cubism_context.prototype;
+
+ cubism_contextPrototype.constant = function (value) {
+ return new cubism_metricConstant(this, +value);
+ };
+ cubism_contextPrototype.cube = function (host) {
+ if (!arguments.length) host = "";
+ var source = {},
+ context = this;
+
+ source.metric = function (expression) {
+ return context.metric(function (start, stop, step, callback) {
+ d3.json(host + "/1.0/metric"
+ + "?expression=" + encodeURIComponent(expression)
+ + "&start=" + cubism_cubeFormatDate(start)
+ + "&stop=" + cubism_cubeFormatDate(stop)
+ + "&step=" + step, function (data) {
+ if (!data) return callback(new Error("unable to load data"));
+ callback(null, data.map(function (d) {
+ return d.value;
+ }));
+ });
+ }, expression += "");
+ };
+
+ // Returns the Cube host.
+ source.toString = function () {
+ return host;
+ };
+
+ return source;
+ };
+
+ var cubism_cubeFormatDate = d3.time.format.iso;
+ cubism_contextPrototype.graphite = function (host) {
+ if (!arguments.length) host = "";
+ var source = {},
+ context = this;
+
+ source.metric = function (expression) {
+ var sum = "sum";
+
+ var metric = context.metric(function (start, stop, step, callback) {
+ var target = expression;
+
+ // Apply the summarize, if necessary.
+ if (step !== 1e4) target = "summarize(" + target + ",'"
+ + (!(step % 36e5) ? step / 36e5 + "hour" : !(step % 6e4) ? step / 6e4 + "min" : step + "sec")
+ + "','" + sum + "')";
+
+ d3.text(host + "/render?format=raw"
+ + "&target=" + encodeURIComponent("alias(" + target + ",'')")
+ + "&from=" + cubism_graphiteFormatDate(start - 2 * step) // off-by-two?
+ + "&until=" + cubism_graphiteFormatDate(stop - 1000), function (text) {
+ if (!text) return callback(new Error("unable to load data"));
+ callback(null, cubism_graphiteParse(text));
+ });
+ }, expression += "");
+
+ metric.summarize = function (_) {
+ sum = _;
+ return metric;
+ };
+
+ return metric;
+ };
+
+ source.find = function (pattern, callback) {
+ d3.json(host + "/metrics/find?format=completer"
+ + "&query=" + encodeURIComponent(pattern), function (result) {
+ if (!result) return callback(new Error("unable to find metrics"));
+ callback(null, result.metrics.map(function (d) {
+ return d.path;
+ }));
+ });
+ };
+
+ // Returns the graphite host.
+ source.toString = function () {
+ return host;
+ };
+
+ return source;
+ };
+
+// Graphite understands seconds since UNIX epoch.
+ function cubism_graphiteFormatDate(time) {
+ return Math.floor(time / 1000);
+ }
+
+// Helper method for parsing graphite's raw format.
+ function cubism_graphiteParse(text) {
+ var i = text.indexOf("|"),
+ meta = text.substring(0, i),
+ c = meta.lastIndexOf(","),
+ b = meta.lastIndexOf(",", c - 1),
+ a = meta.lastIndexOf(",", b - 1),
+ start = meta.substring(a + 1, b) * 1000,
+ step = meta.substring(c + 1) * 1000;
+ return text
+ .substring(i + 1)
+ .split(",")
+ .slice(1)// the first value is always None?
+ .map(function (d) {
+ return +d;
+ });
+ }
+
+ function cubism_metric(context) {
+ if (!(context instanceof cubism_context)) throw new Error("invalid context");
+ this.context = context;
+ }
+
+ var cubism_metricPrototype = cubism_metric.prototype;
+
+ cubism.metric = cubism_metric;
+
+ cubism_metricPrototype.valueAt = function () {
+ return NaN;
+ };
+
+ cubism_metricPrototype.alias = function (name) {
+ this.toString = function () {
+ return name;
+ };
+ return this;
+ };
+
+ cubism_metricPrototype.extent = function () {
+ var i = 0,
+ n = this.context.size(),
+ value,
+ min = Infinity,
+ max = -Infinity;
+ while (++i < n) {
+ value = this.valueAt(i);
+ if (value < min) min = value;
+ if (value > max) max = value;
+ }
+ return [min, max];
+ };
+
+ cubism_metricPrototype.on = function (type, listener) {
+ return arguments.length < 2 ? null : this;
+ };
+
+ cubism_metricPrototype.shift = function () {
+ return this;
+ };
+
+ cubism_metricPrototype.on = function () {
+ return arguments.length < 2 ? null : this;
+ };
+
+ cubism_contextPrototype.metric = function (request, name) {
+ var context = this,
+ metric = new cubism_metric(context),
+ id = ".metric-" + ++cubism_id,
+ start = -Infinity,
+ stop,
+ step = context.step(),
+ size = context.size(),
+ values = [],
+ event = d3.dispatch("change"),
+ listening = 0,
+ fetching;
+
+ // Prefetch new data into a temporary array.
+ function prepare(start1, stop) {
+ var steps = Math.min(size, Math.round((start1 - start) / step));
+ if (!steps || fetching) return; // already fetched, or fetching!
+ fetching = true;
+ steps = Math.min(size, steps + cubism_metricOverlap);
+ var start0 = new Date(stop - steps * step);
+ request(start0, stop, step, function (error, data) {
+ fetching = false;
+ if (error) return console.warn(error);
+ var i = isFinite(start) ? Math.round((start0 - start) / step) : 0;
+ for (var j = 0, m = data.length; j < m; ++j) values[j + i] = data[j];
+ event.change.call(metric, start, stop);
+ });
+ }
+
+ // When the context changes, switch to the new data, ready-or-not!
+ function beforechange(start1, stop1) {
+ if (!isFinite(start)) start = start1;
+ values.splice(0, Math.max(0, Math.min(size, Math.round((start1 - start) / step))));
+ start = start1;
+ stop = stop1;
+ }
+
+ //
+ metric.valueAt = function (i) {
+ return values[i];
+ };
+
+ //
+ metric.shift = function (offset) {
+ return context.metric(cubism_metricShift(request, +offset));
+ };
+
+ //
+ metric.on = function (type, listener) {
+ if (!arguments.length) return event.on(type);
+
+ // If there are no listeners, then stop listening to the context,
+ // and avoid unnecessary fetches.
+ if (listener == null) {
+ if (event.on(type) != null && --listening == 0) {
+ context.on("prepare" + id, null).on("beforechange" + id, null);
+ }
+ } else {
+ if (event.on(type) == null && ++listening == 1) {
+ context.on("prepare" + id, prepare).on("beforechange" + id, beforechange);
+ }
+ }
+
+ event.on(type, listener);
+
+ // Notify the listener of the current start and stop time, as appropriate.
+ // This way, charts can display synchronous metrics immediately.
+ if (listener != null) {
+ if (/^change(\.|$)/.test(type)) listener.call(context, start, stop);
+ }
+
+ return metric;
+ };
+
+ //
+ if (arguments.length > 1) metric.toString = function () {
+ return name;
+ };
+
+ return metric;
+ };
+
+// Number of metric to refetch each period, in case of lag.
+ var cubism_metricOverlap = 6;
+
+// Wraps the specified request implementation, and shifts time by the given offset.
+ function cubism_metricShift(request, offset) {
+ return function (start, stop, step, callback) {
+ request(new Date(+start + offset), new Date(+stop + offset), step, callback);
+ };
+ }
+
+ function cubism_metricConstant(context, value) {
+ cubism_metric.call(this, context);
+ value = +value;
+ var name = value + "";
+ this.valueOf = function () {
+ return value;
+ };
+ this.toString = function () {
+ return name;
+ };
+ }
+
+ var cubism_metricConstantPrototype = cubism_metricConstant.prototype = Object.create(cubism_metric.prototype);
+
+ cubism_metricConstantPrototype.valueAt = function () {
+ return +this;
+ };
+
+ cubism_metricConstantPrototype.extent = function () {
+ return [+this, +this];
+ };
+ function cubism_metricOperator(name, operate) {
+
+ function cubism_metricOperator(left, right) {
+ if (!(right instanceof cubism_metric)) right = new cubism_metricConstant(left.context, right);
+ else if (left.context !== right.context) throw new Error("mismatch context");
+ cubism_metric.call(this, left.context);
+ this.left = left;
+ this.right = right;
+ this.toString = function () {
+ return left + " " + name + " " + right;
+ };
+ }
+
+ var cubism_metricOperatorPrototype = cubism_metricOperator.prototype = Object.create(cubism_metric.prototype);
+
+ cubism_metricOperatorPrototype.valueAt = function (i) {
+ return operate(this.left.valueAt(i), this.right.valueAt(i));
+ };
+
+ cubism_metricOperatorPrototype.shift = function (offset) {
+ return new cubism_metricOperator(this.left.shift(offset), this.right.shift(offset));
+ };
+
+ cubism_metricOperatorPrototype.on = function (type, listener) {
+ if (arguments.length < 2) return this.left.on(type);
+ this.left.on(type, listener);
+ this.right.on(type, listener);
+ return this;
+ };
+
+ return function (right) {
+ return new cubism_metricOperator(this, right);
+ };
+ }
+
+ cubism_metricPrototype.add = cubism_metricOperator("+", function (left, right) {
+ return left + right;
+ });
+
+ cubism_metricPrototype.subtract = cubism_metricOperator("-", function (left, right) {
+ return left - right;
+ });
+
+ cubism_metricPrototype.multiply = cubism_metricOperator("*", function (left, right) {
+ return left * right;
+ });
+
+ cubism_metricPrototype.divide = cubism_metricOperator("/", function (left, right) {
+ return left / right;
+ });
+ cubism_contextPrototype.horizon = function () {
+ var context = this,
+ mode = "offset",
+ buffer = document.createElement("canvas"),
+ width = buffer.width = context.size(),
+ height = buffer.height = 30,
+ scale = d3.scale.linear().interpolate(d3.interpolateRound),
+ metric = cubism_identity,
+ extent = null,
+ title = cubism_identity,
+ format = d3.format(".2s"),
+ colors = ["#08519c", "#3182bd", "#6baed6", "#bdd7e7", "#bae4b3", "#74c476", "#31a354", "#006d2c"];
+
+ function horizon(selection) {
+
+ selection
+ .on("mousemove.horizon", function () {
+ context.focus(d3.mouse(this)[0]);
+ })
+ .on("mouseout.horizon", function () {
+ context.focus(null);
+ });
+
+ selection.append("canvas")
+ .attr("width", width)
+ .attr("height", height);
+
+ selection.append("span")
+ .attr("class", "title")
+ .text(title);
+
+ selection.append("span")
+ .attr("class", "value");
+
+ selection.each(function (d, i) {
+ var that = this,
+ id = ++cubism_id,
+ metric_ = typeof metric === "function" ? metric.call(that, d, i) : metric,
+ colors_ = typeof colors === "function" ? colors.call(that, d, i) : colors,
+ extent_ = typeof extent === "function" ? extent.call(that, d, i) : extent,
+ start = -Infinity,
+ step = context.step(),
+ canvas = d3.select(that).select("canvas"),
+ span = d3.select(that).select(".value"),
+ max_,
+ m = colors_.length >> 1,
+ ready;
+
+ canvas.datum({id:id, metric:metric_});
+ canvas = canvas.node().getContext("2d");
+
+ function change(start1, stop) {
+ canvas.save();
+
+ // compute the new extent and ready flag
+ var extent = metric_.extent();
+ ready = extent.every(isFinite);
+ if (extent_ != null) extent = extent_;
+
+ // if this is an update (with no extent change), copy old values!
+ var i0 = 0, max = Math.max(-extent[0], extent[1]);
+ if (this === context) {
+ if (max == max_) {
+ i0 = width - cubism_metricOverlap;
+ var dx = (start1 - start) / step;
+ if (dx < width) {
+ var canvas0 = buffer.getContext("2d");
+ canvas0.clearRect(0, 0, width, height);
+ canvas0.drawImage(canvas.canvas, dx, 0, width - dx, height, 0, 0, width - dx, height);
+ canvas.clearRect(0, 0, width, height);
+ canvas.drawImage(canvas0.canvas, 0, 0);
+ }
+ }
+ start = start1;
+ }
+
+ // update the domain
+ scale.domain([0, max_ = max]);
+
+ // clear for the new data
+ canvas.clearRect(i0, 0, width - i0, height);
+
+ // record whether there are negative values to display
+ var negative;
+
+ // positive bands
+ for (var j = 0; j < m; ++j) {
+ canvas.fillStyle = colors_[m + j];
+
+ // Adjust the range based on the current band index.
+ var y0 = (j - m + 1) * height;
+ scale.range([m * height + y0, y0]);
+ y0 = scale(0);
+
+ for (var i = i0, n = width, y1; i < n; ++i) {
+ y1 = metric_.valueAt(i);
+ if (y1 <= 0) {
+ negative = true;
+ continue;
+ }
+ canvas.fillRect(i, y1 = scale(y1), 1, y0 - y1);
+ }
+ }
+
+ if (negative) {
+ // enable offset mode
+ if (mode === "offset") {
+ canvas.translate(0, height);
+ canvas.scale(1, -1);
+ }
+
+ // negative bands
+ for (var j = 0; j < m; ++j) {
+ canvas.fillStyle = colors_[m - 1 - j];
+
+ // Adjust the range based on the current band index.
+ var y0 = (j - m + 1) * height;
+ scale.range([m * height + y0, y0]);
+ y0 = scale(0);
+
+ for (var i = i0, n = width, y1; i < n; ++i) {
+ y1 = metric_.valueAt(i);
+ if (y1 >= 0) continue;
+ canvas.fillRect(i, scale(-y1), 1, y0 - scale(-y1));
+ }
+ }
+ }
+
+ canvas.restore();
+ }
+
+ function focus(i) {
+ if (i == null) i = width - 1;
+ var value = metric_.valueAt(i);
+ span.datum(value).text(isNaN(value) ? null : format);
+ }
+
+ // Update the chart when the context changes.
+ context.on("change.horizon-" + id, change);
+ context.on("focus.horizon-" + id, focus);
+
+ // Display the first metric change immediately,
+ // but defer subsequent updates to the canvas change.
+ // Note that someone still needs to listen to the metric,
+ // so that it continues to update automatically.
+ metric_.on("change.horizon-" + id, function (start, stop) {
+ change(start, stop), focus();
+ if (ready) metric_.on("change.horizon-" + id, cubism_identity);
+ });
+ });
+ }
+
+ horizon.remove = function (selection) {
+
+ selection
+ .on("mousemove.horizon", null)
+ .on("mouseout.horizon", null);
+
+ selection.selectAll("canvas")
+ .each(remove)
+ .remove();
+
+ selection.selectAll(".title,.value")
+ .remove();
+
+ function remove(d) {
+ d.metric.on("change.horizon-" + d.id, null);
+ context.on("change.horizon-" + d.id, null);
+ context.on("focus.horizon-" + d.id, null);
+ }
+ };
+
+ horizon.mode = function (_) {
+ if (!arguments.length) return mode;
+ mode = _ + "";
+ return horizon;
+ };
+
+ horizon.height = function (_) {
+ if (!arguments.length) return height;
+ buffer.height = height = +_;
+ return horizon;
+ };
+
+ horizon.metric = function (_) {
+ if (!arguments.length) return metric;
+ metric = _;
+ return horizon;
+ };
+
+ horizon.scale = function (_) {
+ if (!arguments.length) return scale;
+ scale = _;
+ return horizon;
+ };
+
+ horizon.extent = function (_) {
+ if (!arguments.length) return extent;
+ extent = _;
+ return horizon;
+ };
+
+ horizon.title = function (_) {
+ if (!arguments.length) return title;
+ title = _;
+ return horizon;
+ };
+
+ horizon.format = function (_) {
+ if (!arguments.length) return format;
+ format = _;
+ return horizon;
+ };
+
+ horizon.colors = function (_) {
+ if (!arguments.length) return colors;
+ colors = _;
+ return horizon;
+ };
+
+ return horizon;
+ };
+ cubism_contextPrototype.comparison = function () {
+ var context = this,
+ width = context.size(),
+ height = 120,
+ scale = d3.scale.linear().interpolate(d3.interpolateRound),
+ primary = function (d) {
+ return d[0];
+ },
+ secondary = function (d) {
+ return d[1];
+ },
+ extent = null,
+ title = cubism_identity,
+ formatPrimary = cubism_comparisonPrimaryFormat,
+ formatChange = cubism_comparisonChangeFormat,
+ colors = ["#9ecae1", "#225b84", "#a1d99b", "#22723a"],
+ strokeWidth = 1.5;
+
+ function comparison(selection) {
+
+ selection
+ .on("mousemove.comparison", function () {
+ context.focus(d3.mouse(this)[0]);
+ })
+ .on("mouseout.comparison", function () {
+ context.focus(null);
+ });
+
+ selection.append("canvas")
+ .attr("width", width)
+ .attr("height", height);
+
+ selection.append("span")
+ .attr("class", "title")
+ .text(title);
+
+ selection.append("span")
+ .attr("class", "value primary");
+
+ selection.append("span")
+ .attr("class", "value change");
+
+ selection.each(function (d, i) {
+ var that = this,
+ id = ++cubism_id,
+ primary_ = typeof primary === "function" ? primary.call(that, d, i) : primary,
+ secondary_ = typeof secondary === "function" ? secondary.call(that, d, i) : secondary,
+ extent_ = typeof extent === "function" ? extent.call(that, d, i) : extent,
+ div = d3.select(that),
+ canvas = div.select("canvas"),
+ spanPrimary = div.select(".value.primary"),
+ spanChange = div.select(".value.change"),
+ ready;
+
+ canvas.datum({id:id, primary:primary_, secondary:secondary_});
+ canvas = canvas.node().getContext("2d");
+
+ function change(start, stop) {
+ canvas.save();
+ canvas.clearRect(0, 0, width, height);
+
+ // update the scale
+ var primaryExtent = primary_.extent(),
+ secondaryExtent = secondary_.extent(),
+ extent = extent_ == null ? primaryExtent : extent_;
+ scale.domain(extent).range([height, 0]);
+ ready = primaryExtent.concat(secondaryExtent).every(isFinite);
+
+ // consistent overplotting
+ var round = start / context.step() & 1
+ ? cubism_comparisonRoundOdd
+ : cubism_comparisonRoundEven;
+
+ // positive changes
+ canvas.fillStyle = colors[2];
+ for (var i = 0, n = width; i < n; ++i) {
+ var y0 = scale(primary_.valueAt(i)),
+ y1 = scale(secondary_.valueAt(i));
+ if (y0 < y1) canvas.fillRect(round(i), y0, 1, y1 - y0);
+ }
+
+ // negative changes
+ canvas.fillStyle = colors[0];
+ for (i = 0; i < n; ++i) {
+ var y0 = scale(primary_.valueAt(i)),
+ y1 = scale(secondary_.valueAt(i));
+ if (y0 > y1) canvas.fillRect(round(i), y1, 1, y0 - y1);
+ }
+
+ // positive values
+ canvas.fillStyle = colors[3];
+ for (i = 0; i < n; ++i) {
+ var y0 = scale(primary_.valueAt(i)),
+ y1 = scale(secondary_.valueAt(i));
+ if (y0 <= y1) canvas.fillRect(round(i), y0, 1, strokeWidth);
+ }
+
+ // negative values
+ canvas.fillStyle = colors[1];
+ for (i = 0; i < n; ++i) {
+ var y0 = scale(primary_.valueAt(i)),
+ y1 = scale(secondary_.valueAt(i));
+ if (y0 > y1) canvas.fillRect(round(i), y0 - strokeWidth, 1, strokeWidth);
+ }
+
+ canvas.restore();
+ }
+
+ function focus(i) {
+ if (i == null) i = width - 1;
+ var valuePrimary = primary_.valueAt(i),
+ valueSecondary = secondary_.valueAt(i),
+ valueChange = (valuePrimary - valueSecondary) / valueSecondary;
+
+ spanPrimary
+ .datum(valuePrimary)
+ .text(isNaN(valuePrimary) ? null : formatPrimary);
+
+ spanChange
+ .datum(valueChange)
+ .text(isNaN(valueChange) ? null : formatChange)
+ .attr("class", "value change " + (valueChange > 0 ? "positive" : valueChange < 0 ? "negative" : ""));
+ }
+
+ // Display the first primary change immediately,
+ // but defer subsequent updates to the context change.
+ // Note that someone still needs to listen to the metric,
+ // so that it continues to update automatically.
+ primary_.on("change.comparison-" + id, firstChange);
+ secondary_.on("change.comparison-" + id, firstChange);
+ function firstChange(start, stop) {
+ change(start, stop), focus();
+ if (ready) {
+ primary_.on("change.comparison-" + id, cubism_identity);
+ secondary_.on("change.comparison-" + id, cubism_identity);
+ }
+ }
+
+ // Update the chart when the context changes.
+ context.on("change.comparison-" + id, change);
+ context.on("focus.comparison-" + id, focus);
+ });
+ }
+
+ comparison.remove = function (selection) {
+
+ selection
+ .on("mousemove.comparison", null)
+ .on("mouseout.comparison", null);
+
+ selection.selectAll("canvas")
+ .each(remove)
+ .remove();
+
+ selection.selectAll(".title,.value")
+ .remove();
+
+ function remove(d) {
+ d.primary.on("change.comparison-" + d.id, null);
+ d.secondary.on("change.comparison-" + d.id, null);
+ context.on("change.comparison-" + d.id, null);
+ context.on("focus.comparison-" + d.id, null);
+ }
+ };
+
+ comparison.height = function (_) {
+ if (!arguments.length) return height;
+ height = +_;
+ return comparison;
+ };
+
+ comparison.primary = function (_) {
+ if (!arguments.length) return primary;
+ primary = _;
+ return comparison;
+ };
+
+ comparison.secondary = function (_) {
+ if (!arguments.length) return secondary;
+ secondary = _;
+ return comparison;
+ };
+
+ comparison.scale = function (_) {
+ if (!arguments.length) return scale;
+ scale = _;
+ return comparison;
+ };
+
+ comparison.extent = function (_) {
+ if (!arguments.length) return extent;
+ extent = _;
+ return comparison;
+ };
+
+ comparison.title = function (_) {
+ if (!arguments.length) return title;
+ title = _;
+ return comparison;
+ };
+
+ comparison.formatPrimary = function (_) {
+ if (!arguments.length) return formatPrimary;
+ formatPrimary = _;
+ return comparison;
+ };
+
+ comparison.formatChange = function (_) {
+ if (!arguments.length) return formatChange;
+ formatChange = _;
+ return comparison;
+ };
+
+ comparison.colors = function (_) {
+ if (!arguments.length) return colors;
+ colors = _;
+ return comparison;
+ };
+
+ comparison.strokeWidth = function (_) {
+ if (!arguments.length) return strokeWidth;
+ strokeWidth = _;
+ return comparison;
+ };
+
+ return comparison;
+ };
+
+ var cubism_comparisonPrimaryFormat = d3.format(".2s"),
+ cubism_comparisonChangeFormat = d3.format("+.0%");
+
+ function cubism_comparisonRoundEven(i) {
+ return i & 0xfffffe;
+ }
+
+ function cubism_comparisonRoundOdd(i) {
+ return ((i + 1) & 0xfffffe) - 1;
+ }
+
+ cubism_contextPrototype.axis = function () {
+ var context = this,
+ scale = context.scale,
+ axis_ = d3.svg.axis().scale(scale);
+
+ var format = context.step() < 6e4 ? cubism_axisFormatSeconds
+ : context.step() < 864e5 ? cubism_axisFormatMinutes
+ : cubism_axisFormatDays;
+
+ function axis(selection) {
+ var id = ++cubism_id,
+ tick;
+
+ var g = selection.append("svg")
+ .datum({id:id})
+ .attr("width", context.size())
+ .attr("height", Math.max(28, -axis.tickSize()))
+ .append("g")
+ .attr("transform", "translate(0," + (axis_.orient() === "top" ? 27 : 4) + ")")
+ .call(axis_);
+
+ context.on("change.axis-" + id, function () {
+ g.call(axis_);
+ if (!tick) tick = d3.select(g.node().appendChild(g.selectAll("text").node().cloneNode(true)))
+ .style("display", "none")
+ .text(null);
+ });
+
+ context.on("focus.axis-" + id, function (i) {
+ if (tick) {
+ if (i == null) {
+ tick.style("display", "none");
+ g.selectAll("text").style("fill-opacity", null);
+ } else {
+ tick.style("display", null).attr("x", i).text(format(scale.invert(i)));
+ var dx = tick.node().getComputedTextLength() + 6;
+ g.selectAll("text").style("fill-opacity", function (d) {
+ return Math.abs(scale(d) - i) < dx ? 0 : 1;
+ });
+ }
+ }
+ });
+ }
+
+ axis.remove = function (selection) {
+
+ selection.selectAll("svg")
+ .each(remove)
+ .remove();
+
+ function remove(d) {
+ context.on("change.axis-" + d.id, null);
+ context.on("focus.axis-" + d.id, null);
+ }
+ };
+
+ return d3.rebind(axis, axis_,
+ "orient",
+ "ticks",
+ "tickSubdivide",
+ "tickSize",
+ "tickPadding",
+ "tickFormat");
+ };
+
+ var cubism_axisFormatSeconds = d3.time.format("%I:%M:%S %p"),
+ cubism_axisFormatMinutes = d3.time.format("%I:%M %p"),
+ cubism_axisFormatDays = d3.time.format("%B %d");
+ cubism_contextPrototype.rule = function () {
+ var context = this,
+ metric = cubism_identity;
+
+ function rule(selection) {
+ var id = ++cubism_id;
+
+ var line = selection.append("div")
+ .datum({id:id})
+ .attr("class", "line")
+ .call(cubism_ruleStyle);
+
+ selection.each(function (d, i) {
+ var that = this,
+ id = ++cubism_id,
+ metric_ = typeof metric === "function" ? metric.call(that, d, i) : metric;
+
+ if (!metric_) return;
+
+ function change(start, stop) {
+ var values = [];
+
+ for (var i = 0, n = context.size(); i < n; ++i) {
+ if (metric_.valueAt(i)) {
+ values.push(i);
+ }
+ }
+
+ var lines = selection.selectAll(".metric").data(values);
+ lines.exit().remove();
+ lines.enter().append("div").attr("class", "metric line").call(cubism_ruleStyle);
+ lines.style("left", cubism_ruleLeft);
+ }
+
+ context.on("change.rule-" + id, change);
+ metric_.on("change.rule-" + id, change);
+ });
+
+ context.on("focus.rule-" + id, function (i) {
+ line.datum(i)
+ .style("display", i == null ? "none" : null)
+ .style("left", cubism_ruleLeft);
+ });
+ }
+
+ rule.remove = function (selection) {
+
+ selection.selectAll(".line")
+ .each(remove)
+ .remove();
+
+ function remove(d) {
+ context.on("focus.rule-" + d.id, null);
+ }
+ };
+
+ rule.metric = function (_) {
+ if (!arguments.length) return metric;
+ metric = _;
+ return rule;
+ };
+
+ return rule;
+ };
+
+ function cubism_ruleStyle(line) {
+ line
+ .style("position", "absolute")
+ .style("top", 0)
+ .style("bottom", 0)
+ .style("width", "1px")
+ .style("pointer-events", "none");
+ }
+
+ function cubism_ruleLeft(i) {
+ return i + "px";
+ }
+})(this);
[3/8] AMBARI-5928. Create and populate Metrics section of a slider
app. (onechiporenko)
Posted by on...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/jquery.ui.core.js
----------------------------------------------------------------------
diff --git a/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/jquery.ui.core.js b/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/jquery.ui.core.js
new file mode 100644
index 0000000..1285a6d
--- /dev/null
+++ b/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/jquery.ui.core.js
@@ -0,0 +1,334 @@
+/*!
+ * jQuery UI 1.8.23
+ *
+ * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI
+ */
+(function( $, undefined ) {
+
+// prevent duplicate loading
+// this is only a problem because we proxy existing functions
+// and we don't want to double proxy them
+$.ui = $.ui || {};
+if ( $.ui.version ) {
+ return;
+}
+
+$.extend( $.ui, {
+ version: "1.8.23",
+
+ keyCode: {
+ ALT: 18,
+ BACKSPACE: 8,
+ CAPS_LOCK: 20,
+ COMMA: 188,
+ COMMAND: 91,
+ COMMAND_LEFT: 91, // COMMAND
+ COMMAND_RIGHT: 93,
+ CONTROL: 17,
+ DELETE: 46,
+ DOWN: 40,
+ END: 35,
+ ENTER: 13,
+ ESCAPE: 27,
+ HOME: 36,
+ INSERT: 45,
+ LEFT: 37,
+ MENU: 93, // COMMAND_RIGHT
+ NUMPAD_ADD: 107,
+ NUMPAD_DECIMAL: 110,
+ NUMPAD_DIVIDE: 111,
+ NUMPAD_ENTER: 108,
+ NUMPAD_MULTIPLY: 106,
+ NUMPAD_SUBTRACT: 109,
+ PAGE_DOWN: 34,
+ PAGE_UP: 33,
+ PERIOD: 190,
+ RIGHT: 39,
+ SHIFT: 16,
+ SPACE: 32,
+ TAB: 9,
+ UP: 38,
+ WINDOWS: 91 // COMMAND
+ }
+});
+
+// plugins
+$.fn.extend({
+ propAttr: $.fn.prop || $.fn.attr,
+
+ _focus: $.fn.focus,
+ focus: function( delay, fn ) {
+ return typeof delay === "number" ?
+ this.each(function() {
+ var elem = this;
+ setTimeout(function() {
+ $( elem ).focus();
+ if ( fn ) {
+ fn.call( elem );
+ }
+ }, delay );
+ }) :
+ this._focus.apply( this, arguments );
+ },
+
+ scrollParent: function() {
+ var scrollParent;
+ if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
+ scrollParent = this.parents().filter(function() {
+ return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
+ }).eq(0);
+ } else {
+ scrollParent = this.parents().filter(function() {
+ return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
+ }).eq(0);
+ }
+
+ return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
+ },
+
+ zIndex: function( zIndex ) {
+ if ( zIndex !== undefined ) {
+ return this.css( "zIndex", zIndex );
+ }
+
+ if ( this.length ) {
+ var elem = $( this[ 0 ] ), position, value;
+ while ( elem.length && elem[ 0 ] !== document ) {
+ // Ignore z-index if position is set to a value where z-index is ignored by the browser
+ // This makes behavior of this function consistent across browsers
+ // WebKit always returns auto if the element is positioned
+ position = elem.css( "position" );
+ if ( position === "absolute" || position === "relative" || position === "fixed" ) {
+ // IE returns 0 when zIndex is not specified
+ // other browsers return a string
+ // we ignore the case of nested elements with an explicit value of 0
+ // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
+ value = parseInt( elem.css( "zIndex" ), 10 );
+ if ( !isNaN( value ) && value !== 0 ) {
+ return value;
+ }
+ }
+ elem = elem.parent();
+ }
+ }
+
+ return 0;
+ },
+
+ disableSelection: function() {
+ return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
+ ".ui-disableSelection", function( event ) {
+ event.preventDefault();
+ });
+ },
+
+ enableSelection: function() {
+ return this.unbind( ".ui-disableSelection" );
+ }
+});
+
+// support: jQuery <1.8
+if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
+ $.each( [ "Width", "Height" ], function( i, name ) {
+ var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
+ type = name.toLowerCase(),
+ orig = {
+ innerWidth: $.fn.innerWidth,
+ innerHeight: $.fn.innerHeight,
+ outerWidth: $.fn.outerWidth,
+ outerHeight: $.fn.outerHeight
+ };
+
+ function reduce( elem, size, border, margin ) {
+ $.each( side, function() {
+ size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0;
+ if ( border ) {
+ size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0;
+ }
+ if ( margin ) {
+ size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0;
+ }
+ });
+ return size;
+ }
+
+ $.fn[ "inner" + name ] = function( size ) {
+ if ( size === undefined ) {
+ return orig[ "inner" + name ].call( this );
+ }
+
+ return this.each(function() {
+ $( this ).css( type, reduce( this, size ) + "px" );
+ });
+ };
+
+ $.fn[ "outer" + name] = function( size, margin ) {
+ if ( typeof size !== "number" ) {
+ return orig[ "outer" + name ].call( this, size );
+ }
+
+ return this.each(function() {
+ $( this).css( type, reduce( this, size, true, margin ) + "px" );
+ });
+ };
+ });
+}
+
+// selectors
+function focusable( element, isTabIndexNotNaN ) {
+ var nodeName = element.nodeName.toLowerCase();
+ if ( "area" === nodeName ) {
+ var map = element.parentNode,
+ mapName = map.name,
+ img;
+ if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
+ return false;
+ }
+ img = $( "img[usemap=#" + mapName + "]" )[0];
+ return !!img && visible( img );
+ }
+ return ( /input|select|textarea|button|object/.test( nodeName )
+ ? !element.disabled
+ : "a" == nodeName
+ ? element.href || isTabIndexNotNaN
+ : isTabIndexNotNaN)
+ // the element and all of its ancestors must be visible
+ && visible( element );
+}
+
+function visible( element ) {
+ return !$( element ).parents().andSelf().filter(function() {
+ return $.curCSS( this, "visibility" ) === "hidden" ||
+ $.expr.filters.hidden( this );
+ }).length;
+}
+
+$.extend( $.expr[ ":" ], {
+ data: $.expr.createPseudo ?
+ $.expr.createPseudo(function( dataName ) {
+ return function( elem ) {
+ return !!$.data( elem, dataName );
+ };
+ }) :
+ // support: jQuery <1.8
+ function( elem, i, match ) {
+ return !!$.data( elem, match[ 3 ] );
+ },
+
+ focusable: function( element ) {
+ return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
+ },
+
+ tabbable: function( element ) {
+ var tabIndex = $.attr( element, "tabindex" ),
+ isTabIndexNaN = isNaN( tabIndex );
+ return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
+ }
+});
+
+// support
+$(function() {
+ var body = document.body,
+ div = body.appendChild( div = document.createElement( "div" ) );
+
+ // access offsetHeight before setting the style to prevent a layout bug
+ // in IE 9 which causes the elemnt to continue to take up space even
+ // after it is removed from the DOM (#8026)
+ div.offsetHeight;
+
+ $.extend( div.style, {
+ minHeight: "100px",
+ height: "auto",
+ padding: 0,
+ borderWidth: 0
+ });
+
+ $.support.minHeight = div.offsetHeight === 100;
+ $.support.selectstart = "onselectstart" in div;
+
+ // set display to none to avoid a layout bug in IE
+ // http://dev.jquery.com/ticket/4014
+ body.removeChild( div ).style.display = "none";
+});
+
+// jQuery <1.4.3 uses curCSS, in 1.4.3 - 1.7.2 curCSS = css, 1.8+ only has css
+if ( !$.curCSS ) {
+ $.curCSS = $.css;
+}
+
+
+
+
+
+// deprecated
+$.extend( $.ui, {
+ // $.ui.plugin is deprecated. Use the proxy pattern instead.
+ plugin: {
+ add: function( module, option, set ) {
+ var proto = $.ui[ module ].prototype;
+ for ( var i in set ) {
+ proto.plugins[ i ] = proto.plugins[ i ] || [];
+ proto.plugins[ i ].push( [ option, set[ i ] ] );
+ }
+ },
+ call: function( instance, name, args ) {
+ var set = instance.plugins[ name ];
+ if ( !set || !instance.element[ 0 ].parentNode ) {
+ return;
+ }
+
+ for ( var i = 0; i < set.length; i++ ) {
+ if ( instance.options[ set[ i ][ 0 ] ] ) {
+ set[ i ][ 1 ].apply( instance.element, args );
+ }
+ }
+ }
+ },
+
+ // will be deprecated when we switch to jQuery 1.4 - use jQuery.contains()
+ contains: function( a, b ) {
+ return document.compareDocumentPosition ?
+ a.compareDocumentPosition( b ) & 16 :
+ a !== b && a.contains( b );
+ },
+
+ // only used by resizable
+ hasScroll: function( el, a ) {
+
+ //If overflow is hidden, the element might have extra content, but the user wants to hide it
+ if ( $( el ).css( "overflow" ) === "hidden") {
+ return false;
+ }
+
+ var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
+ has = false;
+
+ if ( el[ scroll ] > 0 ) {
+ return true;
+ }
+
+ // TODO: determine which cases actually cause this to happen
+ // if the element doesn't have the scroll set, see if it's possible to
+ // set the scroll
+ el[ scroll ] = 1;
+ has = ( el[ scroll ] > 0 );
+ el[ scroll ] = 0;
+ return has;
+ },
+
+ // these are odd functions, fix the API or move into individual plugins
+ isOverAxis: function( x, reference, size ) {
+ //Determines when x coordinate is over "b" element axis
+ return ( x > reference ) && ( x < ( reference + size ) );
+ },
+ isOver: function( y, x, top, left, height, width ) {
+ //Determines when x, y coordinates is over "b" element
+ return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
+ }
+});
+
+})( jQuery );
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/jquery.ui.mouse.js
----------------------------------------------------------------------
diff --git a/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/jquery.ui.mouse.js b/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/jquery.ui.mouse.js
new file mode 100644
index 0000000..78c8ef6
--- /dev/null
+++ b/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/jquery.ui.mouse.js
@@ -0,0 +1,175 @@
+/*!
+ * jQuery UI Mouse 1.8.23
+ *
+ * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Mouse
+ *
+ * Depends:
+ * jquery.ui.widget.js
+ */
+(function ($, undefined) {
+
+ var mouseHandled = false;
+ $(document).mouseup(function (e) {
+ mouseHandled = false;
+ });
+
+ $.widget("ui.mouse", {
+ options:{
+ cancel:':input,option',
+ distance:1,
+ delay:0
+ },
+ _mouseInit:function () {
+ var self = this;
+
+ this.element
+ .bind('mousedown.' + this.widgetName, function (event) {
+ return self._mouseDown(event);
+ })
+ .bind('click.' + this.widgetName, function (event) {
+ if (true === $.data(event.target, self.widgetName + '.preventClickEvent')) {
+ $.removeData(event.target, self.widgetName + '.preventClickEvent');
+ event.stopImmediatePropagation();
+ return false;
+ }
+ });
+
+ this.started = false;
+ },
+
+ // TODO: make sure destroying one instance of mouse doesn't mess with
+ // other instances of mouse
+ _mouseDestroy:function () {
+ this.element.unbind('.' + this.widgetName);
+ if (this._mouseMoveDelegate) {
+ $(document)
+ .unbind('mousemove.' + this.widgetName, this._mouseMoveDelegate)
+ .unbind('mouseup.' + this.widgetName, this._mouseUpDelegate);
+ }
+ },
+
+ _mouseDown:function (event) {
+ // don't let more than one widget handle mouseStart
+ if (mouseHandled) {
+ return
+ }
+ ;
+
+ // we may have missed mouseup (out of window)
+ (this._mouseStarted && this._mouseUp(event));
+
+ this._mouseDownEvent = event;
+
+ var self = this,
+ btnIsLeft = (event.which == 1),
+ // event.target.nodeName works around a bug in IE 8 with
+ // disabled inputs (#7620)
+ elIsCancel = (typeof this.options.cancel == "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
+ if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
+ return true;
+ }
+
+ this.mouseDelayMet = !this.options.delay;
+ if (!this.mouseDelayMet) {
+ this._mouseDelayTimer = setTimeout(function () {
+ self.mouseDelayMet = true;
+ }, this.options.delay);
+ }
+
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+ this._mouseStarted = (this._mouseStart(event) !== false);
+ if (!this._mouseStarted) {
+ event.preventDefault();
+ return true;
+ }
+ }
+
+ // Click event may never have fired (Gecko & Opera)
+ if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
+ $.removeData(event.target, this.widgetName + '.preventClickEvent');
+ }
+
+ // these delegates are required to keep context
+ this._mouseMoveDelegate = function (event) {
+ return self._mouseMove(event);
+ };
+ this._mouseUpDelegate = function (event) {
+ return self._mouseUp(event);
+ };
+ $(document)
+ .bind('mousemove.' + this.widgetName, this._mouseMoveDelegate)
+ .bind('mouseup.' + this.widgetName, this._mouseUpDelegate);
+
+ event.preventDefault();
+
+ mouseHandled = true;
+ return true;
+ },
+
+ _mouseMove:function (event) {
+ // IE mouseup check - mouseup happened when mouse was out of window
+ if ($.browser.msie && !(document.documentMode >= 9) && !event.button) {
+ return this._mouseUp(event);
+ }
+
+ if (this._mouseStarted) {
+ this._mouseDrag(event);
+ return event.preventDefault();
+ }
+
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+ this._mouseStarted =
+ (this._mouseStart(this._mouseDownEvent, event) !== false);
+ (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
+ }
+
+ return !this._mouseStarted;
+ },
+
+ _mouseUp:function (event) {
+ $(document)
+ .unbind('mousemove.' + this.widgetName, this._mouseMoveDelegate)
+ .unbind('mouseup.' + this.widgetName, this._mouseUpDelegate);
+
+ if (this._mouseStarted) {
+ this._mouseStarted = false;
+
+ if (event.target == this._mouseDownEvent.target) {
+ $.data(event.target, this.widgetName + '.preventClickEvent', true);
+ }
+
+ this._mouseStop(event);
+ }
+
+ return false;
+ },
+
+ _mouseDistanceMet:function (event) {
+ return (Math.max(
+ Math.abs(this._mouseDownEvent.pageX - event.pageX),
+ Math.abs(this._mouseDownEvent.pageY - event.pageY)
+ ) >= this.options.distance
+ );
+ },
+
+ _mouseDelayMet:function (event) {
+ return this.mouseDelayMet;
+ },
+
+ // These are placeholder methods, to be overriden by extending plugin
+ _mouseStart:function (event) {
+ },
+ _mouseDrag:function (event) {
+ },
+ _mouseStop:function (event) {
+ },
+ _mouseCapture:function (event) {
+ return true;
+ }
+ });
+
+})(jQuery);
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/jquery.ui.sortable.js
----------------------------------------------------------------------
diff --git a/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/jquery.ui.sortable.js b/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/jquery.ui.sortable.js
new file mode 100644
index 0000000..8aa4dc4
--- /dev/null
+++ b/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/jquery.ui.sortable.js
@@ -0,0 +1,1088 @@
+/*!
+ * jQuery UI Sortable 1.9.0
+ * http://jqueryui.com
+ *
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/sortable/
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.mouse.js
+ * jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+$.widget("ui.sortable", $.ui.mouse, {
+ version: "1.9.0",
+ widgetEventPrefix: "sort",
+ ready: false,
+ options: {
+ appendTo: "parent",
+ axis: false,
+ connectWith: false,
+ containment: false,
+ cursor: 'auto',
+ cursorAt: false,
+ dropOnEmpty: true,
+ forcePlaceholderSize: false,
+ forceHelperSize: false,
+ grid: false,
+ handle: false,
+ helper: "original",
+ items: '> *',
+ opacity: false,
+ placeholder: false,
+ revert: false,
+ scroll: true,
+ scrollSensitivity: 20,
+ scrollSpeed: 20,
+ scope: "default",
+ tolerance: "intersect",
+ zIndex: 1000
+ },
+ _create: function() {
+
+ var o = this.options;
+ this.containerCache = {};
+ this.element.addClass("ui-sortable");
+
+ //Get the items
+ this.refresh();
+
+ //Let's determine if the items are being displayed horizontally
+ this.floating = this.items.length ? o.axis === 'x' || (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false;
+
+ //Let's determine the parent's offset
+ this.offset = this.element.offset();
+
+ //Initialize mouse events for interaction
+ this._mouseInit();
+
+ //We're ready to go
+ this.ready = true
+
+ },
+
+ _destroy: function() {
+ this.element
+ .removeClass("ui-sortable ui-sortable-disabled");
+ this._mouseDestroy();
+
+ for ( var i = this.items.length - 1; i >= 0; i-- )
+ this.items[i].item.removeData(this.widgetName + "-item");
+
+ return this;
+ },
+
+ _setOption: function(key, value){
+ if ( key === "disabled" ) {
+ this.options[ key ] = value;
+
+ this.widget().toggleClass( "ui-sortable-disabled", !!value );
+ } else {
+ // Don't call widget base _setOption for disable as it adds ui-state-disabled class
+ $.Widget.prototype._setOption.apply(this, arguments);
+ }
+ },
+
+ _mouseCapture: function(event, overrideHandle) {
+ var that = this;
+
+ if (this.reverting) {
+ return false;
+ }
+
+ if(this.options.disabled || this.options.type == 'static') return false;
+
+ //We have to refresh the items data once first
+ this._refreshItems(event);
+
+ //Find out if the clicked node (or one of its parents) is a actual item in this.items
+ var currentItem = null, nodes = $(event.target).parents().each(function() {
+ if($.data(this, that.widgetName + '-item') == that) {
+ currentItem = $(this);
+ return false;
+ }
+ });
+ if($.data(event.target, that.widgetName + '-item') == that) currentItem = $(event.target);
+
+ if(!currentItem) return false;
+ if(this.options.handle && !overrideHandle) {
+ var validHandle = false;
+
+ $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
+ if(!validHandle) return false;
+ }
+
+ this.currentItem = currentItem;
+ this._removeCurrentsFromItems();
+ return true;
+
+ },
+
+ _mouseStart: function(event, overrideHandle, noActivation) {
+
+ var o = this.options;
+ this.currentContainer = this;
+
+ //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
+ this.refreshPositions();
+
+ //Create and append the visible helper
+ this.helper = this._createHelper(event);
+
+ //Cache the helper size
+ this._cacheHelperProportions();
+
+ /*
+ * - Position generation -
+ * This block generates everything position related - it's the core of draggables.
+ */
+
+ //Cache the margins of the original element
+ this._cacheMargins();
+
+ //Get the next scrolling parent
+ this.scrollParent = this.helper.scrollParent();
+
+ //The element's absolute position on the page minus margins
+ this.offset = this.currentItem.offset();
+ this.offset = {
+ top: this.offset.top - this.margins.top,
+ left: this.offset.left - this.margins.left
+ };
+
+ $.extend(this.offset, {
+ click: { //Where the click happened, relative to the element
+ left: event.pageX - this.offset.left,
+ top: event.pageY - this.offset.top
+ },
+ parent: this._getParentOffset(),
+ relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
+ });
+
+ // Only after we got the offset, we can change the helper's position to absolute
+ // TODO: Still need to figure out a way to make relative sorting possible
+ this.helper.css("position", "absolute");
+ this.cssPosition = this.helper.css("position");
+
+ //Generate the original position
+ this.originalPosition = this._generatePosition(event);
+ this.originalPageX = event.pageX;
+ this.originalPageY = event.pageY;
+
+ //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
+ (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
+
+ //Cache the former DOM position
+ this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
+
+ //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
+ if(this.helper[0] != this.currentItem[0]) {
+ this.currentItem.hide();
+ }
+
+ //Create the placeholder
+ this._createPlaceholder();
+
+ //Set a containment if given in the options
+ if(o.containment)
+ this._setContainment();
+
+ if(o.cursor) { // cursor option
+ if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
+ $('body').css("cursor", o.cursor);
+ }
+
+ if(o.opacity) { // opacity option
+ if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
+ this.helper.css("opacity", o.opacity);
+ }
+
+ if(o.zIndex) { // zIndex option
+ if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
+ this.helper.css("zIndex", o.zIndex);
+ }
+
+ //Prepare scrolling
+ if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
+ this.overflowOffset = this.scrollParent.offset();
+
+ //Call callbacks
+ this._trigger("start", event, this._uiHash());
+
+ //Recache the helper size
+ if(!this._preserveHelperProportions)
+ this._cacheHelperProportions();
+
+
+ //Post 'activate' events to possible containers
+ if(!noActivation) {
+ for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, this._uiHash(this)); }
+ }
+
+ //Prepare possible droppables
+ if($.ui.ddmanager)
+ $.ui.ddmanager.current = this;
+
+ if ($.ui.ddmanager && !o.dropBehaviour)
+ $.ui.ddmanager.prepareOffsets(this, event);
+
+ this.dragging = true;
+
+ this.helper.addClass("ui-sortable-helper");
+ this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
+ return true;
+
+ },
+
+ _mouseDrag: function(event) {
+
+ //Compute the helpers position
+ this.position = this._generatePosition(event);
+ this.positionAbs = this._convertPositionTo("absolute");
+
+ if (!this.lastPositionAbs) {
+ this.lastPositionAbs = this.positionAbs;
+ }
+
+ //Do scrolling
+ if(this.options.scroll) {
+ var o = this.options, scrolled = false;
+ if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
+
+ if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
+ else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
+
+ if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
+ else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
+
+ } else {
+
+ if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
+ scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
+ else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
+ scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
+
+ if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
+ scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
+ else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
+ scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
+
+ }
+
+ if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
+ $.ui.ddmanager.prepareOffsets(this, event);
+ }
+
+ //Regenerate the absolute position used for position checks
+ this.positionAbs = this._convertPositionTo("absolute");
+
+ //Set the helper position
+ if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
+ if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
+
+ //Rearrange
+ for (var i = this.items.length - 1; i >= 0; i--) {
+
+ //Cache variables and intersection, continue if no intersection
+ var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
+ if (!intersection) continue;
+
+ // Only put the placeholder inside the current Container, skip all
+ // items form other containers. This works because when moving
+ // an item from one container to another the
+ // currentContainer is switched before the placeholder is moved.
+ //
+ // Without this moving items in "sub-sortables" can cause the placeholder to jitter
+ // beetween the outer and inner container.
+ if (item.instance !== this.currentContainer) continue;
+
+ if (itemElement != this.currentItem[0] //cannot intersect with itself
+ && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
+ && !$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
+ && (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true)
+ //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
+ ) {
+
+ this.direction = intersection == 1 ? "down" : "up";
+
+ if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
+ this._rearrange(event, item);
+ } else {
+ break;
+ }
+
+ this._trigger("change", event, this._uiHash());
+ break;
+ }
+ }
+
+ //Post events to containers
+ this._contactContainers(event);
+
+ //Interconnect with droppables
+ if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
+
+ //Call callbacks
+ this._trigger('sort', event, this._uiHash());
+
+ this.lastPositionAbs = this.positionAbs;
+ return false;
+
+ },
+
+ _mouseStop: function(event, noPropagation) {
+
+ if(!event) return;
+
+ //If we are using droppables, inform the manager about the drop
+ if ($.ui.ddmanager && !this.options.dropBehaviour)
+ $.ui.ddmanager.drop(this, event);
+
+ if(this.options.revert) {
+ var that = this;
+ var cur = this.placeholder.offset();
+
+ this.reverting = true;
+
+ $(this.helper).animate({
+ left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
+ top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
+ }, parseInt(this.options.revert, 10) || 500, function() {
+ that._clear(event);
+ });
+ } else {
+ this._clear(event, noPropagation);
+ }
+
+ return false;
+
+ },
+
+ cancel: function() {
+
+ if(this.dragging) {
+
+ this._mouseUp({ target: null });
+
+ if(this.options.helper == "original")
+ this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
+ else
+ this.currentItem.show();
+
+ //Post deactivating events to containers
+ for (var i = this.containers.length - 1; i >= 0; i--){
+ this.containers[i]._trigger("deactivate", null, this._uiHash(this));
+ if(this.containers[i].containerCache.over) {
+ this.containers[i]._trigger("out", null, this._uiHash(this));
+ this.containers[i].containerCache.over = 0;
+ }
+ }
+
+ }
+
+ if (this.placeholder) {
+ //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
+ if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
+ if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
+
+ $.extend(this, {
+ helper: null,
+ dragging: false,
+ reverting: false,
+ _noFinalSort: null
+ });
+
+ if(this.domPosition.prev) {
+ $(this.domPosition.prev).after(this.currentItem);
+ } else {
+ $(this.domPosition.parent).prepend(this.currentItem);
+ }
+ }
+
+ return this;
+
+ },
+
+ serialize: function(o) {
+
+ var items = this._getItemsAsjQuery(o && o.connected);
+ var str = []; o = o || {};
+
+ $(items).each(function() {
+ var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
+ if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
+ });
+
+ if(!str.length && o.key) {
+ str.push(o.key + '=');
+ }
+
+ return str.join('&');
+
+ },
+
+ toArray: function(o) {
+
+ var items = this._getItemsAsjQuery(o && o.connected);
+ var ret = []; o = o || {};
+
+ items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
+ return ret;
+
+ },
+
+ /* Be careful with the following core functions */
+ _intersectsWith: function(item) {
+
+ var x1 = this.positionAbs.left,
+ x2 = x1 + this.helperProportions.width,
+ y1 = this.positionAbs.top,
+ y2 = y1 + this.helperProportions.height;
+
+ var l = item.left,
+ r = l + item.width,
+ t = item.top,
+ b = t + item.height;
+
+ var dyClick = this.offset.click.top,
+ dxClick = this.offset.click.left;
+
+ var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
+
+ if( this.options.tolerance == "pointer"
+ || this.options.forcePointerForContainers
+ || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
+ ) {
+ return isOverElement;
+ } else {
+
+ return (l < x1 + (this.helperProportions.width / 2) // Right Half
+ && x2 - (this.helperProportions.width / 2) < r // Left Half
+ && t < y1 + (this.helperProportions.height / 2) // Bottom Half
+ && y2 - (this.helperProportions.height / 2) < b ); // Top Half
+
+ }
+ },
+
+ _intersectsWithPointer: function(item) {
+
+ var isOverElementHeight = (this.options.axis === 'x') || $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
+ isOverElementWidth = (this.options.axis === 'y') || $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
+ isOverElement = isOverElementHeight && isOverElementWidth,
+ verticalDirection = this._getDragVerticalDirection(),
+ horizontalDirection = this._getDragHorizontalDirection();
+
+ if (!isOverElement)
+ return false;
+
+ return this.floating ?
+ ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
+ : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
+
+ },
+
+ _intersectsWithSides: function(item) {
+
+ var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
+ isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
+ verticalDirection = this._getDragVerticalDirection(),
+ horizontalDirection = this._getDragHorizontalDirection();
+
+ if (this.floating && horizontalDirection) {
+ return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
+ } else {
+ return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
+ }
+
+ },
+
+ _getDragVerticalDirection: function() {
+ var delta = this.positionAbs.top - this.lastPositionAbs.top;
+ return delta != 0 && (delta > 0 ? "down" : "up");
+ },
+
+ _getDragHorizontalDirection: function() {
+ var delta = this.positionAbs.left - this.lastPositionAbs.left;
+ return delta != 0 && (delta > 0 ? "right" : "left");
+ },
+
+ refresh: function(event) {
+ this._refreshItems(event);
+ this.refreshPositions();
+ return this;
+ },
+
+ _connectWith: function() {
+ var options = this.options;
+ return options.connectWith.constructor == String
+ ? [options.connectWith]
+ : options.connectWith;
+ },
+
+ _getItemsAsjQuery: function(connected) {
+
+ var items = [];
+ var queries = [];
+ var connectWith = this._connectWith();
+
+ if(connectWith && connected) {
+ for (var i = connectWith.length - 1; i >= 0; i--){
+ var cur = $(connectWith[i]);
+ for (var j = cur.length - 1; j >= 0; j--){
+ var inst = $.data(cur[j], this.widgetName);
+ if(inst && inst != this && !inst.options.disabled) {
+ queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), inst]);
+ }
+ };
+ };
+ }
+
+ queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), this]);
+
+ for (var i = queries.length - 1; i >= 0; i--){
+ queries[i][0].each(function() {
+ items.push(this);
+ });
+ };
+
+ return $(items);
+
+ },
+
+ _removeCurrentsFromItems: function() {
+
+ var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
+
+ for (var i=0; i < this.items.length; i++) {
+
+ for (var j=0; j < list.length; j++) {
+ if(list[j] == this.items[i].item[0])
+ this.items.splice(i,1);
+ };
+
+ };
+
+ },
+
+ _refreshItems: function(event) {
+
+ this.items = [];
+ this.containers = [this];
+ var items = this.items;
+ var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
+ var connectWith = this._connectWith();
+
+ if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
+ for (var i = connectWith.length - 1; i >= 0; i--){
+ var cur = $(connectWith[i]);
+ for (var j = cur.length - 1; j >= 0; j--){
+ var inst = $.data(cur[j], this.widgetName);
+ if(inst && inst != this && !inst.options.disabled) {
+ queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
+ this.containers.push(inst);
+ }
+ };
+ };
+ }
+
+ for (var i = queries.length - 1; i >= 0; i--) {
+ var targetData = queries[i][1];
+ var _queries = queries[i][0];
+
+ for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
+ var item = $(_queries[j]);
+
+ item.data(this.widgetName + '-item', targetData); // Data for target checking (mouse manager)
+
+ items.push({
+ item: item,
+ instance: targetData,
+ width: 0, height: 0,
+ left: 0, top: 0
+ });
+ };
+ };
+
+ },
+
+ refreshPositions: function(fast) {
+
+ //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
+ if(this.offsetParent && this.helper) {
+ this.offset.parent = this._getParentOffset();
+ }
+
+ for (var i = this.items.length - 1; i >= 0; i--){
+ var item = this.items[i];
+
+ //We ignore calculating positions of all connected containers when we're not over them
+ if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
+ continue;
+
+ var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
+
+ if (!fast) {
+ item.width = t.outerWidth();
+ item.height = t.outerHeight();
+ }
+
+ var p = t.offset();
+ item.left = p.left;
+ item.top = p.top;
+ };
+
+ if(this.options.custom && this.options.custom.refreshContainers) {
+ this.options.custom.refreshContainers.call(this);
+ } else {
+ for (var i = this.containers.length - 1; i >= 0; i--){
+ var p = this.containers[i].element.offset();
+ this.containers[i].containerCache.left = p.left;
+ this.containers[i].containerCache.top = p.top;
+ this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
+ this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
+ };
+ }
+
+ return this;
+ },
+
+ _createPlaceholder: function(that) {
+ that = that || this;
+ var o = that.options;
+
+ if(!o.placeholder || o.placeholder.constructor == String) {
+ var className = o.placeholder;
+ o.placeholder = {
+ element: function() {
+
+ var el = $(document.createElement(that.currentItem[0].nodeName))
+ .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
+ .removeClass("ui-sortable-helper")[0];
+
+ if(!className)
+ el.style.visibility = "hidden";
+
+ return el;
+ },
+ update: function(container, p) {
+
+ // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
+ // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
+ if(className && !o.forcePlaceholderSize) return;
+
+ //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
+ if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css('paddingTop')||0, 10) - parseInt(that.currentItem.css('paddingBottom')||0, 10)); };
+ if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css('paddingLeft')||0, 10) - parseInt(that.currentItem.css('paddingRight')||0, 10)); };
+ }
+ };
+ }
+
+ //Create the placeholder
+ that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
+
+ //Append it after the actual current item
+ that.currentItem.after(that.placeholder);
+
+ //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
+ o.placeholder.update(that, that.placeholder);
+
+ },
+
+ _contactContainers: function(event) {
+
+ // get innermost container that intersects with item
+ var innermostContainer = null, innermostIndex = null;
+
+
+ for (var i = this.containers.length - 1; i >= 0; i--){
+
+ // never consider a container that's located within the item itself
+ if($.contains(this.currentItem[0], this.containers[i].element[0]))
+ continue;
+
+ if(this._intersectsWith(this.containers[i].containerCache)) {
+
+ // if we've already found a container and it's more "inner" than this, then continue
+ if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0]))
+ continue;
+
+ innermostContainer = this.containers[i];
+ innermostIndex = i;
+
+ } else {
+ // container doesn't intersect. trigger "out" event if necessary
+ if(this.containers[i].containerCache.over) {
+ this.containers[i]._trigger("out", event, this._uiHash(this));
+ this.containers[i].containerCache.over = 0;
+ }
+ }
+
+ }
+
+ // if no intersecting containers found, return
+ if(!innermostContainer) return;
+
+ // move the item into the container if it's not there already
+ if(this.containers.length === 1) {
+ this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
+ this.containers[innermostIndex].containerCache.over = 1;
+ } else if(this.currentContainer != this.containers[innermostIndex]) {
+
+ //When entering a new container, we will find the item with the least distance and append our item near it
+ var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top'];
+ for (var j = this.items.length - 1; j >= 0; j--) {
+ if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
+ var cur = this.containers[innermostIndex].floating ? this.items[j].item.offset().left : this.items[j].item.offset().top;
+ if(Math.abs(cur - base) < dist) {
+ dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
+ this.direction = (cur - base > 0) ? 'down' : 'up';
+ }
+ }
+
+ if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
+ return;
+
+ this.currentContainer = this.containers[innermostIndex];
+ itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
+ this._trigger("change", event, this._uiHash());
+ this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
+
+ //Update the placeholder
+ this.options.placeholder.update(this.currentContainer, this.placeholder);
+
+ this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
+ this.containers[innermostIndex].containerCache.over = 1;
+ }
+
+
+ },
+
+ _createHelper: function(event) {
+
+ var o = this.options;
+ var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
+
+ if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
+ $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
+
+ if(helper[0] == this.currentItem[0])
+ this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
+
+ if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
+ if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
+
+ return helper;
+
+ },
+
+ _adjustOffsetFromHelper: function(obj) {
+ if (typeof obj == 'string') {
+ obj = obj.split(' ');
+ }
+ if ($.isArray(obj)) {
+ obj = {left: +obj[0], top: +obj[1] || 0};
+ }
+ if ('left' in obj) {
+ this.offset.click.left = obj.left + this.margins.left;
+ }
+ if ('right' in obj) {
+ this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
+ }
+ if ('top' in obj) {
+ this.offset.click.top = obj.top + this.margins.top;
+ }
+ if ('bottom' in obj) {
+ this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
+ }
+ },
+
+ _getParentOffset: function() {
+
+
+ //Get the offsetParent and cache its position
+ this.offsetParent = this.helper.offsetParent();
+ var po = this.offsetParent.offset();
+
+ // This is a special case where we need to modify a offset calculated on start, since the following happened:
+ // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
+ // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
+ // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
+ if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
+ po.left += this.scrollParent.scrollLeft();
+ po.top += this.scrollParent.scrollTop();
+ }
+
+ if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
+ || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
+ po = { top: 0, left: 0 };
+
+ return {
+ top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
+ left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
+ };
+
+ },
+
+ _getRelativeOffset: function() {
+
+ if(this.cssPosition == "relative") {
+ var p = this.currentItem.position();
+ return {
+ top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
+ left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
+ };
+ } else {
+ return { top: 0, left: 0 };
+ }
+
+ },
+
+ _cacheMargins: function() {
+ this.margins = {
+ left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
+ top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
+ };
+ },
+
+ _cacheHelperProportions: function() {
+ this.helperProportions = {
+ width: this.helper.outerWidth(),
+ height: this.helper.outerHeight()
+ };
+ },
+
+ _setContainment: function() {
+
+ var o = this.options;
+ if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
+ if(o.containment == 'document' || o.containment == 'window') this.containment = [
+ 0 - this.offset.relative.left - this.offset.parent.left,
+ 0 - this.offset.relative.top - this.offset.parent.top,
+ $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
+ ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
+ ];
+
+ if(!(/^(document|window|parent)$/).test(o.containment)) {
+ var ce = $(o.containment)[0];
+ var co = $(o.containment).offset();
+ var over = ($(ce).css("overflow") != 'hidden');
+
+ this.containment = [
+ co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
+ co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
+ co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
+ co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
+ ];
+ }
+
+ },
+
+ _convertPositionTo: function(d, pos) {
+
+ if(!pos) pos = this.position;
+ var mod = d == "absolute" ? 1 : -1;
+ var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+
+ return {
+ top: (
+ pos.top // The absolute mouse position
+ + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
+ + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
+ - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
+ ),
+ left: (
+ pos.left // The absolute mouse position
+ + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
+ + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
+ - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
+ )
+ };
+
+ },
+
+ _generatePosition: function(event) {
+
+ var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+
+ // This is another very weird special case that only happens for relative elements:
+ // 1. If the css position is relative
+ // 2. and the scroll parent is the document or similar to the offset parent
+ // we have to refresh the relative offset during the scroll so there are no jumps
+ if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
+ this.offset.relative = this._getRelativeOffset();
+ }
+
+ var pageX = event.pageX;
+ var pageY = event.pageY;
+
+ /*
+ * - Position constraining -
+ * Constrain the position to a mix of grid, containment.
+ */
+
+ if(this.originalPosition) { //If we are not dragging yet, we won't check for options
+
+ if(this.containment) {
+ if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
+ if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
+ if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
+ if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
+ }
+
+ if(o.grid) {
+ var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
+ pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
+
+ var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
+ pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
+ }
+
+ }
+
+ return {
+ top: (
+ pageY // The absolute mouse position
+ - this.offset.click.top // Click offset (relative to the element)
+ - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
+ - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
+ + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
+ ),
+ left: (
+ pageX // The absolute mouse position
+ - this.offset.click.left // Click offset (relative to the element)
+ - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
+ - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
+ + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
+ )
+ };
+
+ },
+
+ _rearrange: function(event, i, a, hardRefresh) {
+
+ a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling));
+
+ //Various things done here to improve the performance:
+ // 1. we create a setTimeout, that calls refreshPositions
+ // 2. on the instance, we have a counter variable, that get's higher after every append
+ // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
+ // 4. this lets only the last addition to the timeout stack through
+ this.counter = this.counter ? ++this.counter : 1;
+ var counter = this.counter;
+
+ // Cause error when sort widgets on dashboard. Error: Object has no _delay method
+ //this._delay(function() {
+ //if(counter == this.counter) this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
+ //});
+
+ },
+
+ _clear: function(event, noPropagation) {
+
+ this.reverting = false;
+ // We delay all events that have to be triggered to after the point where the placeholder has been removed and
+ // everything else normalized again
+ var delayedTriggers = [];
+
+ // We first have to update the dom position of the actual currentItem
+ // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
+ if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem);
+ this._noFinalSort = null;
+
+ if(this.helper[0] == this.currentItem[0]) {
+ for(var i in this._storedCSS) {
+ if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
+ }
+ this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
+ } else {
+ this.currentItem.show();
+ }
+
+ if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
+ if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
+
+ // Check if the items Container has Changed and trigger appropriate
+ // events.
+ if (this !== this.currentContainer) {
+ if(!noPropagation) {
+ delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
+ delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
+ delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
+ }
+ }
+
+
+ //Post events to containers
+ for (var i = this.containers.length - 1; i >= 0; i--){
+ if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
+ if(this.containers[i].containerCache.over) {
+ delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
+ this.containers[i].containerCache.over = 0;
+ }
+ }
+
+ //Do what was originally in plugins
+ if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
+ if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
+ if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
+
+ this.dragging = false;
+ if(this.cancelHelperRemoval) {
+ if(!noPropagation) {
+ this._trigger("beforeStop", event, this._uiHash());
+ for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
+ this._trigger("stop", event, this._uiHash());
+ }
+
+ this.fromOutside = false;
+ return false;
+ }
+
+ if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
+
+ //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
+ this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
+
+ if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
+
+ if(!noPropagation) {
+ for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
+ this._trigger("stop", event, this._uiHash());
+ }
+
+ this.fromOutside = false;
+ return true;
+
+ },
+
+ _trigger: function() {
+ if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
+ this.cancel();
+ }
+ },
+
+ _uiHash: function(_inst) {
+ var inst = _inst || this;
+ return {
+ helper: inst.helper,
+ placeholder: inst.placeholder || $([]),
+ position: inst.position,
+ originalPosition: inst.originalPosition,
+ offset: inst.positionAbs,
+ item: inst.currentItem,
+ sender: _inst ? _inst.element : null
+ };
+ }
+
+});
+
+})(jQuery);
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/jquery.ui.widget.js
----------------------------------------------------------------------
diff --git a/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/jquery.ui.widget.js b/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/jquery.ui.widget.js
new file mode 100644
index 0000000..544ce71
--- /dev/null
+++ b/ambari-web/contrib/views/slider/src/main/resources/ui/vendor/scripts/common/jquery.ui.widget.js
@@ -0,0 +1,276 @@
+/*!
+ * jQuery UI Widget 1.8.23
+ *
+ * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Widget
+ */
+(function ($, undefined) {
+
+// jQuery 1.4+
+ if ($.cleanData) {
+ var _cleanData = $.cleanData;
+ $.cleanData = function (elems) {
+ for (var i = 0, elem; (elem = elems[i]) != null; i++) {
+ try {
+ $(elem).triggerHandler("remove");
+ // http://bugs.jquery.com/ticket/8235
+ } catch (e) {
+ }
+ }
+ _cleanData(elems);
+ };
+ } else {
+ var _remove = $.fn.remove;
+ $.fn.remove = function (selector, keepData) {
+ return this.each(function () {
+ if (!keepData) {
+ if (!selector || $.filter(selector, [ this ]).length) {
+ $("*", this).add([ this ]).each(function () {
+ try {
+ $(this).triggerHandler("remove");
+ // http://bugs.jquery.com/ticket/8235
+ } catch (e) {
+ }
+ });
+ }
+ }
+ return _remove.call($(this), selector, keepData);
+ });
+ };
+ }
+
+ $.widget = function (name, base, prototype) {
+ var namespace = name.split(".")[ 0 ],
+ fullName;
+ name = name.split(".")[ 1 ];
+ fullName = namespace + "-" + name;
+
+ if (!prototype) {
+ prototype = base;
+ base = $.Widget;
+ }
+
+ // create selector for plugin
+ $.expr[ ":" ][ fullName ] = function (elem) {
+ return !!$.data(elem, name);
+ };
+
+ $[ namespace ] = $[ namespace ] || {};
+ $[ namespace ][ name ] = function (options, element) {
+ // allow instantiation without initializing for simple inheritance
+ if (arguments.length) {
+ this._createWidget(options, element);
+ }
+ };
+
+ var basePrototype = new base();
+ // we need to make the options hash a property directly on the new instance
+ // otherwise we'll modify the options hash on the prototype that we're
+ // inheriting from
+// $.each( basePrototype, function( key, val ) {
+// if ( $.isPlainObject(val) ) {
+// basePrototype[ key ] = $.extend( {}, val );
+// }
+// });
+ basePrototype.options = $.extend(true, {}, basePrototype.options);
+ $[ namespace ][ name ].prototype = $.extend(true, basePrototype, {
+ namespace:namespace,
+ widgetName:name,
+ widgetEventPrefix:$[ namespace ][ name ].prototype.widgetEventPrefix || name,
+ widgetBaseClass:fullName
+ }, prototype);
+
+ $.widget.bridge(name, $[ namespace ][ name ]);
+ };
+
+ $.widget.bridge = function (name, object) {
+ $.fn[ name ] = function (options) {
+ var isMethodCall = typeof options === "string",
+ args = Array.prototype.slice.call(arguments, 1),
+ returnValue = this;
+
+ // allow multiple hashes to be passed on init
+ options = !isMethodCall && args.length ?
+ $.extend.apply(null, [ true, options ].concat(args)) :
+ options;
+
+ // prevent calls to internal methods
+ if (isMethodCall && options.charAt(0) === "_") {
+ return returnValue;
+ }
+
+ if (isMethodCall) {
+ this.each(function () {
+ var instance = $.data(this, name),
+ methodValue = instance && $.isFunction(instance[options]) ?
+ instance[ options ].apply(instance, args) :
+ instance;
+ // TODO: add this back in 1.9 and use $.error() (see #5972)
+// if ( !instance ) {
+// throw "cannot call methods on " + name + " prior to initialization; " +
+// "attempted to call method '" + options + "'";
+// }
+// if ( !$.isFunction( instance[options] ) ) {
+// throw "no such method '" + options + "' for " + name + " widget instance";
+// }
+// var methodValue = instance[ options ].apply( instance, args );
+ if (methodValue !== instance && methodValue !== undefined) {
+ returnValue = methodValue;
+ return false;
+ }
+ });
+ } else {
+ this.each(function () {
+ var instance = $.data(this, name);
+ if (instance) {
+ instance.option(options || {})._init();
+ } else {
+ $.data(this, name, new object(options, this));
+ }
+ });
+ }
+
+ return returnValue;
+ };
+ };
+
+ $.Widget = function (options, element) {
+ // allow instantiation without initializing for simple inheritance
+ if (arguments.length) {
+ this._createWidget(options, element);
+ }
+ };
+
+ $.Widget.prototype = {
+ widgetName:"widget",
+ widgetEventPrefix:"",
+ options:{
+ disabled:false
+ },
+ _createWidget:function (options, element) {
+ // $.widget.bridge stores the plugin instance, but we do it anyway
+ // so that it's stored even before the _create function runs
+ $.data(element, this.widgetName, this);
+ this.element = $(element);
+ this.options = $.extend(true, {},
+ this.options,
+ this._getCreateOptions(),
+ options);
+
+ var self = this;
+ this.element.bind("remove." + this.widgetName, function () {
+ self.destroy();
+ });
+
+ this._create();
+ this._trigger("create");
+ this._init();
+ },
+ _getCreateOptions:function () {
+ return $.metadata && $.metadata.get(this.element[0])[ this.widgetName ];
+ },
+ _create:function () {
+ },
+ _init:function () {
+ },
+
+ destroy:function () {
+ this.element
+ .unbind("." + this.widgetName)
+ .removeData(this.widgetName);
+ this.widget()
+ .unbind("." + this.widgetName)
+ .removeAttr("aria-disabled")
+ .removeClass(
+ this.widgetBaseClass + "-disabled " +
+ "ui-state-disabled");
+ },
+
+ widget:function () {
+ return this.element;
+ },
+
+ option:function (key, value) {
+ var options = key;
+
+ if (arguments.length === 0) {
+ // don't return a reference to the internal hash
+ return $.extend({}, this.options);
+ }
+
+ if (typeof key === "string") {
+ if (value === undefined) {
+ return this.options[ key ];
+ }
+ options = {};
+ options[ key ] = value;
+ }
+
+ this._setOptions(options);
+
+ return this;
+ },
+ _setOptions:function (options) {
+ var self = this;
+ $.each(options, function (key, value) {
+ self._setOption(key, value);
+ });
+
+ return this;
+ },
+ _setOption:function (key, value) {
+ this.options[ key ] = value;
+
+ if (key === "disabled") {
+ this.widget()
+ [ value ? "addClass" : "removeClass"](
+ this.widgetBaseClass + "-disabled" + " " +
+ "ui-state-disabled")
+ .attr("aria-disabled", value);
+ }
+
+ return this;
+ },
+
+ enable:function () {
+ return this._setOption("disabled", false);
+ },
+ disable:function () {
+ return this._setOption("disabled", true);
+ },
+
+ _trigger:function (type, event, data) {
+ var prop, orig,
+ callback = this.options[ type ];
+
+ data = data || {};
+ event = $.Event(event);
+ event.type = ( type === this.widgetEventPrefix ?
+ type :
+ this.widgetEventPrefix + type ).toLowerCase();
+ // the original event may come from any element
+ // so we need to reset the target on the new event
+ event.target = this.element[ 0 ];
+
+ // copy original event properties over to the new event
+ orig = event.originalEvent;
+ if (orig) {
+ for (prop in orig) {
+ if (!( prop in event )) {
+ event[ prop ] = orig[ prop ];
+ }
+ }
+ }
+
+ this.element.trigger(event, data);
+
+ return !( $.isFunction(callback) &&
+ callback.call(this.element[0], event, data) === false ||
+ event.isDefaultPrevented() );
+ }
+ };
+
+})(jQuery);
[7/8] AMBARI-5928. Create and populate Metrics section of a slider
app. (onechiporenko)
Posted by on...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/79f3a1a3/ambari-web/contrib/views/slider/src/main/resources/ui/app/assets/data/metrics/metric2.json
----------------------------------------------------------------------
diff --git a/ambari-web/contrib/views/slider/src/main/resources/ui/app/assets/data/metrics/metric2.json b/ambari-web/contrib/views/slider/src/main/resources/ui/app/assets/data/metrics/metric2.json
new file mode 100644
index 0000000..15b9200
--- /dev/null
+++ b/ambari-web/contrib/views/slider/src/main/resources/ui/app/assets/data/metrics/metric2.json
@@ -0,0 +1,3838 @@
+{
+ "metrics" : {
+ "jvm" : {
+ "threadsBlocked" : [
+ [
+ 0.0,
+ 1401359115
+ ],
+ [
+ 0.0,
+ 1401359130
+ ],
+ [
+ 0.0,
+ 1401359145
+ ],
+ [
+ 0.0,
+ 1401359160
+ ],
+ [
+ 0.0,
+ 1401359175
+ ],
+ [
+ 0.0,
+ 1401359190
+ ],
+ [
+ 0.0,
+ 1401359205
+ ],
+ [
+ 0.0,
+ 1401359220
+ ],
+ [
+ 0.0,
+ 1401359235
+ ],
+ [
+ 0.0,
+ 1401359250
+ ],
+ [
+ 0.0,
+ 1401359265
+ ],
+ [
+ 0.0,
+ 1401359280
+ ],
+ [
+ 0.0,
+ 1401359295
+ ],
+ [
+ 0.0,
+ 1401359310
+ ],
+ [
+ 0.0,
+ 1401359325
+ ],
+ [
+ 0.0,
+ 1401359340
+ ],
+ [
+ 0.0,
+ 1401359355
+ ],
+ [
+ 0.0,
+ 1401359370
+ ],
+ [
+ 0.0,
+ 1401359385
+ ],
+ [
+ 0.0,
+ 1401359400
+ ],
+ [
+ 0.0,
+ 1401359415
+ ],
+ [
+ 0.0,
+ 1401359430
+ ],
+ [
+ 0.0,
+ 1401359445
+ ],
+ [
+ 0.0,
+ 1401359460
+ ],
+ [
+ 0.0,
+ 1401359475
+ ],
+ [
+ 0.0,
+ 1401359490
+ ],
+ [
+ 0.0,
+ 1401359505
+ ],
+ [
+ 0.0,
+ 1401359520
+ ],
+ [
+ 0.0,
+ 1401359535
+ ],
+ [
+ 0.0,
+ 1401359550
+ ],
+ [
+ 0.0,
+ 1401359565
+ ],
+ [
+ 0.0,
+ 1401359580
+ ],
+ [
+ 0.0,
+ 1401359595
+ ],
+ [
+ 0.0,
+ 1401359610
+ ],
+ [
+ 0.0,
+ 1401359625
+ ],
+ [
+ 0.0,
+ 1401359640
+ ],
+ [
+ 0.0,
+ 1401359655
+ ],
+ [
+ 0.0,
+ 1401359670
+ ],
+ [
+ 0.0,
+ 1401359685
+ ],
+ [
+ 0.0,
+ 1401359700
+ ],
+ [
+ 0.0,
+ 1401359715
+ ],
+ [
+ 0.0,
+ 1401359730
+ ],
+ [
+ 0.0,
+ 1401359745
+ ],
+ [
+ 0.0,
+ 1401359760
+ ],
+ [
+ 0.0,
+ 1401359775
+ ],
+ [
+ 0.0,
+ 1401359790
+ ],
+ [
+ 0.0,
+ 1401359805
+ ],
+ [
+ 0.0,
+ 1401359820
+ ],
+ [
+ 0.0,
+ 1401359835
+ ],
+ [
+ 0.0,
+ 1401359850
+ ],
+ [
+ 0.0,
+ 1401359865
+ ],
+ [
+ 0.0,
+ 1401359880
+ ],
+ [
+ 0.0,
+ 1401359895
+ ],
+ [
+ 0.0,
+ 1401359910
+ ],
+ [
+ 0.0,
+ 1401359925
+ ],
+ [
+ 0.0,
+ 1401359940
+ ],
+ [
+ 0.0,
+ 1401359955
+ ],
+ [
+ 0.0,
+ 1401359970
+ ],
+ [
+ 0.0,
+ 1401359985
+ ],
+ [
+ 0.0,
+ 1401360000
+ ],
+ [
+ 0.0,
+ 1401360015
+ ],
+ [
+ 0.0,
+ 1401360030
+ ],
+ [
+ 0.0,
+ 1401360045
+ ],
+ [
+ 0.0,
+ 1401360060
+ ],
+ [
+ 0.0,
+ 1401360075
+ ],
+ [
+ 0.0,
+ 1401360090
+ ],
+ [
+ 0.0,
+ 1401360105
+ ],
+ [
+ 0.0,
+ 1401360120
+ ],
+ [
+ 0.0,
+ 1401360135
+ ],
+ [
+ 0.0,
+ 1401360150
+ ],
+ [
+ 0.0,
+ 1401360165
+ ],
+ [
+ 0.0,
+ 1401360180
+ ],
+ [
+ 0.0,
+ 1401360195
+ ],
+ [
+ 0.0,
+ 1401360210
+ ],
+ [
+ 0.0,
+ 1401360225
+ ],
+ [
+ 0.0,
+ 1401360240
+ ],
+ [
+ 0.0,
+ 1401360255
+ ],
+ [
+ 0.0,
+ 1401360270
+ ],
+ [
+ 0.0,
+ 1401360285
+ ],
+ [
+ 0.0,
+ 1401360300
+ ],
+ [
+ 0.0,
+ 1401360315
+ ],
+ [
+ 0.0,
+ 1401360330
+ ],
+ [
+ 0.0,
+ 1401360345
+ ],
+ [
+ 0.0,
+ 1401360360
+ ],
+ [
+ 0.0,
+ 1401360375
+ ],
+ [
+ 0.0,
+ 1401360390
+ ],
+ [
+ 0.0,
+ 1401360405
+ ],
+ [
+ 0.0,
+ 1401360420
+ ],
+ [
+ 0.0,
+ 1401360435
+ ],
+ [
+ 0.0,
+ 1401360450
+ ],
+ [
+ 0.0,
+ 1401360465
+ ],
+ [
+ 0.0,
+ 1401360480
+ ],
+ [
+ 0.0,
+ 1401360495
+ ],
+ [
+ 0.0,
+ 1401360510
+ ],
+ [
+ 0.0,
+ 1401360525
+ ],
+ [
+ 0.0,
+ 1401360540
+ ],
+ [
+ 0.0,
+ 1401360555
+ ],
+ [
+ 0.0,
+ 1401360570
+ ],
+ [
+ 0.0,
+ 1401360585
+ ],
+ [
+ 0.0,
+ 1401360600
+ ],
+ [
+ 0.0,
+ 1401360615
+ ],
+ [
+ 0.0,
+ 1401360630
+ ],
+ [
+ 0.0,
+ 1401360645
+ ],
+ [
+ 0.0,
+ 1401360660
+ ],
+ [
+ 0.0,
+ 1401360675
+ ],
+ [
+ 0.0,
+ 1401360690
+ ],
+ [
+ 0.0,
+ 1401360705
+ ],
+ [
+ 0.0,
+ 1401360720
+ ],
+ [
+ 0.0,
+ 1401360735
+ ],
+ [
+ 0.0,
+ 1401360750
+ ],
+ [
+ 0.0,
+ 1401360765
+ ],
+ [
+ 0.0,
+ 1401360780
+ ],
+ [
+ 0.0,
+ 1401360795
+ ],
+ [
+ 0.0,
+ 1401360810
+ ],
+ [
+ 0.0,
+ 1401360825
+ ],
+ [
+ 0.0,
+ 1401360840
+ ],
+ [
+ 0.0,
+ 1401360855
+ ],
+ [
+ 0.0,
+ 1401360870
+ ],
+ [
+ 0.0,
+ 1401360885
+ ],
+ [
+ 0.0,
+ 1401360900
+ ],
+ [
+ 0.0,
+ 1401360915
+ ],
+ [
+ 0.0,
+ 1401360930
+ ],
+ [
+ 0.0,
+ 1401360945
+ ],
+ [
+ 0.0,
+ 1401360960
+ ],
+ [
+ 0.0,
+ 1401360975
+ ],
+ [
+ 0.0,
+ 1401360990
+ ],
+ [
+ 0.0,
+ 1401361005
+ ],
+ [
+ 0.0,
+ 1401361020
+ ],
+ [
+ 0.0,
+ 1401361035
+ ],
+ [
+ 0.0,
+ 1401361050
+ ],
+ [
+ 0.0,
+ 1401361065
+ ],
+ [
+ 0.0,
+ 1401361080
+ ],
+ [
+ 0.0,
+ 1401361095
+ ],
+ [
+ 0.0,
+ 1401361110
+ ],
+ [
+ 0.0,
+ 1401361125
+ ],
+ [
+ 0.0,
+ 1401361140
+ ],
+ [
+ 0.0,
+ 1401361155
+ ],
+ [
+ 0.0,
+ 1401361170
+ ],
+ [
+ 0.0,
+ 1401361185
+ ],
+ [
+ 0.0,
+ 1401361200
+ ],
+ [
+ 0.0,
+ 1401361215
+ ],
+ [
+ 0.0,
+ 1401361230
+ ],
+ [
+ 0.0,
+ 1401361245
+ ],
+ [
+ 0.0,
+ 1401361260
+ ],
+ [
+ 0.0,
+ 1401361275
+ ],
+ [
+ 0.0,
+ 1401361290
+ ],
+ [
+ 0.0,
+ 1401361305
+ ],
+ [
+ 0.0,
+ 1401361320
+ ],
+ [
+ 0.0,
+ 1401361335
+ ],
+ [
+ 0.0,
+ 1401361350
+ ],
+ [
+ 0.0,
+ 1401361365
+ ],
+ [
+ 0.0,
+ 1401361380
+ ],
+ [
+ 0.0,
+ 1401361395
+ ],
+ [
+ 0.0,
+ 1401361410
+ ],
+ [
+ 0.0,
+ 1401361425
+ ],
+ [
+ 0.0,
+ 1401361440
+ ],
+ [
+ 0.0,
+ 1401361455
+ ],
+ [
+ 0.0,
+ 1401361470
+ ],
+ [
+ 0.0,
+ 1401361485
+ ],
+ [
+ 0.0,
+ 1401361500
+ ],
+ [
+ 0.0,
+ 1401361515
+ ],
+ [
+ 0.0,
+ 1401361530
+ ],
+ [
+ 0.0,
+ 1401361545
+ ],
+ [
+ 0.0,
+ 1401361560
+ ],
+ [
+ 0.0,
+ 1401361575
+ ],
+ [
+ 0.0,
+ 1401361590
+ ],
+ [
+ 0.0,
+ 1401361605
+ ],
+ [
+ 0.0,
+ 1401361620
+ ],
+ [
+ 0.0,
+ 1401361635
+ ],
+ [
+ 0.0,
+ 1401361650
+ ],
+ [
+ 0.0,
+ 1401361665
+ ],
+ [
+ 0.0,
+ 1401361680
+ ],
+ [
+ 0.0,
+ 1401361695
+ ],
+ [
+ 0.0,
+ 1401361710
+ ],
+ [
+ 0.0,
+ 1401361725
+ ],
+ [
+ 0.0,
+ 1401361740
+ ],
+ [
+ 0.0,
+ 1401361755
+ ],
+ [
+ 0.0,
+ 1401361770
+ ],
+ [
+ 0.0,
+ 1401361785
+ ],
+ [
+ 0.0,
+ 1401361800
+ ],
+ [
+ 0.0,
+ 1401361815
+ ],
+ [
+ 0.0,
+ 1401361830
+ ],
+ [
+ 0.0,
+ 1401361845
+ ],
+ [
+ 0.0,
+ 1401361860
+ ],
+ [
+ 0.0,
+ 1401361875
+ ],
+ [
+ 0.0,
+ 1401361890
+ ],
+ [
+ 0.0,
+ 1401361905
+ ],
+ [
+ 0.0,
+ 1401361920
+ ],
+ [
+ 0.0,
+ 1401361935
+ ],
+ [
+ 0.0,
+ 1401361950
+ ],
+ [
+ 0.0,
+ 1401361965
+ ],
+ [
+ 0.0,
+ 1401361980
+ ],
+ [
+ 0.0,
+ 1401361995
+ ],
+ [
+ 0.0,
+ 1401362010
+ ],
+ [
+ 0.0,
+ 1401362025
+ ],
+ [
+ 0.0,
+ 1401362040
+ ],
+ [
+ 0.0,
+ 1401362055
+ ],
+ [
+ 0.0,
+ 1401362070
+ ],
+ [
+ 0.0,
+ 1401362085
+ ],
+ [
+ 0.0,
+ 1401362100
+ ],
+ [
+ 0.0,
+ 1401362115
+ ],
+ [
+ 0.0,
+ 1401362130
+ ],
+ [
+ 0.0,
+ 1401362145
+ ],
+ [
+ 0.0,
+ 1401362160
+ ],
+ [
+ 0.0,
+ 1401362175
+ ],
+ [
+ 0.0,
+ 1401362190
+ ],
+ [
+ 0.0,
+ 1401362205
+ ],
+ [
+ 0.0,
+ 1401362220
+ ],
+ [
+ 0.0,
+ 1401362235
+ ],
+ [
+ 0.0,
+ 1401362250
+ ],
+ [
+ 0.0,
+ 1401362265
+ ],
+ [
+ 0.0,
+ 1401362280
+ ],
+ [
+ 0.0,
+ 1401362295
+ ],
+ [
+ 0.0,
+ 1401362310
+ ],
+ [
+ 0.0,
+ 1401362325
+ ],
+ [
+ 0.0,
+ 1401362340
+ ],
+ [
+ 0.0,
+ 1401362355
+ ],
+ [
+ 0.0,
+ 1401362370
+ ],
+ [
+ 0.0,
+ 1401362385
+ ],
+ [
+ 0.0,
+ 1401362400
+ ],
+ [
+ 0.0,
+ 1401362415
+ ],
+ [
+ 0.0,
+ 1401362430
+ ],
+ [
+ 0.0,
+ 1401362445
+ ],
+ [
+ 0.0,
+ 1401362460
+ ],
+ [
+ 0.0,
+ 1401362475
+ ],
+ [
+ 0.0,
+ 1401362490
+ ],
+ [
+ 0.0,
+ 1401362505
+ ],
+ [
+ 0.0,
+ 1401362520
+ ],
+ [
+ 0.0,
+ 1401362535
+ ],
+ [
+ 0.0,
+ 1401362550
+ ],
+ [
+ 0.0,
+ 1401362565
+ ],
+ [
+ 0.0,
+ 1401362580
+ ],
+ [
+ 0.0,
+ 1401362595
+ ],
+ [
+ 0.0,
+ 1401362610
+ ],
+ [
+ 0.0,
+ 1401362625
+ ],
+ [
+ 0.0,
+ 1401362640
+ ],
+ [
+ 0.0,
+ 1401362655
+ ],
+ [
+ 0.0,
+ 1401362670
+ ],
+ [
+ 0.0,
+ 1401362685
+ ]
+ ],
+ "threadsRunnable" : [
+ [
+ 7.0,
+ 1401359115
+ ],
+ [
+ 7.0,
+ 1401359130
+ ],
+ [
+ 7.0,
+ 1401359145
+ ],
+ [
+ 7.0,
+ 1401359160
+ ],
+ [
+ 7.0,
+ 1401359175
+ ],
+ [
+ 7.0,
+ 1401359190
+ ],
+ [
+ 7.0,
+ 1401359205
+ ],
+ [
+ 7.0,
+ 1401359220
+ ],
+ [
+ 7.0,
+ 1401359235
+ ],
+ [
+ 7.0,
+ 1401359250
+ ],
+ [
+ 7.0,
+ 1401359265
+ ],
+ [
+ 7.0,
+ 1401359280
+ ],
+ [
+ 7.0,
+ 1401359295
+ ],
+ [
+ 7.0,
+ 1401359310
+ ],
+ [
+ 7.0,
+ 1401359325
+ ],
+ [
+ 7.0,
+ 1401359340
+ ],
+ [
+ 7.0,
+ 1401359355
+ ],
+ [
+ 7.0,
+ 1401359370
+ ],
+ [
+ 7.0,
+ 1401359385
+ ],
+ [
+ 7.0,
+ 1401359400
+ ],
+ [
+ 7.06666666667,
+ 1401359415
+ ],
+ [
+ 8.0,
+ 1401359430
+ ],
+ [
+ 7.93333333333,
+ 1401359445
+ ],
+ [
+ 7.0,
+ 1401359460
+ ],
+ [
+ 7.0,
+ 1401359475
+ ],
+ [
+ 7.0,
+ 1401359490
+ ],
+ [
+ 7.0,
+ 1401359505
+ ],
+ [
+ 7.0,
+ 1401359520
+ ],
+ [
+ 7.0,
+ 1401359535
+ ],
+ [
+ 7.0,
+ 1401359550
+ ],
+ [
+ 7.0,
+ 1401359565
+ ],
+ [
+ 7.0,
+ 1401359580
+ ],
+ [
+ 7.13333333333,
+ 1401359595
+ ],
+ [
+ 7.93333333333,
+ 1401359610
+ ],
+ [
+ 7.0,
+ 1401359625
+ ],
+ [
+ 7.0,
+ 1401359640
+ ],
+ [
+ 7.0,
+ 1401359655
+ ],
+ [
+ 7.06666666667,
+ 1401359670
+ ],
+ [
+ 7.93333333333,
+ 1401359685
+ ],
+ [
+ 7.0,
+ 1401359700
+ ],
+ [
+ 7.0,
+ 1401359715
+ ],
+ [
+ 7.0,
+ 1401359730
+ ],
+ [
+ 7.0,
+ 1401359745
+ ],
+ [
+ 7.0,
+ 1401359760
+ ],
+ [
+ 7.0,
+ 1401359775
+ ],
+ [
+ 7.13333333333,
+ 1401359790
+ ],
+ [
+ 7.86666666667,
+ 1401359805
+ ],
+ [
+ 7.0,
+ 1401359820
+ ],
+ [
+ 7.13333333333,
+ 1401359835
+ ],
+ [
+ 7.86666666667,
+ 1401359850
+ ],
+ [
+ 7.0,
+ 1401359865
+ ],
+ [
+ 7.0,
+ 1401359880
+ ],
+ [
+ 7.0,
+ 1401359895
+ ],
+ [
+ 7.0,
+ 1401359910
+ ],
+ [
+ 7.0,
+ 1401359925
+ ],
+ [
+ 7.0,
+ 1401359940
+ ],
+ [
+ 7.0,
+ 1401359955
+ ],
+ [
+ 7.0,
+ 1401359970
+ ],
+ [
+ 7.0,
+ 1401359985
+ ],
+ [
+ 7.0,
+ 1401360000
+ ],
+ [
+ 8.0,
+ 1401360015
+ ],
+ [
+ 7.0,
+ 1401360030
+ ],
+ [
+ 8.0,
+ 1401360045
+ ],
+ [
+ 7.06666666667,
+ 1401360060
+ ],
+ [
+ 7.0,
+ 1401360075
+ ],
+ [
+ 7.0,
+ 1401360090
+ ],
+ [
+ 7.0,
+ 1401360105
+ ],
+ [
+ 7.0,
+ 1401360120
+ ],
+ [
+ 7.0,
+ 1401360135
+ ],
+ [
+ 8.0,
+ 1401360150
+ ],
+ [
+ 7.06666666667,
+ 1401360165
+ ],
+ [
+ 7.0,
+ 1401360180
+ ],
+ [
+ 7.0,
+ 1401360195
+ ],
+ [
+ 7.86666666667,
+ 1401360210
+ ],
+ [
+ 7.13333333333,
+ 1401360225
+ ],
+ [
+ 7.0,
+ 1401360240
+ ],
+ [
+ 7.0,
+ 1401360255
+ ],
+ [
+ 7.0,
+ 1401360270
+ ],
+ [
+ 7.0,
+ 1401360285
+ ],
+ [
+ 7.0,
+ 1401360300
+ ],
+ [
+ 7.0,
+ 1401360315
+ ],
+ [
+ 7.0,
+ 1401360330
+ ],
+ [
+ 7.0,
+ 1401360345
+ ],
+ [
+ 7.0,
+ 1401360360
+ ],
+ [
+ 7.0,
+ 1401360375
+ ],
+ [
+ 7.0,
+ 1401360390
+ ],
+ [
+ 7.0,
+ 1401360405
+ ],
+ [
+ 7.0,
+ 1401360420
+ ],
+ [
+ 7.0,
+ 1401360435
+ ],
+ [
+ 7.0,
+ 1401360450
+ ],
+ [
+ 7.0,
+ 1401360465
+ ],
+ [
+ 7.0,
+ 1401360480
+ ],
+ [
+ 7.8,
+ 1401360495
+ ],
+ [
+ 7.2,
+ 1401360510
+ ],
+ [
+ 7.0,
+ 1401360525
+ ],
+ [
+ 7.0,
+ 1401360540
+ ],
+ [
+ 7.0,
+ 1401360555
+ ],
+ [
+ 7.0,
+ 1401360570
+ ],
+ [
+ 7.0,
+ 1401360585
+ ],
+ [
+ 7.0,
+ 1401360600
+ ],
+ [
+ 7.8,
+ 1401360615
+ ],
+ [
+ 7.2,
+ 1401360630
+ ],
+ [
+ 7.0,
+ 1401360645
+ ],
+ [
+ 7.0,
+ 1401360660
+ ],
+ [
+ 7.0,
+ 1401360675
+ ],
+ [
+ 7.0,
+ 1401360690
+ ],
+ [
+ 7.0,
+ 1401360705
+ ],
+ [
+ 7.0,
+ 1401360720
+ ],
+ [
+ 7.0,
+ 1401360735
+ ],
+ [
+ 7.0,
+ 1401360750
+ ],
+ [
+ 7.0,
+ 1401360765
+ ],
+ [
+ 7.0,
+ 1401360780
+ ],
+ [
+ 7.0,
+ 1401360795
+ ],
+ [
+ 7.0,
+ 1401360810
+ ],
+ [
+ 7.0,
+ 1401360825
+ ],
+ [
+ 7.0,
+ 1401360840
+ ],
+ [
+ 7.0,
+ 1401360855
+ ],
+ [
+ 7.0,
+ 1401360870
+ ],
+ [
+ 7.0,
+ 1401360885
+ ],
+ [
+ 7.0,
+ 1401360900
+ ],
+ [
+ 7.0,
+ 1401360915
+ ],
+ [
+ 7.0,
+ 1401360930
+ ],
+ [
+ 7.0,
+ 1401360945
+ ],
+ [
+ 7.0,
+ 1401360960
+ ],
+ [
+ 7.0,
+ 1401360975
+ ],
+ [
+ 7.0,
+ 1401360990
+ ],
+ [
+ 7.0,
+ 1401361005
+ ],
+ [
+ 7.0,
+ 1401361020
+ ],
+ [
+ 7.0,
+ 1401361035
+ ],
+ [
+ 7.0,
+ 1401361050
+ ],
+ [
+ 7.0,
+ 1401361065
+ ],
+ [
+ 7.0,
+ 1401361080
+ ],
+ [
+ 7.0,
+ 1401361095
+ ],
+ [
+ 7.0,
+ 1401361110
+ ],
+ [
+ 7.0,
+ 1401361125
+ ],
+ [
+ 7.0,
+ 1401361140
+ ],
+ [
+ 7.0,
+ 1401361155
+ ],
+ [
+ 7.0,
+ 1401361170
+ ],
+ [
+ 7.0,
+ 1401361185
+ ],
+ [
+ 7.0,
+ 1401361200
+ ],
+ [
+ 7.0,
+ 1401361215
+ ],
+ [
+ 7.0,
+ 1401361230
+ ],
+ [
+ 7.0,
+ 1401361245
+ ],
+ [
+ 7.0,
+ 1401361260
+ ],
+ [
+ 7.0,
+ 1401361275
+ ],
+ [
+ 7.0,
+ 1401361290
+ ],
+ [
+ 7.0,
+ 1401361305
+ ],
+ [
+ 7.0,
+ 1401361320
+ ],
+ [
+ 7.0,
+ 1401361335
+ ],
+ [
+ 7.0,
+ 1401361350
+ ],
+ [
+ 7.0,
+ 1401361365
+ ],
+ [
+ 7.0,
+ 1401361380
+ ],
+ [
+ 7.0,
+ 1401361395
+ ],
+ [
+ 7.0,
+ 1401361410
+ ],
+ [
+ 7.0,
+ 1401361425
+ ],
+ [
+ 7.0,
+ 1401361440
+ ],
+ [
+ 7.0,
+ 1401361455
+ ],
+ [
+ 7.0,
+ 1401361470
+ ],
+ [
+ 7.0,
+ 1401361485
+ ],
+ [
+ 7.0,
+ 1401361500
+ ],
+ [
+ 7.0,
+ 1401361515
+ ],
+ [
+ 7.0,
+ 1401361530
+ ],
+ [
+ 7.0,
+ 1401361545
+ ],
+ [
+ 7.0,
+ 1401361560
+ ],
+ [
+ 7.0,
+ 1401361575
+ ],
+ [
+ 7.0,
+ 1401361590
+ ],
+ [
+ 7.0,
+ 1401361605
+ ],
+ [
+ 7.0,
+ 1401361620
+ ],
+ [
+ 7.0,
+ 1401361635
+ ],
+ [
+ 7.0,
+ 1401361650
+ ],
+ [
+ 7.0,
+ 1401361665
+ ],
+ [
+ 7.0,
+ 1401361680
+ ],
+ [
+ 7.0,
+ 1401361695
+ ],
+ [
+ 7.0,
+ 1401361710
+ ],
+ [
+ 7.0,
+ 1401361725
+ ],
+ [
+ 7.0,
+ 1401361740
+ ],
+ [
+ 7.0,
+ 1401361755
+ ],
+ [
+ 7.0,
+ 1401361770
+ ],
+ [
+ 7.0,
+ 1401361785
+ ],
+ [
+ 7.0,
+ 1401361800
+ ],
+ [
+ 7.0,
+ 1401361815
+ ],
+ [
+ 7.0,
+ 1401361830
+ ],
+ [
+ 7.0,
+ 1401361845
+ ],
+ [
+ 7.0,
+ 1401361860
+ ],
+ [
+ 7.0,
+ 1401361875
+ ],
+ [
+ 7.0,
+ 1401361890
+ ],
+ [
+ 7.0,
+ 1401361905
+ ],
+ [
+ 7.0,
+ 1401361920
+ ],
+ [
+ 7.0,
+ 1401361935
+ ],
+ [
+ 7.0,
+ 1401361950
+ ],
+ [
+ 7.0,
+ 1401361965
+ ],
+ [
+ 7.0,
+ 1401361980
+ ],
+ [
+ 7.0,
+ 1401361995
+ ],
+ [
+ 7.0,
+ 1401362010
+ ],
+ [
+ 7.0,
+ 1401362025
+ ],
+ [
+ 7.0,
+ 1401362040
+ ],
+ [
+ 7.0,
+ 1401362055
+ ],
+ [
+ 7.0,
+ 1401362070
+ ],
+ [
+ 7.0,
+ 1401362085
+ ],
+ [
+ 7.0,
+ 1401362100
+ ],
+ [
+ 7.0,
+ 1401362115
+ ],
+ [
+ 7.0,
+ 1401362130
+ ],
+ [
+ 7.0,
+ 1401362145
+ ],
+ [
+ 7.0,
+ 1401362160
+ ],
+ [
+ 7.0,
+ 1401362175
+ ],
+ [
+ 7.0,
+ 1401362190
+ ],
+ [
+ 7.0,
+ 1401362205
+ ],
+ [
+ 7.0,
+ 1401362220
+ ],
+ [
+ 7.0,
+ 1401362235
+ ],
+ [
+ 7.0,
+ 1401362250
+ ],
+ [
+ 7.0,
+ 1401362265
+ ],
+ [
+ 7.0,
+ 1401362280
+ ],
+ [
+ 7.0,
+ 1401362295
+ ],
+ [
+ 7.0,
+ 1401362310
+ ],
+ [
+ 7.0,
+ 1401362325
+ ],
+ [
+ 7.0,
+ 1401362340
+ ],
+ [
+ 7.0,
+ 1401362355
+ ],
+ [
+ 7.0,
+ 1401362370
+ ],
+ [
+ 7.0,
+ 1401362385
+ ],
+ [
+ 7.0,
+ 1401362400
+ ],
+ [
+ 7.0,
+ 1401362415
+ ],
+ [
+ 7.0,
+ 1401362430
+ ],
+ [
+ 7.0,
+ 1401362445
+ ],
+ [
+ 7.0,
+ 1401362460
+ ],
+ [
+ 7.0,
+ 1401362475
+ ],
+ [
+ 7.0,
+ 1401362490
+ ],
+ [
+ 7.0,
+ 1401362505
+ ],
+ [
+ 7.0,
+ 1401362520
+ ],
+ [
+ 7.0,
+ 1401362535
+ ],
+ [
+ 7.0,
+ 1401362550
+ ],
+ [
+ 7.0,
+ 1401362565
+ ],
+ [
+ 7.0,
+ 1401362580
+ ],
+ [
+ 7.0,
+ 1401362595
+ ],
+ [
+ 7.0,
+ 1401362610
+ ],
+ [
+ 7.0,
+ 1401362625
+ ],
+ [
+ 7.0,
+ 1401362640
+ ],
+ [
+ 7.0,
+ 1401362655
+ ],
+ [
+ 7.0,
+ 1401362670
+ ],
+ [
+ 7.0,
+ 1401362685
+ ]
+ ],
+ "threadsTimedWaiting" : [
+ [
+ 54.0666666667,
+ 1401359115
+ ],
+ [
+ 55.0,
+ 1401359130
+ ],
+ [
+ 55.0,
+ 1401359145
+ ],
+ [
+ 54.9333333333,
+ 1401359160
+ ],
+ [
+ 54.0,
+ 1401359175
+ ],
+ [
+ 54.0,
+ 1401359190
+ ],
+ [
+ 54.0,
+ 1401359205
+ ],
+ [
+ 54.0,
+ 1401359220
+ ],
+ [
+ 54.0,
+ 1401359235
+ ],
+ [
+ 54.0,
+ 1401359250
+ ],
+ [
+ 54.0,
+ 1401359265
+ ],
+ [
+ 54.0,
+ 1401359280
+ ],
+ [
+ 54.0,
+ 1401359295
+ ],
+ [
+ 54.0,
+ 1401359310
+ ],
+ [
+ 54.0,
+ 1401359325
+ ],
+ [
+ 54.0,
+ 1401359340
+ ],
+ [
+ 54.0,
+ 1401359355
+ ],
+ [
+ 54.0,
+ 1401359370
+ ],
+ [
+ 54.0,
+ 1401359385
+ ],
+ [
+ 54.0,
+ 1401359400
+ ],
+ [
+ 53.9333333333,
+ 1401359415
+ ],
+ [
+ 53.0,
+ 1401359430
+ ],
+ [
+ 53.0666666667,
+ 1401359445
+ ],
+ [
+ 54.0,
+ 1401359460
+ ],
+ [
+ 54.1333333333,
+ 1401359475
+ ],
+ [
+ 55.0,
+ 1401359490
+ ],
+ [
+ 55.0,
+ 1401359505
+ ],
+ [
+ 55.0,
+ 1401359520
+ ],
+ [
+ 54.8666666667,
+ 1401359535
+ ],
+ [
+ 54.0,
+ 1401359550
+ ],
+ [
+ 54.0,
+ 1401359565
+ ],
+ [
+ 54.0666666667,
+ 1401359580
+ ],
+ [
+ 54.7333333333,
+ 1401359595
+ ],
+ [
+ 53.0666666667,
+ 1401359610
+ ],
+ [
+ 54.0,
+ 1401359625
+ ],
+ [
+ 54.0666666667,
+ 1401359640
+ ],
+ [
+ 54.9333333333,
+ 1401359655
+ ],
+ [
+ 53.9333333333,
+ 1401359670
+ ],
+ [
+ 53.1333333333,
+ 1401359685
+ ],
+ [
+ 55.0,
+ 1401359700
+ ],
+ [
+ 54.8666666667,
+ 1401359715
+ ],
+ [
+ 54.0,
+ 1401359730
+ ],
+ [
+ 54.0,
+ 1401359745
+ ],
+ [
+ 54.0,
+ 1401359760
+ ],
+ [
+ 54.0,
+ 1401359775
+ ],
+ [
+ 53.8666666667,
+ 1401359790
+ ],
+ [
+ 53.1333333333,
+ 1401359805
+ ],
+ [
+ 54.0,
+ 1401359820
+ ],
+ [
+ 53.8666666667,
+ 1401359835
+ ],
+ [
+ 53.1333333333,
+ 1401359850
+ ],
+ [
+ 54.0,
+ 1401359865
+ ],
+ [
+ 54.0,
+ 1401359880
+ ],
+ [
+ 54.0,
+ 1401359895
+ ],
+ [
+ 54.0,
+ 1401359910
+ ],
+ [
+ 54.0,
+ 1401359925
+ ],
+ [
+ 54.0,
+ 1401359940
+ ],
+ [
+ 54.0,
+ 1401359955
+ ],
+ [
+ 54.0,
+ 1401359970
+ ],
+ [
+ 54.0,
+ 1401359985
+ ],
+ [
+ 54.0,
+ 1401360000
+ ],
+ [
+ 53.0,
+ 1401360015
+ ],
+ [
+ 54.0,
+ 1401360030
+ ],
+ [
+ 52.0,
+ 1401360045
+ ],
+ [
+ 53.8666666667,
+ 1401360060
+ ],
+ [
+ 54.0,
+ 1401360075
+ ],
+ [
+ 54.0,
+ 1401360090
+ ],
+ [
+ 55.0,
+ 1401360105
+ ],
+ [
+ 54.0,
+ 1401360120
+ ],
+ [
+ 54.0,
+ 1401360135
+ ],
+ [
+ 53.0,
+ 1401360150
+ ],
+ [
+ 53.9333333333,
+ 1401360165
+ ],
+ [
+ 54.0,
+ 1401360180
+ ],
+ [
+ 54.0,
+ 1401360195
+ ],
+ [
+ 53.1333333333,
+ 1401360210
+ ],
+ [
+ 53.8666666667,
+ 1401360225
+ ],
+ [
+ 54.0,
+ 1401360240
+ ],
+ [
+ 54.0,
+ 1401360255
+ ],
+ [
+ 54.0,
+ 1401360270
+ ],
+ [
+ 54.8666666667,
+ 1401360285
+ ],
+ [
+ 54.0666666667,
+ 1401360300
+ ],
+ [
+ 54.0,
+ 1401360315
+ ],
+ [
+ 54.0,
+ 1401360330
+ ],
+ [
+ 54.0,
+ 1401360345
+ ],
+ [
+ 54.0,
+ 1401360360
+ ],
+ [
+ 54.0,
+ 1401360375
+ ],
+ [
+ 54.0,
+ 1401360390
+ ],
+ [
+ 54.8666666667,
+ 1401360405
+ ],
+ [
+ 54.1333333333,
+ 1401360420
+ ],
+ [
+ 54.0,
+ 1401360435
+ ],
+ [
+ 54.0,
+ 1401360450
+ ],
+ [
+ 54.0,
+ 1401360465
+ ],
+ [
+ 54.0,
+ 1401360480
+ ],
+ [
+ 53.2,
+ 1401360495
+ ],
+ [
+ 53.8,
+ 1401360510
+ ],
+ [
+ 54.0,
+ 1401360525
+ ],
+ [
+ 54.0,
+ 1401360540
+ ],
+ [
+ 54.0,
+ 1401360555
+ ],
+ [
+ 54.0,
+ 1401360570
+ ],
+ [
+ 54.0,
+ 1401360585
+ ],
+ [
+ 54.0,
+ 1401360600
+ ],
+ [
+ 53.2,
+ 1401360615
+ ],
+ [
+ 53.8,
+ 1401360630
+ ],
+ [
+ 54.0,
+ 1401360645
+ ],
+ [
+ 54.0,
+ 1401360660
+ ],
+ [
+ 54.0,
+ 1401360675
+ ],
+ [
+ 54.0,
+ 1401360690
+ ],
+ [
+ 54.0,
+ 1401360705
+ ],
+ [
+ 54.0,
+ 1401360720
+ ],
+ [
+ 54.0,
+ 1401360735
+ ],
+ [
+ 54.0,
+ 1401360750
+ ],
+ [
+ 54.0,
+ 1401360765
+ ],
+ [
+ 54.0,
+ 1401360780
+ ],
+ [
+ 54.0,
+ 1401360795
+ ],
+ [
+ 54.0,
+ 1401360810
+ ],
+ [
+ 54.0,
+ 1401360825
+ ],
+ [
+ 54.0,
+ 1401360840
+ ],
+ [
+ 54.0,
+ 1401360855
+ ],
+ [
+ 54.0,
+ 1401360870
+ ],
+ [
+ 54.0,
+ 1401360885
+ ],
+ [
+ 54.0,
+ 1401360900
+ ],
+ [
+ 53.2666666667,
+ 1401360915
+ ],
+ [
+ 53.7333333333,
+ 1401360930
+ ],
+ [
+ 54.0,
+ 1401360945
+ ],
+ [
+ 54.0,
+ 1401360960
+ ],
+ [
+ 54.0,
+ 1401360975
+ ],
+ [
+ 54.0,
+ 1401360990
+ ],
+ [
+ 54.0,
+ 1401361005
+ ],
+ [
+ 54.0,
+ 1401361020
+ ],
+ [
+ 54.0,
+ 1401361035
+ ],
+ [
+ 54.0,
+ 1401361050
+ ],
+ [
+ 54.0,
+ 1401361065
+ ],
+ [
+ 54.8,
+ 1401361080
+ ],
+ [
+ 55.0,
+ 1401361095
+ ],
+ [
+ 54.2,
+ 1401361110
+ ],
+ [
+ 54.0,
+ 1401361125
+ ],
+ [
+ 54.0,
+ 1401361140
+ ],
+ [
+ 54.0,
+ 1401361155
+ ],
+ [
+ 54.0,
+ 1401361170
+ ],
+ [
+ 54.0,
+ 1401361185
+ ],
+ [
+ 54.0,
+ 1401361200
+ ],
+ [
+ 54.0,
+ 1401361215
+ ],
+ [
+ 54.0,
+ 1401361230
+ ],
+ [
+ 54.7333333333,
+ 1401361245
+ ],
+ [
+ 55.0,
+ 1401361260
+ ],
+ [
+ 55.0,
+ 1401361275
+ ],
+ [
+ 54.2666666667,
+ 1401361290
+ ],
+ [
+ 54.0,
+ 1401361305
+ ],
+ [
+ 54.0,
+ 1401361320
+ ],
+ [
+ 54.0,
+ 1401361335
+ ],
+ [
+ 54.0,
+ 1401361350
+ ],
+ [
+ 54.0,
+ 1401361365
+ ],
+ [
+ 54.7333333333,
+ 1401361380
+ ],
+ [
+ 55.0,
+ 1401361395
+ ],
+ [
+ 54.2666666667,
+ 1401361410
+ ],
+ [
+ 54.0,
+ 1401361425
+ ],
+ [
+ 54.0,
+ 1401361440
+ ],
+ [
+ 54.0,
+ 1401361455
+ ],
+ [
+ 54.0,
+ 1401361470
+ ],
+ [
+ 54.0,
+ 1401361485
+ ],
+ [
+ 54.0,
+ 1401361500
+ ],
+ [
+ 54.0,
+ 1401361515
+ ],
+ [
+ 54.0,
+ 1401361530
+ ],
+ [
+ 54.0,
+ 1401361545
+ ],
+ [
+ 54.0,
+ 1401361560
+ ],
+ [
+ 54.0,
+ 1401361575
+ ],
+ [
+ 54.0,
+ 1401361590
+ ],
+ [
+ 54.0,
+ 1401361605
+ ],
+ [
+ 54.0,
+ 1401361620
+ ],
+ [
+ 54.0,
+ 1401361635
+ ],
+ [
+ 54.0,
+ 1401361650
+ ],
+ [
+ 54.0,
+ 1401361665
+ ],
+ [
+ 54.0,
+ 1401361680
+ ],
+ [
+ 54.0,
+ 1401361695
+ ],
+ [
+ 54.0,
+ 1401361710
+ ],
+ [
+ 53.2666666667,
+ 1401361725
+ ],
+ [
+ 53.7333333333,
+ 1401361740
+ ],
+ [
+ 54.0,
+ 1401361755
+ ],
+ [
+ 54.0,
+ 1401361770
+ ],
+ [
+ 54.0,
+ 1401361785
+ ],
+ [
+ 54.0,
+ 1401361800
+ ],
+ [
+ 54.0,
+ 1401361815
+ ],
+ [
+ 54.0,
+ 1401361830
+ ],
+ [
+ 54.0,
+ 1401361845
+ ],
+ [
+ 54.0,
+ 1401361860
+ ],
+ [
+ 54.0,
+ 1401361875
+ ],
+ [
+ 54.0,
+ 1401361890
+ ],
+ [
+ 54.0,
+ 1401361905
+ ],
+ [
+ 54.0,
+ 1401361920
+ ],
+ [
+ 54.0,
+ 1401361935
+ ],
+ [
+ 54.0,
+ 1401361950
+ ],
+ [
+ 54.0,
+ 1401361965
+ ],
+ [
+ 54.0,
+ 1401361980
+ ],
+ [
+ 54.0,
+ 1401361995
+ ],
+ [
+ 54.0,
+ 1401362010
+ ],
+ [
+ 54.0,
+ 1401362025
+ ],
+ [
+ 54.0,
+ 1401362040
+ ],
+ [
+ 54.0,
+ 1401362055
+ ],
+ [
+ 54.0,
+ 1401362070
+ ],
+ [
+ 54.0,
+ 1401362085
+ ],
+ [
+ 54.0,
+ 1401362100
+ ],
+ [
+ 54.0,
+ 1401362115
+ ],
+ [
+ 54.0,
+ 1401362130
+ ],
+ [
+ 54.0,
+ 1401362145
+ ],
+ [
+ 54.0,
+ 1401362160
+ ],
+ [
+ 54.0,
+ 1401362175
+ ],
+ [
+ 54.7333333333,
+ 1401362190
+ ],
+ [
+ 55.0,
+ 1401362205
+ ],
+ [
+ 55.0,
+ 1401362220
+ ],
+ [
+ 54.2,
+ 1401362235
+ ],
+ [
+ 54.0,
+ 1401362250
+ ],
+ [
+ 54.0,
+ 1401362265
+ ],
+ [
+ 54.0,
+ 1401362280
+ ],
+ [
+ 54.0,
+ 1401362295
+ ],
+ [
+ 54.0,
+ 1401362310
+ ],
+ [
+ 54.0,
+ 1401362325
+ ],
+ [
+ 54.0,
+ 1401362340
+ ],
+ [
+ 54.0,
+ 1401362355
+ ],
+ [
+ 54.0,
+ 1401362370
+ ],
+ [
+ 54.0,
+ 1401362385
+ ],
+ [
+ 54.0,
+ 1401362400
+ ],
+ [
+ 54.0,
+ 1401362415
+ ],
+ [
+ 54.0,
+ 1401362430
+ ],
+ [
+ 54.0,
+ 1401362445
+ ],
+ [
+ 54.0,
+ 1401362460
+ ],
+ [
+ 54.0,
+ 1401362475
+ ],
+ [
+ 54.0,
+ 1401362490
+ ],
+ [
+ 54.0,
+ 1401362505
+ ],
+ [
+ 54.0,
+ 1401362520
+ ],
+ [
+ 54.0,
+ 1401362535
+ ],
+ [
+ 54.0,
+ 1401362550
+ ],
+ [
+ 54.0,
+ 1401362565
+ ],
+ [
+ 54.0,
+ 1401362580
+ ],
+ [
+ 54.0,
+ 1401362595
+ ],
+ [
+ 54.0,
+ 1401362610
+ ],
+ [
+ 54.0,
+ 1401362625
+ ],
+ [
+ 54.6666666667,
+ 1401362640
+ ],
+ [
+ 55.0,
+ 1401362655
+ ],
+ [
+ 54.2666666667,
+ 1401362670
+ ],
+ [
+ 54.0,
+ 1401362685
+ ]
+ ],
+ "threadsWaiting" : [
+ [
+ 4.0,
+ 1401359115
+ ],
+ [
+ 4.0,
+ 1401359130
+ ],
+ [
+ 4.0,
+ 1401359145
+ ],
+ [
+ 4.0,
+ 1401359160
+ ],
+ [
+ 4.0,
+ 1401359175
+ ],
+ [
+ 4.0,
+ 1401359190
+ ],
+ [
+ 4.0,
+ 1401359205
+ ],
+ [
+ 4.0,
+ 1401359220
+ ],
+ [
+ 4.0,
+ 1401359235
+ ],
+ [
+ 4.0,
+ 1401359250
+ ],
+ [
+ 4.0,
+ 1401359265
+ ],
+ [
+ 4.0,
+ 1401359280
+ ],
+ [
+ 4.0,
+ 1401359295
+ ],
+ [
+ 4.0,
+ 1401359310
+ ],
+ [
+ 4.0,
+ 1401359325
+ ],
+ [
+ 4.0,
+ 1401359340
+ ],
+ [
+ 4.0,
+ 1401359355
+ ],
+ [
+ 4.0,
+ 1401359370
+ ],
+ [
+ 4.0,
+ 1401359385
+ ],
+ [
+ 4.0,
+ 1401359400
+ ],
+ [
+ 4.0,
+ 1401359415
+ ],
+ [
+ 4.0,
+ 1401359430
+ ],
+ [
+ 4.0,
+ 1401359445
+ ],
+ [
+ 4.0,
+ 1401359460
+ ],
+ [
+ 4.0,
+ 1401359475
+ ],
+ [
+ 4.0,
+ 1401359490
+ ],
+ [
+ 4.0,
+ 1401359505
+ ],
+ [
+ 4.0,
+ 1401359520
+ ],
+ [
+ 4.0,
+ 1401359535
+ ],
+ [
+ 4.0,
+ 1401359550
+ ],
+ [
+ 4.0,
+ 1401359565
+ ],
+ [
+ 4.0,
+ 1401359580
+ ],
+ [
+ 4.0,
+ 1401359595
+ ],
+ [
+ 4.0,
+ 1401359610
+ ],
+ [
+ 4.0,
+ 1401359625
+ ],
+ [
+ 4.0,
+ 1401359640
+ ],
+ [
+ 4.0,
+ 1401359655
+ ],
+ [
+ 4.0,
+ 1401359670
+ ],
+ [
+ 4.0,
+ 1401359685
+ ],
+ [
+ 4.0,
+ 1401359700
+ ],
+ [
+ 4.0,
+ 1401359715
+ ],
+ [
+ 4.0,
+ 1401359730
+ ],
+ [
+ 4.0,
+ 1401359745
+ ],
+ [
+ 4.0,
+ 1401359760
+ ],
+ [
+ 4.0,
+ 1401359775
+ ],
+ [
+ 4.0,
+ 1401359790
+ ],
+ [
+ 4.0,
+ 1401359805
+ ],
+ [
+ 4.0,
+ 1401359820
+ ],
+ [
+ 4.0,
+ 1401359835
+ ],
+ [
+ 4.0,
+ 1401359850
+ ],
+ [
+ 4.0,
+ 1401359865
+ ],
+ [
+ 4.0,
+ 1401359880
+ ],
+ [
+ 4.0,
+ 1401359895
+ ],
+ [
+ 4.0,
+ 1401359910
+ ],
+ [
+ 4.0,
+ 1401359925
+ ],
+ [
+ 4.0,
+ 1401359940
+ ],
+ [
+ 4.0,
+ 1401359955
+ ],
+ [
+ 4.0,
+ 1401359970
+ ],
+ [
+ 4.0,
+ 1401359985
+ ],
+ [
+ 4.0,
+ 1401360000
+ ],
+ [
+ 4.0,
+ 1401360015
+ ],
+ [
+ 4.0,
+ 1401360030
+ ],
+ [
+ 4.0,
+ 1401360045
+ ],
+ [
+ 4.0,
+ 1401360060
+ ],
+ [
+ 4.0,
+ 1401360075
+ ],
+ [
+ 4.0,
+ 1401360090
+ ],
+ [
+ 4.0,
+ 1401360105
+ ],
+ [
+ 4.0,
+ 1401360120
+ ],
+ [
+ 4.0,
+ 1401360135
+ ],
+ [
+ 4.0,
+ 1401360150
+ ],
+ [
+ 4.0,
+ 1401360165
+ ],
+ [
+ 4.0,
+ 1401360180
+ ],
+ [
+ 4.0,
+ 1401360195
+ ],
+ [
+ 4.0,
+ 1401360210
+ ],
+ [
+ 4.0,
+ 1401360225
+ ],
+ [
+ 4.0,
+ 1401360240
+ ],
+ [
+ 4.0,
+ 1401360255
+ ],
+ [
+ 4.0,
+ 1401360270
+ ],
+ [
+ 4.0,
+ 1401360285
+ ],
+ [
+ 4.0,
+ 1401360300
+ ],
+ [
+ 4.0,
+ 1401360315
+ ],
+ [
+ 4.0,
+ 1401360330
+ ],
+ [
+ 4.0,
+ 1401360345
+ ],
+ [
+ 4.0,
+ 1401360360
+ ],
+ [
+ 4.0,
+ 1401360375
+ ],
+ [
+ 4.0,
+ 1401360390
+ ],
+ [
+ 4.0,
+ 1401360405
+ ],
+ [
+ 4.0,
+ 1401360420
+ ],
+ [
+ 4.0,
+ 1401360435
+ ],
+ [
+ 4.0,
+ 1401360450
+ ],
+ [
+ 4.0,
+ 1401360465
+ ],
+ [
+ 4.0,
+ 1401360480
+ ],
+ [
+ 4.0,
+ 1401360495
+ ],
+ [
+ 4.0,
+ 1401360510
+ ],
+ [
+ 4.0,
+ 1401360525
+ ],
+ [
+ 4.0,
+ 1401360540
+ ],
+ [
+ 4.0,
+ 1401360555
+ ],
+ [
+ 4.0,
+ 1401360570
+ ],
+ [
+ 4.0,
+ 1401360585
+ ],
+ [
+ 4.0,
+ 1401360600
+ ],
+ [
+ 4.0,
+ 1401360615
+ ],
+ [
+ 4.0,
+ 1401360630
+ ],
+ [
+ 4.0,
+ 1401360645
+ ],
+ [
+ 4.0,
+ 1401360660
+ ],
+ [
+ 4.0,
+ 1401360675
+ ],
+ [
+ 4.0,
+ 1401360690
+ ],
+ [
+ 4.0,
+ 1401360705
+ ],
+ [
+ 4.0,
+ 1401360720
+ ],
+ [
+ 4.0,
+ 1401360735
+ ],
+ [
+ 4.0,
+ 1401360750
+ ],
+ [
+ 4.0,
+ 1401360765
+ ],
+ [
+ 4.0,
+ 1401360780
+ ],
+ [
+ 4.0,
+ 1401360795
+ ],
+ [
+ 4.0,
+ 1401360810
+ ],
+ [
+ 4.0,
+ 1401360825
+ ],
+ [
+ 4.0,
+ 1401360840
+ ],
+ [
+ 4.0,
+ 1401360855
+ ],
+ [
+ 4.0,
+ 1401360870
+ ],
+ [
+ 4.0,
+ 1401360885
+ ],
+ [
+ 4.0,
+ 1401360900
+ ],
+ [
+ 4.0,
+ 1401360915
+ ],
+ [
+ 4.0,
+ 1401360930
+ ],
+ [
+ 4.0,
+ 1401360945
+ ],
+ [
+ 4.0,
+ 1401360960
+ ],
+ [
+ 4.0,
+ 1401360975
+ ],
+ [
+ 4.0,
+ 1401360990
+ ],
+ [
+ 4.0,
+ 1401361005
+ ],
+ [
+ 4.0,
+ 1401361020
+ ],
+ [
+ 4.0,
+ 1401361035
+ ],
+ [
+ 4.0,
+ 1401361050
+ ],
+ [
+ 4.0,
+ 1401361065
+ ],
+ [
+ 4.0,
+ 1401361080
+ ],
+ [
+ 4.0,
+ 1401361095
+ ],
+ [
+ 4.0,
+ 1401361110
+ ],
+ [
+ 4.0,
+ 1401361125
+ ],
+ [
+ 4.0,
+ 1401361140
+ ],
+ [
+ 4.0,
+ 1401361155
+ ],
+ [
+ 4.0,
+ 1401361170
+ ],
+ [
+ 4.0,
+ 1401361185
+ ],
+ [
+ 4.0,
+ 1401361200
+ ],
+ [
+ 4.0,
+ 1401361215
+ ],
+ [
+ 4.0,
+ 1401361230
+ ],
+ [
+ 4.0,
+ 1401361245
+ ],
+ [
+ 4.0,
+ 1401361260
+ ],
+ [
+ 4.0,
+ 1401361275
+ ],
+ [
+ 4.0,
+ 1401361290
+ ],
+ [
+ 4.0,
+ 1401361305
+ ],
+ [
+ 4.0,
+ 1401361320
+ ],
+ [
+ 4.0,
+ 1401361335
+ ],
+ [
+ 4.0,
+ 1401361350
+ ],
+ [
+ 4.0,
+ 1401361365
+ ],
+ [
+ 4.0,
+ 1401361380
+ ],
+ [
+ 4.0,
+ 1401361395
+ ],
+ [
+ 4.0,
+ 1401361410
+ ],
+ [
+ 4.0,
+ 1401361425
+ ],
+ [
+ 4.0,
+ 1401361440
+ ],
+ [
+ 4.0,
+ 1401361455
+ ],
+ [
+ 4.0,
+ 1401361470
+ ],
+ [
+ 4.0,
+ 1401361485
+ ],
+ [
+ 4.0,
+ 1401361500
+ ],
+ [
+ 4.0,
+ 1401361515
+ ],
+ [
+ 4.0,
+ 1401361530
+ ],
+ [
+ 4.0,
+ 1401361545
+ ],
+ [
+ 4.0,
+ 1401361560
+ ],
+ [
+ 4.0,
+ 1401361575
+ ],
+ [
+ 4.0,
+ 1401361590
+ ],
+ [
+ 4.0,
+ 1401361605
+ ],
+ [
+ 4.0,
+ 1401361620
+ ],
+ [
+ 4.0,
+ 1401361635
+ ],
+ [
+ 4.0,
+ 1401361650
+ ],
+ [
+ 4.0,
+ 1401361665
+ ],
+ [
+ 4.0,
+ 1401361680
+ ],
+ [
+ 4.0,
+ 1401361695
+ ],
+ [
+ 4.0,
+ 1401361710
+ ],
+ [
+ 4.0,
+ 1401361725
+ ],
+ [
+ 4.0,
+ 1401361740
+ ],
+ [
+ 4.0,
+ 1401361755
+ ],
+ [
+ 4.0,
+ 1401361770
+ ],
+ [
+ 4.0,
+ 1401361785
+ ],
+ [
+ 4.0,
+ 1401361800
+ ],
+ [
+ 4.0,
+ 1401361815
+ ],
+ [
+ 4.0,
+ 1401361830
+ ],
+ [
+ 4.0,
+ 1401361845
+ ],
+ [
+ 4.0,
+ 1401361860
+ ],
+ [
+ 4.0,
+ 1401361875
+ ],
+ [
+ 4.0,
+ 1401361890
+ ],
+ [
+ 4.0,
+ 1401361905
+ ],
+ [
+ 4.0,
+ 1401361920
+ ],
+ [
+ 4.0,
+ 1401361935
+ ],
+ [
+ 4.0,
+ 1401361950
+ ],
+ [
+ 4.0,
+ 1401361965
+ ],
+ [
+ 4.0,
+ 1401361980
+ ],
+ [
+ 4.0,
+ 1401361995
+ ],
+ [
+ 4.0,
+ 1401362010
+ ],
+ [
+ 4.0,
+ 1401362025
+ ],
+ [
+ 4.0,
+ 1401362040
+ ],
+ [
+ 4.0,
+ 1401362055
+ ],
+ [
+ 4.0,
+ 1401362070
+ ],
+ [
+ 4.0,
+ 1401362085
+ ],
+ [
+ 4.0,
+ 1401362100
+ ],
+ [
+ 4.0,
+ 1401362115
+ ],
+ [
+ 4.0,
+ 1401362130
+ ],
+ [
+ 4.0,
+ 1401362145
+ ],
+ [
+ 4.0,
+ 1401362160
+ ],
+ [
+ 4.0,
+ 1401362175
+ ],
+ [
+ 4.0,
+ 1401362190
+ ],
+ [
+ 4.0,
+ 1401362205
+ ],
+ [
+ 4.0,
+ 1401362220
+ ],
+ [
+ 4.0,
+ 1401362235
+ ],
+ [
+ 4.0,
+ 1401362250
+ ],
+ [
+ 4.0,
+ 1401362265
+ ],
+ [
+ 4.0,
+ 1401362280
+ ],
+ [
+ 4.0,
+ 1401362295
+ ],
+ [
+ 4.0,
+ 1401362310
+ ],
+ [
+ 4.0,
+ 1401362325
+ ],
+ [
+ 4.0,
+ 1401362340
+ ],
+ [
+ 4.0,
+ 1401362355
+ ],
+ [
+ 4.0,
+ 1401362370
+ ],
+ [
+ 4.0,
+ 1401362385
+ ],
+ [
+ 4.0,
+ 1401362400
+ ],
+ [
+ 4.0,
+ 1401362415
+ ],
+ [
+ 4.0,
+ 1401362430
+ ],
+ [
+ 4.0,
+ 1401362445
+ ],
+ [
+ 4.0,
+ 1401362460
+ ],
+ [
+ 4.0,
+ 1401362475
+ ],
+ [
+ 4.0,
+ 1401362490
+ ],
+ [
+ 4.0,
+ 1401362505
+ ],
+ [
+ 4.0,
+ 1401362520
+ ],
+ [
+ 4.0,
+ 1401362535
+ ],
+ [
+ 4.0,
+ 1401362550
+ ],
+ [
+ 4.0,
+ 1401362565
+ ],
+ [
+ 4.0,
+ 1401362580
+ ],
+ [
+ 4.0,
+ 1401362595
+ ],
+ [
+ 4.0,
+ 1401362610
+ ],
+ [
+ 4.0,
+ 1401362625
+ ],
+ [
+ 4.0,
+ 1401362640
+ ],
+ [
+ 4.0,
+ 1401362655
+ ],
+ [
+ 4.0,
+ 1401362670
+ ],
+ [
+ 4.0,
+ 1401362685
+ ]
+ ]
+ }
+ }
+}