/hippo/src/main/webapp/yui/profilerviewer/profilerviewer-debug.js
http://hdbc.googlecode.com/ · JavaScript · 1229 lines · 621 code · 140 blank · 468 comment · 57 complexity · 9e6f600727b2590682cca7e9d3c7f88a MD5 · raw file
- /*
- Copyright (c) 2009, Yahoo! Inc. All rights reserved.
- Code licensed under the BSD License:
- http://developer.yahoo.net/yui/license.txt
- version: 2.7.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',
-
- /**
- * Strings used in the UI.
- * @static
- * @property STRINGS
- * @object
- * @public
- * @default English language strings for UI.
- */
- STRINGS: {
- title: "YUI Profiler (beta)",
- 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-size
- calls: ["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 record
- o.points = r.points.slice(); //copy live array
- o.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 column
- for (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 to
- reflect 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.
- * @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.7.0", build: "1799"});