AutorÃa | Ultima modificación | Ver Log |
YUI.add('yui2-profilerviewer', function(Y) {var YAHOO = Y.YUI2;/*Copyright (c) 2011, Yahoo! Inc. All rights reserved.Code licensed under the BSD License:http://developer.yahoo.com/yui/license.htmlversion: 2.9.0*/(function() {/*** The ProfilerViewer module provides a graphical display for viewing* the output of the YUI Profiler <http://developer.yahoo.com/yui/profiler>.* @module profilerviewer* @requires yahoo, dom, event, element, profiler, yuiloader*//*** A widget to view YUI Profiler output.* @namespace YAHOO.widget* @class ProfilerViewer* @extends YAHOO.util.Element* @constructor* @param {HTMLElement | String | Object} el(optional) The html* element into which the ProfileViewer should be rendered.* An element will be created if none provided.* @param {Object} attr (optional) A key map of the ProfilerViewer's* initial attributes. Ignored if first arg is an attributes object.*/YAHOO.widget.ProfilerViewer = function(el, attr) {attr = attr || {};if (arguments.length == 1 && !YAHOO.lang.isString(el) && !el.nodeName) {attr = el;el = attr.element || null;}if (!el && !attr.element) {el = this._createProfilerViewerElement();}YAHOO.widget.ProfilerViewer.superclass.constructor.call(this, el, attr);this._init();YAHOO.log("ProfilerViewer instantiated.", "info", "ProfilerViewer");};YAHOO.extend(YAHOO.widget.ProfilerViewer, YAHOO.util.Element);// Static members of YAHOO.widget.ProfilerViewer:YAHOO.lang.augmentObject(YAHOO.widget.ProfilerViewer, {/*** Classname for ProfilerViewer containing element.* @static* @property CLASS* @type string* @public* @default "yui-pv"*/CLASS: 'yui-pv',/*** Classname for ProfilerViewer button dashboard.* @static* @property CLASS_DASHBOARD* @type string* @public* @default "yui-pv-dashboard"*/CLASS_DASHBOARD: 'yui-pv-dashboard',/*** Classname for the "refresh data" button.* @static* @property CLASS_REFRESH* @type string* @public* @default "yui-pv-refresh"*/CLASS_REFRESH: 'yui-pv-refresh',/*** Classname for busy indicator in the dashboard.* @static* @property CLASS_BUSY* @type string* @public* @default "yui-pv-busy"*/CLASS_BUSY: 'yui-pv-busy',/*** Classname for element containing the chart and chart* legend elements.* @static* @property CLASS_CHART_CONTAINER* @type string* @public* @default "yui-pv-chartcontainer"*/CLASS_CHART_CONTAINER: 'yui-pv-chartcontainer',/*** Classname for element containing the chart.* @static* @property CLASS_CHART* @type string* @public* @default "yui-pv-chart"*/CLASS_CHART: 'yui-pv-chart',/*** Classname for element containing the chart's legend.* @static* @property CLASS_CHART_LEGEND* @type string* @public* @default "yui-pv-chartlegend"*/CLASS_CHART_LEGEND: 'yui-pv-chartlegend',/*** Classname for element containing the datatable.* @static* @property CLASS_TABLE* @type string* @public* @default "yui-pv-table"*/CLASS_TABLE: 'yui-pv-table',/*** HTML strings used in the UI. Values will be inserted into DOM with innerHTML.* @static* @property STRINGS* @object* @public* @default English language strings for UI.*/STRINGS: {title: "YUI ProfilerViewer",buttons: {viewprofiler: "View Profiler Data",hideprofiler: "Hide Profiler Report",showchart: "Show Chart",hidechart: "Hide Chart",refreshdata: "Refresh Data"},colHeads: {//key: [column head label, width in pixels]fn: ["Function/Method", null], //must auto-sizecalls: ["Calls", 40],avg: ["Average", 80],min: ["Shortest", 70],max: ["Longest", 70],total: ["Total Time", 70],pct: ["Percent", 70]},millisecondsAbbrev: "ms",initMessage: "initialiazing chart...",installFlashMessage: "Unable to load Flash content. The YUI Charts Control requires Flash Player 9.0.45 or higher. You can download the latest version of Flash Player from the <a href='http://www.adobe.com/go/getflashplayer'>Adobe Flash Player Download Center</a>."},/*** Function used to format numbers in milliseconds* for chart; must be publicly accessible, per Charts spec.* @static* @property timeAxisLabelFunction* @type function* @private*/timeAxisLabelFunction: function(n) {var a = (n === Math.floor(n)) ? n : (Math.round(n*1000))/1000;return (a + " " + YAHOO.widget.ProfilerViewer.STRINGS.millisecondsAbbrev);},/*** Function used to format percent numbers for chart; must* be publicly accessible, per Charts spec.* @static* @property percentAxisLabelFunction* @type function* @private*/percentAxisLabelFunction: function(n) {var a = (n === Math.floor(n)) ? n : (Math.round(n*100))/100;return (a + "%");}},true);//// STANDARD SHORTCUTS//var Dom = YAHOO.util.Dom;var Event = YAHOO.util.Event;var Profiler = YAHOO.tool.Profiler;var PV = YAHOO.widget.ProfilerViewer;var proto = PV.prototype;//// PUBLIC METHODS///*** Refreshes the data displayed in the ProfilerViewer. When called,* this will invoke a refresh of the DataTable and (if displayed)* the Chart.* @method refreshData* @return void* @public*/proto.refreshData = function() {YAHOO.log("Data refresh requested via refreshData method.", "info", "ProfilerViewer");this.fireEvent("dataRefreshEvent");};/*** Returns the element containing the console's header.* @method getHeadEl* @return HTMLElement* @public*/proto.getHeadEl = function() {YAHOO.log("Head element requested via getHeadEl.", "info", "ProfilerViewer");return (this._headEl) ? Dom.get(this._headEl) : false;};/*** Returns the element containing the console's body, including* the chart and the datatable..* @method getBodyEl* @return HTMLElement* @public*/proto.getBodyEl = function() {YAHOO.log("Body element requested via getBodyEl.", "info", "ProfilerViewer");return (this._bodyEl) ? Dom.get(this._bodyEl) : false;};/*** Returns the element containing the console's chart.* @method getChartEl* @return HTMLElement* @public*/proto.getChartEl = function() {YAHOO.log("Chart element requested via getChartEl.", "info", "ProfilerViewer");return (this._chartEl) ? Dom.get(this._chartEl) : false;};/*** Returns the element containing the console's dataTable.* @method getTableEl* @return HTMLElement* @public*/proto.getTableEl = function() {YAHOO.log("DataTable element requested via getTableEl.", "info", "ProfilerViewer");return (this._tableEl) ? Dom.get(this._tableEl) : false;};/*** Returns the element containing the console's DataTable* instance.* @method getDataTable* @return YAHOO.widget.DataTable* @public*/proto.getDataTable = function() {YAHOO.log("DataTable instance requested via getDataTable.", "info", "ProfilerViewer");return this._dataTable;};/*** Returns the element containing the console's Chart instance.* @method getChart* @return YAHOO.widget.BarChart* @public*/proto.getChart = function() {YAHOO.log("Chart instance requested via getChart.", "info", "ProfilerViewer");return this._chart;};//// PRIVATE PROPERTIES//proto._rendered = false;proto._headEl = null;proto._bodyEl = null;proto._toggleVisibleEl = null;proto._busyEl = null;proto._busy = false;proto._tableEl = null;proto._dataTable = null;proto._chartEl = null;proto._chartLegendEl = null;proto._chartElHeight = 250;proto._chart = null;proto._chartInitialized = false;//// PRIVATE METHODS//proto._init = function() {/*** CUSTOM EVENTS**//*** Fired when a data refresh is requested. No arguments are passed* with this event.** @event refreshDataEvent*/this.createEvent("dataRefreshEvent");/*** Fired when the viewer canvas first renders. No arguments are passed* with this event.** @event renderEvent*/this.createEvent("renderEvent");this.on("dataRefreshEvent", this._refreshDataTable, this, true);this._initLauncherDOM();if(this.get("showChart")) {this.on("sortedByChange", this._refreshChart);}YAHOO.log("ProfilerViewer instance initialization complete.", "info", "ProfilerViewer");};/*** If no element is passed in, create it as the first element* in the document.* @method _createProfilerViewerElement* @return HTMLElement* @private*/proto._createProfilerViewerElement = function() {YAHOO.log("Creating root element...", "info", "ProfilerViewer");var el = document.createElement("div");document.body.insertBefore(el, document.body.firstChild);Dom.addClass(el, this.SKIN_CLASS);Dom.addClass(el, PV.CLASS);YAHOO.log(el);return el;};/*** Provides a readable name for the ProfilerViewer instance.* @method toString* @return String* @private*/proto.toString = function() {return "ProfilerViewer " + (this.get('id') || this.get('tagName'));};/*** Toggles visibility of the viewer canvas.* @method _toggleVisible* @return void* @private*/proto._toggleVisible = function() {YAHOO.log("Toggling visibility to " + !this.get("visible") + ".", "info", "ProfilerViewer");var newVis = (this.get("visible")) ? false : true;this.set("visible", newVis);};/*** Shows the viewer canvas.* @method show* @return void* @private*/proto._show = function() {if(!this._busy) {this._setBusyState(true);if(!this._rendered) {var loader = new YAHOO.util.YUILoader();if (this.get("base")) {loader.base = this.get("base");}var modules = ["datatable"];if(this.get("showChart")) {modules.push("charts");}loader.insert({ require: modules,onSuccess: function() {this._render();},scope: this});} else {var el = this.get("element");Dom.removeClass(el, "yui-pv-minimized");this._toggleVisibleEl.innerHTML = PV.STRINGS.buttons.hideprofiler;//The Flash Charts component can't be set to display:none,//and even after positioning it offscreen the screen//may fail to repaint in some browsers. Adding an empty//style rule to the console body can help force a repaint:Dom.addClass(el, "yui-pv-null");Dom.removeClass(el, "yui-pv-null");//Always refresh data when changing to visible:this.refreshData();}}};/*** Hides the viewer canvas.* @method hide* @return void* @private*/proto._hide = function() {this._toggleVisibleEl.innerHTML = PV.STRINGS.buttons.viewprofiler;Dom.addClass(this.get("element"), "yui-pv-minimized");};/*** Render the viewer canvas* @method _render* @return void* @private*/proto._render = function() {YAHOO.log("Beginning to render ProfilerViewer canvas...", "info", "ProfilerViewer");Dom.removeClass(this.get("element"), "yui-pv-minimized");this._initViewerDOM();this._initDataTable();if(this.get("showChart")) {this._initChartDOM();this._initChart();}this._rendered = true;this._toggleVisibleEl.innerHTML = PV.STRINGS.buttons.hideprofiler;this.fireEvent("renderEvent");YAHOO.log("ProfilerViewer rendering complete...", "info", "ProfilerViewer");};/*** Set up the DOM structure for the ProfilerViewer launcher.* @method _initLauncherDOM* @private*/proto._initLauncherDOM = function() {YAHOO.log("Creating the launcher...", "info", "ProfilerViewer");var el = this.get("element");Dom.addClass(el, PV.CLASS);Dom.addClass(el, "yui-pv-minimized");this._headEl = document.createElement("div");Dom.addClass(this._headEl, "hd");var s = PV.STRINGS.buttons;var b = (this.get("visible")) ? s.hideprofiler : s.viewprofiler;this._toggleVisibleEl = this._createButton(b, this._headEl);this._refreshEl = this._createButton(s.refreshdata, this._headEl);Dom.addClass(this._refreshEl, PV.CLASS_REFRESH);this._busyEl = document.createElement("span");this._headEl.appendChild(this._busyEl);var title = document.createElement("h4");title.innerHTML = PV.STRINGS.title;this._headEl.appendChild(title);el.appendChild(this._headEl);Event.on(this._toggleVisibleEl, "click", this._toggleVisible, this, true);Event.on(this._refreshEl, "click", function() {if(!this._busy) {this._setBusyState(true);this.fireEvent("dataRefreshEvent");}}, this, true);};/*** Set up the DOM structure for the ProfilerViewer canvas,* including the holder for the DataTable.* @method _initViewerDOM* @private*/proto._initViewerDOM = function() {YAHOO.log("Creating DOM structure for viewer...", "info", "ProfilerViewer");var el = this.get("element");this._bodyEl = document.createElement("div");Dom.addClass(this._bodyEl, "bd");this._tableEl = document.createElement("div");Dom.addClass(this._tableEl, PV.CLASS_TABLE);this._bodyEl.appendChild(this._tableEl);el.appendChild(this._bodyEl);};/*** Set up the DOM structure for the ProfilerViewer canvas.* @method _initChartDOM* @private*/proto._initChartDOM = function() {YAHOO.log("Adding DOM structure for chart...", "info", "ProfilerViewer");this._chartContainer = document.createElement("div");Dom.addClass(this._chartContainer, PV.CLASS_CHART_CONTAINER);var chl = document.createElement("div");Dom.addClass(chl, PV.CLASS_CHART_LEGEND);var chw = document.createElement("div");this._chartLegendEl = document.createElement("dl");this._chartLegendEl.innerHTML = "<dd>" + PV.STRINGS.initMessage + "</dd>";this._chartEl = document.createElement("div");Dom.addClass(this._chartEl, PV.CLASS_CHART);var msg = document.createElement("p");msg.innerHTML = PV.STRINGS.installFlashMessage;this._chartEl.appendChild(msg);this._chartContainer.appendChild(chl);chl.appendChild(chw);chw.appendChild(this._chartLegendEl);this._chartContainer.appendChild(this._chartEl);this._bodyEl.insertBefore(this._chartContainer,this._tableEl);};/*** Create anchor elements for use as buttons. Args: label* is text to appear on the face of the button, parentEl* is the el to which the anchor will be attached, position* is true for inserting as the first node and false for* inserting as the last node of the parentEl.* @method _createButton* @private*/proto._createButton = function(label, parentEl, position) {var b = document.createElement("a");b.innerHTML = b.title = label;if(parentEl) {if(!position) {parentEl.appendChild(b);} else {parentEl.insertBefore(b, parentEl.firstChild);}}return b;};/*** Set's console busy state.* @method _setBusyState* @private**/proto._setBusyState = function(b) {if(b) {Dom.addClass(this._busyEl, PV.CLASS_BUSY);this._busy = true;} else {Dom.removeClass(this._busyEl, PV.CLASS_BUSY);this._busy = false;}};/*** Generages a sorting function based on current sortedBy* values.* @method _createProfilerViewerElement* @private**/proto._genSortFunction = function(key, dir) {var by = key;var direction = dir;return function(a, b) {if (direction == YAHOO.widget.DataTable.CLASS_ASC) {return a[by] - b[by];} else {return ((a[by] - b[by]) * -1);}};};/*** Utility function for array sums.* @method _arraySum* @private**/var _arraySum = function(arr){var ct = 0;for(var i = 0; i < arr.length; ct+=arr[i++]){}return ct;};/*** Retrieves data from Profiler, filtering and sorting as needed* based on current widget state. Adds calculated percentage* column and function name to data returned by Profiler.* @method _getProfilerData* @private**/proto._getProfilerData = function() {YAHOO.log("Profiler data requested from function DataSource.", "info", "ProfilerViewer");var obj = Profiler.getFullReport();var arr = [];var totalTime = 0;for (name in obj) {if (YAHOO.lang.hasOwnProperty(obj, name)) {var r = obj[name];var o = {};o.fn = name; //add function name to recordo.points = r.points.slice(); //copy live arrayo.calls = r.calls;o.min = r.min;o.max = r.max;o.avg = r.avg;o.total = _arraySum(o.points);o.points = r.points;var f = this.get("filter");if((!f) || (f(o))) {arr.push(o);totalTime += o.total;}}}//add calculated percentage columnfor (var i = 0, j = arr.length; i < j; i++) {arr[i].pct = (totalTime) ? (arr[i].total * 100) / totalTime : 0;}var sortedBy = this.get("sortedBy");var key = sortedBy.key;var dir = sortedBy.dir;arr.sort(this._genSortFunction(key, dir));YAHOO.log("Returning data from DataSource: " + YAHOO.lang.dump(arr), "info", "ProfilerViewer");return arr;};/*** Set up the DataTable.* @method _initDataTable* @private*/proto._initDataTable = function() {YAHOO.log("Creating DataTable instance...", "info", "ProfilerViewer");var self = this;//Set up the JS Function DataSource, pulling data from//the Profiler.this._dataSource = new YAHOO.util.DataSource(function() {return self._getProfilerData.call(self);},{responseType: YAHOO.util.DataSource.TYPE_JSARRAY,maxCacheEntries: 0});var ds = this._dataSource;ds.responseSchema ={fields: [ "fn", "avg", "calls", "max", "min", "total", "pct", "points"]};//Set up the DataTable.var formatTimeValue = function(elCell, oRecord, oColumn, oData) {var a = (oData === Math.floor(oData)) ? oData : (Math.round(oData*1000))/1000;elCell.innerHTML = a + " " + PV.STRINGS.millisecondsAbbrev;};var formatPercent = function(elCell, oRecord, oColumn, oData) {var a = (oData === Math.floor(oData)) ? oData : (Math.round(oData*100))/100;elCell.innerHTML = a + "%";};var a = YAHOO.widget.DataTable.CLASS_ASC;var d = YAHOO.widget.DataTable.CLASS_DESC;var c = PV.STRINGS.colHeads;var f = formatTimeValue;var cols = [{key:"fn", sortable:true, label: c.fn[0],sortOptions: {defaultDir:a},resizeable: (YAHOO.util.DragDrop) ? true : false,minWidth:c.fn[1]},{key:"calls", sortable:true, label: c.calls[0],sortOptions: {defaultDir:d},width:c.calls[1]},{key:"avg", sortable:true, label: c.avg[0],sortOptions: {defaultDir:d},formatter:f,width:c.avg[1]},{key:"min", sortable:true, label: c.min[0],sortOptions: {defaultDir:a},formatter:f,width:c.min[1]},{key:"max", sortable:true, label: c.max[0],sortOptions: {defaultDir:d},formatter:f,width:c.max[1]},{key:"total", sortable:true, label: c.total[0],sortOptions: {defaultDir:d},formatter:f,width:c.total[1]},{key:"pct", sortable:true, label: c.pct[0],sortOptions: {defaultDir:d},formatter:formatPercent,width:c.pct[1]}];this._dataTable = new YAHOO.widget.DataTable(this._tableEl, cols, ds, {scrollable:true,height:this.get("tableHeight"),initialRequest:null,sortedBy: {key: "total",dir: YAHOO.widget.DataTable.CLASS_DESC}});var dt = this._dataTable;//Wire up DataTable events to drive the rest of the UI.dt.subscribe("sortedByChange", this._sortedByChange, this, true);dt.subscribe("renderEvent", this._dataTableRenderHandler, this, true);dt.subscribe("initEvent", this._dataTableRenderHandler, this, true);Event.on(this._tableEl.getElementsByTagName("th"), "click", this._thClickHandler, this, true);YAHOO.log("DataTable initialized.", "info", "ProfilerViewer");};/*** Proxy the sort event in DataTable into the ProfilerViewer* attribute.* @method _sortedByChange* @private**/proto._sortedByChange = function(o) {if(o.newValue && o.newValue.key) {YAHOO.log("Relaying DataTable sortedBy value change; new key: " + o.newValue.key + "; new direction: " + o.newValue.dir + ".", "info", "ProfilerViewer");this.set("sortedBy", {key: o.newValue.key, dir:o.newValue.dir});}};/*** Proxy the render event in DataTable into the ProfilerViewer* attribute.* @method _dataTableRenderHandler* @private**/proto._dataTableRenderHandler = function(o) {YAHOO.log("DataTable's render event has fired.", "info", "ProfilerViewer");this._setBusyState(false);};/*** Event handler for clicks on the DataTable's sortable column* heads.* @method _thClickHandler* @private**/proto._thClickHandler = function(o) {YAHOO.log("DataTable's header row was clicked for sorting.", "info", "ProfilerViewer");this._setBusyState(true);};/*** Refresh DataTable, getting new data from Profiler.* @method _refreshDataTable* @private**/proto._refreshDataTable = function(args) {YAHOO.log("Beginning to refresh DataTable contents...", "info", "ProfilerViewer");var dt = this._dataTable;dt.getDataSource().sendRequest("", dt.onDataReturnInitializeTable, dt);YAHOO.log("DataTable refresh complete.", "info", "ProfilerViewer");};/*** Refresh chart, getting new data from table.* @method _refreshChart* @private**/proto._refreshChart = function() {YAHOO.log("Beginning to refresh Chart contents...", "info", "ProfilerViewer");switch (this.get("sortedBy").key) {case "fn":/*Keep the same data on the chart, but force update toreflect new sort order on function/method name: */this._chart.set("dataSource", this._chart.get("dataSource"));/*no further action necessary; chart redraws*/return;case "calls":/*Null out the xAxis formatting before redrawing chart.*/this._chart.set("xAxis", this._chartAxisDefinitionPlain);break;case "pct":this._chart.set("xAxis", this._chartAxisDefinitionPercent);break;default:/*Set the default xAxis; redraw legend; set the new series definition.*/this._chart.set("xAxis", this._chartAxisDefinitionTime);break;}this._drawChartLegend();this._chart.set("series", this._getSeriesDef(this.get("sortedBy").key));YAHOO.log("Chart refresh complete.", "info", "ProfilerViewer");};/*** Get data for the Chart from DataTable recordset* @method _getChartData* @private*/proto._getChartData = function() {YAHOO.log("Getting data for chart from function DataSource.", "info", "ProfilerViewer");//var records = this._getProfilerData();var records = this._dataTable.getRecordSet().getRecords(0, this.get("maxChartFunctions"));var arr = [];for (var i = 0, j = records.length; i<j; i++) {arr.push(records[i].getData());}YAHOO.log("Returning data to Chart: " + YAHOO.lang.dump(arr), "info", "ProfilerViewer");return arr;};/*** Build series definition based on current configuration attributes.* @method _getSeriesDef* @private*/proto._getSeriesDef = function(field) {var sd = this.get("chartSeriesDefinitions")[field];var arr = [];for(var i = 0, j = sd.group.length; i<j; i++) {var c = this.get("chartSeriesDefinitions")[sd.group[i]];arr.push({displayName:c.displayName,xField:c.xField,style: {color:c.style.color, size:c.style.size}});}YAHOO.log("Returning new series definition to chart: " + YAHOO.lang.dump(arr), "info", "ProfilerViewer");return arr;};/*** Set up the Chart.* @method _initChart* @private*/proto._initChart = function() {YAHOO.log("Initializing chart...", "info", "ProfilerViewer");this._sizeChartCanvas();YAHOO.widget.Chart.SWFURL = this.get("swfUrl");var self = this;//Create DataSource based on records currently displayed//at the top of the sort list in the DataTable.var ds = new YAHOO.util.DataSource(//force the jsfunction DataSource to run in the scope of//the ProfilerViewer, not in the YAHOO.util.DataSource scope:function() {return self._getChartData.call(self);},{responseType: YAHOO.util.DataSource.TYPE_JSARRAY,maxCacheEntries: 0});ds.responseSchema ={fields: [ "fn", "avg", "calls", "max", "min", "total", "pct" ]};ds.subscribe('responseEvent', this._sizeChartCanvas, this, true);//Set up the chart itself.this._chartAxisDefinitionTime = new YAHOO.widget.NumericAxis();this._chartAxisDefinitionTime.labelFunction = "YAHOO.widget.ProfilerViewer.timeAxisLabelFunction";this._chartAxisDefinitionPercent = new YAHOO.widget.NumericAxis();this._chartAxisDefinitionPercent.labelFunction = "YAHOO.widget.ProfilerViewer.percentAxisLabelFunction";this._chartAxisDefinitionPlain = new YAHOO.widget.NumericAxis();this._chart = new YAHOO.widget.BarChart( this._chartEl, ds,{yField: "fn",series: this._getSeriesDef(this.get("sortedBy").key),style: this.get("chartStyle"),xAxis: this._chartAxisDefinitionTime} );this._drawChartLegend();this._chartInitialized = true;this._dataTable.unsubscribe("initEvent", this._initChart, this);this._dataTable.subscribe("initEvent", this._refreshChart, this, true);YAHOO.log("Chart initialization complete.", "info", "ProfilerViewer");};/*** Set up the Chart's legend* @method _drawChartLegend* @private**/proto._drawChartLegend = function() {YAHOO.log("Drawing chart legend...", "info", "ProfilerViewer");var seriesDefs = this.get("chartSeriesDefinitions");var currentDef = seriesDefs[this.get("sortedBy").key];var l = this._chartLegendEl;l.innerHTML = "";for(var i = 0, j = currentDef.group.length; i<j; i++) {var c = seriesDefs[currentDef.group[i]];var dt = document.createElement("dt");Dom.setStyle(dt, "backgroundColor", "#" + c.style.color);var dd = document.createElement("dd");dd.innerHTML = c.displayName;l.appendChild(dt);l.appendChild(dd);}};/*** Resize the chart's canvas if based on number of records* returned from the chart's datasource.* @method _sizeChartCanvas* @private**/proto._sizeChartCanvas = function(o) {YAHOO.log("Resizing chart canvas...", "info", "ProfilerViewer");var bars = (o) ? o.response.length : this.get("maxChartFunctions");var s = (bars * 36) + 34;if (s != parseInt(this._chartElHeight, 10)) {this._chartElHeight = s;Dom.setStyle(this._chartEl, "height", s + "px");}};/*** setAttributeConfigs TabView specific properties.* @method initAttributes* @param {Object} attr Hash of initial attributes* @method initAttributes* @private*/proto.initAttributes = function(attr) {YAHOO.log("Initializing attributes...", "info", "ProfilerViewer");YAHOO.widget.ProfilerViewer.superclass.initAttributes.call(this, attr);/*** The YUI Loader base path from which to pull YUI files needed* in the rendering of the ProfilerViewer canvas. Passed directly* to YUI Loader. Leave blank to draw files from* yui.yahooapis.com.* @attribute base* @type string* @default ""*/this.setAttributeConfig('base', {value: attr.base});/*** The height of the DataTable. The table will scroll* vertically if the content overflows the specified* height.* @attribute tableHeight* @type string* @default "15em"*/this.setAttributeConfig('tableHeight', {value: attr.tableHeight || "15em",method: function(s) {if(this._dataTable) {this._dataTable.set("height", s);}}});/*** The default column key to sort by. Valid keys are: fn, calls,* avg, min, max, total. Valid dir values are:* YAHOO.widget.DataTable.CLASS_ASC and* YAHOO.widget.DataTable.CLASS_DESC (or their* string equivalents).* @attribute sortedBy* @type string* @default {key:"total", dir:"yui-dt-desc"}*/this.setAttributeConfig('sortedBy', {value: attr.sortedBy || {key:"total", dir:"yui-dt-desc"}});/*** A filter function to use in selecting functions that will* appear in the ProfilerViewer report. The function is passed* a function report object and should return a boolean indicating* whether that function should be included in the ProfilerViewer* display. The argument is structured as follows:** {* fn: <str function name>,* calls : <n number of calls>,* avg : <n average call duration>,* max: <n duration of longest call>,* min: <n duration of shortest call>,* total: <n total time of all calls>* points : <array time in ms of each call>* }** For example, you would use the follwing filter function to* return only functions that have been called at least once:** function(o) {* return (o.calls > 0);* }** @attribute filter* @type function* @default null*/this.setAttributeConfig('filter', {value: attr.filter || null,validator: YAHOO.lang.isFunction});/*** The path to the YUI Charts swf file; must be a full URI* or a path relative to the page being profiled. Changes at runtime* not supported; pass this value in at instantiation.* @attribute swfUrl* @type string* @default "http://yui.yahooapis.com/2.5.0/build/charts/assets/charts.swf"*/this.setAttributeConfig('swfUrl', {value: attr.swfUrl || "http://yui.yahooapis.com/2.5.0/build/charts/assets/charts.swf"});/*** The maximum number of functions to profile in the chart. The* greater the number of functions, the greater the height of the* chart canvas.* height.* @attribute maxChartFunctions* @type int* @default 6*/this.setAttributeConfig('maxChartFunctions', {value: attr.maxChartFunctions || 6,method: function(s) {if(this._rendered) {this._sizeChartCanvas();}},validator: YAHOO.lang.isNumber});/*** The style object that defines the chart's visual presentation.* Conforms to the style attribute passed to the Charts Control* constructor. See Charts Control User's Guide for more information* on how to format this object.* @attribute chartStyle* @type obj* @default See JS source for default definitions.*/this.setAttributeConfig('chartStyle', {value: attr.chartStyle || {font:{name: "Arial",color: 0xeeee5c,size: 12},background:{color: "6e6e63"}},method: function() {if(this._rendered && this.get("showChart")) {this._refreshChart();}}});/*** The series definition information to use when charting* specific fields on the chart. "displayName", "xField",* and "style" members are used to construct the series* definition; the "group" member is the array of fields* that should be charted when the table is sorted by a* given field. The "displayName" string value will be* treated as markup and inserted into the DOM with innerHTML.* @attribute chartSeriesDefinitions* @type obj* @default See JS source for full default definitions.*/this.setAttributeConfig('chartSeriesDefinitions', {value: attr.chartSeriesDefinitions || {total: {displayName: PV.STRINGS.colHeads.total[0],xField: "total",style: {color:"4d95dd", size:20},group: ["total"]},calls: {displayName: PV.STRINGS.colHeads.calls[0],xField: "calls",style: {color:"edff9f", size:20},group: ["calls"]},avg: {displayName: PV.STRINGS.colHeads.avg[0],xField: "avg",style: {color:"209daf", size:9},group: ["avg", "min", "max"]},min: {displayName: PV.STRINGS.colHeads.min[0],xField: "min",style: {color:"b6ecf4", size:9},group: ["avg", "min", "max"]},max: {displayName: PV.STRINGS.colHeads.max[0],xField: "max",style: {color:"29c7de", size:9},group: ["avg", "min", "max"]},pct: {displayName: PV.STRINGS.colHeads.pct[0],xField: "pct",style: {color:"C96EDB", size:20},group: ["pct"]}},method: function() {if(this._rendered && this.get("showChart")) {this._refreshChart();}}});/*** The default visibility setting for the viewer canvas. If true,* the viewer will load all necessary files and render itself* immediately upon instantiation; otherwise, the viewer will* load only minimal resources until the user toggles visibility* via the UI.* @attribute visible* @type boolean* @default false*/this.setAttributeConfig('visible', {value: attr.visible || false,validator: YAHOO.lang.isBoolean,method: function(b) {if(b) {this._show();} else {if (this._rendered) {this._hide();}}}});/*** The default visibility setting for the chart.* @attribute showChart* @type boolean* @default true*/this.setAttributeConfig('showChart', {value: attr.showChart || true,validator: YAHOO.lang.isBoolean,writeOnce: true});YAHOO.widget.ProfilerViewer.superclass.initAttributes.call(this, attr);YAHOO.log("Attributes initialized.", "info", "ProfilerViewer");};})();YAHOO.register("profilerviewer", YAHOO.widget.ProfilerViewer, {version: "2.9.0", build: "2800"});}, '2.9.0' ,{"requires": ["yui2-skin-sam-profilerviewer", "yui2-yuiloader", "yui2-dom", "yui2-event", "yui2-element", "yui2-profiler"]});