123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405 |
- Ext.define('PageAnalyzer.Console', {
- extend: 'Ext.panel.Panel',
- requires: [
- 'Ext.chart.*',
- 'Ext.grid.Panel',
- 'Ext.grid.feature.Grouping',
- 'Ext.layout.container.Border',
- 'PageAnalyzer.models.BasicTimeData'
- ],
- layout: 'border',
- border: false,
- initComponent: function () {
- var me = this;
- me.addEvents('rawdataupdate');
- me.pathTpl = new Ext.XTemplate('{test} ({env} - {build})');
- me.samples = [];
- me.store = Ext.create('Ext.data.Store', {
- model: 'PageAnalyzer.models.BasicTimeData',
- sorters: [{ property: 'avgTime', direction: 'DESC' }],
- groupField: 'path'
- });
- me.detailStore = Ext.create('Ext.data.Store', {
- model: 'PageAnalyzer.models.BasicTimeData',
- sorters: { property: 'avgTime', direction: 'DESC' }
- });
- me.singleSampleStore = Ext.create('Ext.data.Store', {
- model: 'PageAnalyzer.models.BasicTimeData'
- });
- me.items = [
- {
- region: 'north',
- title: 'Trend',
- itemId: 'trendPanel',
- layout: 'fit',
- split: true,
- collapsible: true,
- collapsed: false,
- flex: 4,
- items: []
- },
- {
- region: 'center',
- title: 'Data',
- flex: 4,
- layout: 'border',
- border: false,
- items: [
- {
- region: 'center',
- xtype: 'tabpanel',
- tabPosition: 'bottom',
- flex: 5,
- items: [
- me.makeDataGrid({
- title: 'Grid',
- border: false
- }),
- {
- region: 'east',
- title: 'Raw',
- layout: 'fit',
- border: false,
- tbar: [
- {
- text: 'Load',
- handler: me.onUpdateFromRawData,
- scope: me
- }
- ],
- items: [
- {
- xtype: 'textarea',
- style: 'margin:0',
- itemId: 'rawData',
- emptyText: 'Raw data goes here...',
- selectOnFocus: true
- }
- ]
- },
- {
- title: 'Accumulators',
- xtype: 'textarea',
- style: 'margin:0',
- itemId: 'accumulatorCfg'
- }
- ]
- },
- me.makeDetailsChart({ region: 'east' })
- ]
- }
- ];
- me.callParent();
- },
- addSample: function (perfData) {
- var me = this,
- last = perfData;
- if (Ext.isArray(perfData)) {
- me.samples.push.apply(me.samples, perfData);
- last = last[last.length-1];
- } else {
- // perfData = { env: '..', test: '..', build: '..', data: Ext.Perf.getData() }
- me.samples.push(perfData);
- }
- me.update();
- var rec = me.store.findRecord('path', me.makePath(last));
- me.select(rec);
- },
- clearSamples: function() {
- var me = this;
- me.samples.length = 0;
- me.update();
- },
- makeDataGrid: function (config) {
- var me = this;
- return Ext.apply({
- xtype: 'grid',
- store: me.store,
- itemId: 'dataGrid',
- flex: 5,
- features: [
- {
- ftype:'grouping',
- hideGroupedHeader: true
- }
- ],
- columns: [
- { text: 'Environment', dataIndex: 'environment', hidden: true },
- { text: 'Build', dataIndex: 'build', hidden: true },
- { text: 'Test', dataIndex: 'test', hidden: true },
- { text: 'Path', dataIndex: 'path', sortable: true },
- { text: 'Name', dataIndex: 'measure', sortable: true },
- { text: 'Time', dataIndex: 'avgTime', sortable: true },
- { text: 'Time/Call', dataIndex: 'avgTimePerCall', sortable: true },
- { text: 'Samples', dataIndex: 'numSamples', sortable: true },
- { text: 'Min Calls', dataIndex: 'minCalls', sortable: true },
- { text: 'Max Calls', dataIndex: 'maxCalls', sortable: true }
- ],
- listeners: {
- selectionchange: function (model, selection) {
- me.onSelect(selection[0]);
- }
- }
- }, config);
- },
- makePath: function (perfData) {
- return this.pathTpl.apply(perfData);
- },
- makeDetailsChart: function (config) {
- var me = this;
- return Ext.apply({
- xtype: 'panel',
- title: 'Details',
- layout: 'fit',
- flex: 3,
- split: true,
- collapsible: true,
- preventHeader: true,
- items: [{
- xtype: 'chart',
- store: me.detailStore,
- itemId: 'measuresPieChart',
- theme: 'Base:gradients',
- series: [{
- type: 'pie',
- field: 'avgTime',
- label: {
- field: 'measure',
- display: 'rotate',
- font: '12px Arial'
- }
- }]
- }]
- }, config);
- },
- makeTrendChart: function () {
- var me = this,
- panel = me.down('#trendPanel'),
- builds = {},
- trendData = [],
- fields = [],
- measures = {},
- measureNames = [],
- modelName,
- chart;
- panel.removeAll();
- chart = {
- xtype: 'chart',
- style: 'background:#fff',
- animate: false,
- shadow: true,
- flex: 5,
- theme: 'Category1',
- legend: {
- position: 'right'
- },
- axes: [{
- type: 'Numeric',
- minimum: 0,
- position: 'left',
- fields: [],
- title: 'Time (ms)',
- minorTickSteps: 1,
- grid: {
- odd: {
- opacity: 1,
- fill: '#ddd',
- stroke: '#bbb',
- 'stroke-width': 0.5
- }
- }
- }, {
- type: 'Category',
- position: 'bottom',
- fields: ['build'],
- title: 'Build'
- }],
- series: []
- };
- me.store.each(function (r) {
- var rd = r.data;
- var build = builds[rd.build];
- if (!build) {
- builds[rd.build] = build = { build: rd.build };
- trendData.push(build);
- }
- build[rd.measure] = rd.avgTime;
- if (rd.measure in measures) {
- return;
- }
- fields.push(measures[rd.measure] = { name: rd.measure, type: 'float' });
- measureNames.push(rd.measure);
- chart.series.push({
- type: 'line',
- highlight: {
- size: 7,
- radius: 7
- },
- axis: 'left',
- xField: 'build',
- yField: rd.measure,
- markerConfig: {
- type: 'circle',
- size: 4,
- radius: 4,
- 'stroke-width': 0
- }
- });
- });
- chart.axes[0].fields = measureNames;
- measureNames.sort();
- var name = 'Trend_' + measureNames.join('$');
- name = name.replace(/\./g, '_');
- modelName = 'PageAnalyzer.models.' + name;
- var mfields = [{
- name: 'build',
- type: 'int'
- }];
- fields.push({name: 'build', type: 'int'});
- if (!PageAnalyzer.models[name]) {
- Ext.define(modelName, {
- extend: 'Ext.data.Model',
- fields: fields
- });
- }
- chart.store = Ext.create('Ext.data.Store', {
- model: modelName,
- sorters: { property: 'build', direction: 'ASC' }
- });
- if (trendData.length == 1) {
- trendData.unshift({
- build: '0',
- avgTime: null
- });
- }
- chart.store.loadData(trendData);
- chart.store.sort();
- panel.add(chart);
- },
- onSelect: function (rec) {
- var me = this,
- records = [],
- store = me.detailStore;
- if (rec) {
- me.store.each(function (r) {
- if (r.data.path == rec.data.path) {
- records.push(r.copy());
- }
- });
- }
- store.removeAll();
- if (records.length) {
- store.add(records);
- store.sort();
- }
- },
- onUpdateFromRawData: function () {
- var me = this,
- rawData = me.down('#rawData').getValue();
- me.samples = Ext.decode(rawData);
- me.update();
- },
- select: function (rec) {
- if (rec) {
- var me = this,
- grid = me.down('#dataGrid');
- grid.getSelectionModel().select(rec);
- }
- },
- update: function () {
- var me = this,
- map = {}, // map[env+test+build][measure] = record
- json = Ext.encode(me.samples),
- key,
- measures,
- measure,
- records = [];
- me.down('#rawData').setValue(json);
- me.fireEvent('rawdataupdate', me, json, me.samples);
- Ext.each(me.samples, function (perfData) {
- key = me.makePath(perfData);
- measures = map[key] || (map[key] = {});
- Ext.Object.each(perfData.data, function (name, stats) {
- measure = measures[name];
- if (!measure) {
- measures[name] = measure = new PageAnalyzer.models.BasicTimeData({
- environment: perfData.env,
- build: perfData.build,
- test: perfData.test,
- path: key,
- measure: name
- });
- }
- records.push(measure);
- measure.addSample(stats.pure.sum, stats.count);
- });
- });
- me.store.removeAll();
- me.store.add(records);
- me.store.sort();
- me.makeTrendChart();
- },
- setAccumulators: function (cfg) {
- var me = this,
- accData = Ext.JSON.encodeValue(cfg, '\n ');
- me.down('#accumulatorCfg').setValue(accData);
- },
- getAccumulators: function () {
- var me = this,
- accData = me.down('#accumulatorCfg').getValue();
- if(!accData || accData == '')
- return null;
- return Ext.decode(accData, true);
- }
- });
|